diff --git a/api/tacticalrmm/core/management/commands/create_natsapi_conf.py b/api/tacticalrmm/core/management/commands/create_natsapi_conf.py index 74d1a01a..9d74632f 100644 --- a/api/tacticalrmm/core/management/commands/create_natsapi_conf.py +++ b/api/tacticalrmm/core/management/commands/create_natsapi_conf.py @@ -4,7 +4,7 @@ import os from django.conf import settings from django.core.management.base import BaseCommand -from tacticalrmm.helpers import get_nats_ports +from tacticalrmm.helpers import get_nats_internal_protocol, get_nats_ports class Command(BaseCommand): @@ -21,9 +21,10 @@ class Command(BaseCommand): ssl = "disable" nats_std_port, _ = get_nats_ports() + proto = get_nats_internal_protocol() config = { "key": settings.SECRET_KEY, - "natsurl": f"tls://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}", + "natsurl": f"{proto}://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}", "user": db["USER"], "pass": db["PASSWORD"], "host": db["HOST"], diff --git a/api/tacticalrmm/core/tests.py b/api/tacticalrmm/core/tests.py index e74a554f..ac664eb9 100644 --- a/api/tacticalrmm/core/tests.py +++ b/api/tacticalrmm/core/tests.py @@ -502,3 +502,27 @@ class TestCoreUtils(TacticalTestCase): r, "http://tactical-meshcentral:4443/meshagents?id=4&meshid=abc123&installflags=0", ) + + @override_settings(TRMM_INSECURE=True) + def test_get_meshagent_url_insecure(self): + r = get_meshagent_url( + ident=MeshAgentIdent.DARWIN_UNIVERSAL, + plat="darwin", + mesh_site="https://mesh.example.com", + mesh_device_id="abc123", + ) + self.assertEqual( + r, + "http://mesh.example.com:4430/meshagents?id=abc123&installflags=2&meshinstall=10005", + ) + + r = get_meshagent_url( + ident=MeshAgentIdent.WIN64, + plat="windows", + mesh_site="https://mesh.example.com", + mesh_device_id="abc123", + ) + self.assertEqual( + r, + "http://mesh.example.com:4430/meshagents?id=4&meshid=abc123&installflags=0", + ) diff --git a/api/tacticalrmm/core/utils.py b/api/tacticalrmm/core/utils.py index f76cb9ee..aeb06e61 100644 --- a/api/tacticalrmm/core/utils.py +++ b/api/tacticalrmm/core/utils.py @@ -88,8 +88,12 @@ def get_mesh_ws_url() -> str: if settings.DOCKER_BUILD: uri = f"{settings.MESH_WS_URL}/control.ashx?auth={token}" else: - site = core.mesh_site.replace("https", "wss") - uri = f"{site}/control.ashx?auth={token}" + if getattr(settings, "TRMM_INSECURE", False): + site = core.mesh_site.replace("https", "ws") + uri = f"{site}:4430/control.ashx?auth={token}" + else: + site = core.mesh_site.replace("https", "wss") + uri = f"{site}/control.ashx?auth={token}" return uri @@ -181,6 +185,8 @@ def get_meshagent_url( ) -> str: if settings.DOCKER_BUILD: base = settings.MESH_WS_URL.replace("ws://", "http://") + elif getattr(settings, "TRMM_INSECURE", False): + base = mesh_site.replace("https", "http") + ":4430" else: base = mesh_site diff --git a/api/tacticalrmm/tacticalrmm/helpers.py b/api/tacticalrmm/tacticalrmm/helpers.py index 86d7a0c1..e8aec603 100644 --- a/api/tacticalrmm/tacticalrmm/helpers.py +++ b/api/tacticalrmm/tacticalrmm/helpers.py @@ -42,6 +42,13 @@ def get_nats_ports() -> tuple[int, int]: return nats_standard_port, nats_websocket_port +def get_nats_internal_protocol() -> str: + if getattr(settings, "TRMM_INSECURE", False): + return "nats" + + return "tls" + + def date_is_in_past(*, datetime_obj: "datetime", agent_tz: str) -> bool: """ datetime_obj must be a naive datetime @@ -66,8 +73,9 @@ def rand_range(min: int, max: int) -> float: def setup_nats_options() -> dict[str, Any]: nats_std_port, _ = get_nats_ports() + proto = get_nats_internal_protocol() opts = { - "servers": f"tls://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}", + "servers": f"{proto}://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}", "user": "tacticalrmm", "name": "trmm-django", "password": settings.SECRET_KEY, diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index 4593ff36..59f0b2ed 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -34,7 +34,12 @@ from tacticalrmm.constants import ( DebugLogType, ScriptShell, ) -from tacticalrmm.helpers import get_certs, get_nats_ports, notify_error +from tacticalrmm.helpers import ( + get_certs, + get_nats_internal_protocol, + get_nats_ports, + notify_error, +) def generate_winagent_exe( @@ -204,10 +209,6 @@ def reload_nats() -> None: nats_std_port, nats_ws_port = get_nats_ports() config = { - "tls": { - "cert_file": cert_file, - "key_file": key_file, - }, "authorization": {"users": users}, "max_payload": 67108864, "port": nats_std_port, # internal only @@ -217,6 +218,12 @@ def reload_nats() -> None: }, } + if get_nats_internal_protocol() == "tls": + config["tls"] = { + "cert_file": cert_file, + "key_file": key_file, + } + if "NATS_HTTP_PORT" in os.environ: config["http_port"] = int(os.getenv("NATS_HTTP_PORT")) # type: ignore elif hasattr(settings, "NATS_HTTP_PORT"): diff --git a/install.sh b/install.sh index 479dd178..624079c2 100644 --- a/install.sh +++ b/install.sh @@ -14,6 +14,7 @@ NC='\033[0m' SCRIPTS_DIR='/opt/trmm-community-scripts' PYTHON_VER='3.11.4' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' +local_settings='/rmm/api/tacticalrmm/tacticalrmm/local_settings.py' TMP_FILE=$(mktemp -p "" "rmminstall_XXXXXXXXXX") curl -s -L "${SCRIPT_URL}" >${TMP_FILE} @@ -161,19 +162,38 @@ if echo "$IPV4" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192 BEHIND_NAT=true fi +insecure=false +if [[ $* == *--insecure* ]]; then + insecure=true +fi + sudo apt install -y software-properties-common sudo apt update -sudo apt install -y certbot openssl +sudo apt install -y openssl -print_green 'Getting wildcard cert' +if [[ "$insecure" = true ]]; then + print_green 'Generating self-signed cert' + certdir='/etc/ssl/tactical' + sudo mkdir -p $certdir + sudo chown ${USER}:${USER} $certdir + sudo chmod 770 $certdir + CERT_PRIV_KEY=${certdir}/privkey.pem + CERT_PUB_KEY=${certdir}/fullchain.pem + openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \ + -nodes -keyout ${CERT_PRIV_KEY} -out ${CERT_PUB_KEY} -subj "/CN=${rootdomain}" \ + -addext "subjectAltName=DNS:${rootdomain},DNS:*.${rootdomain}" + +else + sudo apt install -y certbot + print_green 'Getting wildcard cert' -sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email -while [[ $? -ne 0 ]]; do sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email -done - -CERT_PRIV_KEY=/etc/letsencrypt/live/${rootdomain}/privkey.pem -CERT_PUB_KEY=/etc/letsencrypt/live/${rootdomain}/fullchain.pem + while [[ $? -ne 0 ]]; do + sudo certbot certonly --manual -d *.${rootdomain} --agree-tos --no-bootstrap --preferred-challenges dns -m ${letsemail} --no-eff-email + done + CERT_PRIV_KEY=/etc/letsencrypt/live/${rootdomain}/privkey.pem + CERT_PUB_KEY=/etc/letsencrypt/live/${rootdomain}/fullchain.pem +fi sudo chown ${USER}:${USER} -R /etc/letsencrypt @@ -429,7 +449,11 @@ REDIS_HOST = "localhost" ADMIN_ENABLED = True EOF )" -echo "${localvars}" >/rmm/api/tacticalrmm/tacticalrmm/local_settings.py +echo "${localvars}" >$local_settings + +if [[ "$insecure" = true ]]; then + echo "TRMM_INSECURE = True" | tee --append $local_settings >/dev/null +fi if [ "$arch" = "x86_64" ]; then natsapi='nats-api' @@ -896,7 +920,7 @@ meshtoken="$( MESH_TOKEN_KEY = "${MESHTOKENKEY}" EOF )" -echo "${meshtoken}" | tee --append /rmm/api/tacticalrmm/tacticalrmm/local_settings.py >/dev/null +echo "${meshtoken}" | tee --append $local_settings >/dev/null print_green 'Creating meshcentral account and group' @@ -933,7 +957,7 @@ sudo systemctl enable nats-api.service sudo systemctl start nats-api.service ## disable django admin -sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' /rmm/api/tacticalrmm/tacticalrmm/local_settings.py +sed -i 's/ADMIN_ENABLED = True/ADMIN_ENABLED = False/g' $local_settings print_green 'Restarting services' for i in rmm.service daphne.service celery.service celerybeat.service; do