From 42e1717455f6d3933266e9be9dd10e4fce2c7492 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sun, 26 Jun 2022 21:41:06 +0000 Subject: [PATCH] add nats websocket support --- api/tacticalrmm/agents/models.py | 4 +++- .../management/commands/create_natsapi_conf.py | 5 ++++- api/tacticalrmm/tacticalrmm/helpers.py | 10 ++++++++++ api/tacticalrmm/tacticalrmm/utils.py | 9 ++++++++- docker/containers/tactical-nats/dockerfile | 2 +- docker/containers/tactical-nginx/entrypoint.sh | 14 ++++++++++++++ docker/docker-compose.yml | 1 + install.sh | 14 +++++++++++++- 8 files changed, 54 insertions(+), 5 deletions(-) diff --git a/api/tacticalrmm/agents/models.py b/api/tacticalrmm/agents/models.py index 0e63a15b..1256812e 100644 --- a/api/tacticalrmm/agents/models.py +++ b/api/tacticalrmm/agents/models.py @@ -37,6 +37,7 @@ from tacticalrmm.constants import ( PAAction, PAStatus, ) +from tacticalrmm.helpers import get_nats_ports from tacticalrmm.models import PermissionQuerySet if TYPE_CHECKING: @@ -786,8 +787,9 @@ class Agent(BaseAuditModel): async def nats_cmd( self, data: Dict[Any, Any], timeout: int = 30, wait: bool = True ) -> Any: + nats_std_port, _ = get_nats_ports() options = { - "servers": f"tls://{settings.ALLOWED_HOSTS[0]}:4222", + "servers": f"tls://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}", "user": "tacticalrmm", "password": settings.SECRET_KEY, "connect_timeout": 3, diff --git a/api/tacticalrmm/core/management/commands/create_natsapi_conf.py b/api/tacticalrmm/core/management/commands/create_natsapi_conf.py index 44cd3107..f4734e34 100644 --- a/api/tacticalrmm/core/management/commands/create_natsapi_conf.py +++ b/api/tacticalrmm/core/management/commands/create_natsapi_conf.py @@ -4,6 +4,8 @@ import os from django.conf import settings from django.core.management.base import BaseCommand +from tacticalrmm.helpers import get_nats_ports + class Command(BaseCommand): help = "Generate conf for nats-api" @@ -19,9 +21,10 @@ class Command(BaseCommand): else: ssl = "disable" + nats_std_port, _ = get_nats_ports() config = { "key": settings.SECRET_KEY, - "natsurl": f"tls://{settings.ALLOWED_HOSTS[0]}:4222", + "natsurl": f"tls://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}", "user": db["USER"], "pass": db["PASSWORD"], "host": db["HOST"], diff --git a/api/tacticalrmm/tacticalrmm/helpers.py b/api/tacticalrmm/tacticalrmm/helpers.py index 878b261f..8d12a53c 100644 --- a/api/tacticalrmm/tacticalrmm/helpers.py +++ b/api/tacticalrmm/tacticalrmm/helpers.py @@ -17,3 +17,13 @@ def get_certs() -> tuple[str, str]: def notify_error(msg: str) -> Response: return Response(msg, status=status.HTTP_400_BAD_REQUEST) + + +def get_nats_ports() -> tuple[int, int]: + """ + Returns: tuple[nats_standard_port: int, nats_websocket_port: int] + """ + nats_standard_port = getattr(settings, "NATS_STANDARD_PORT", 4222) + nats_websocket_port = getattr(settings, "NATS_WEBSOCKET_PORT", 9235) + + return (nats_standard_port, nats_websocket_port) diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index 6a5aea7f..12dbbd5d 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -28,7 +28,7 @@ from tacticalrmm.constants import ( DebugLogType, ScriptShell, ) -from tacticalrmm.helpers import get_certs, notify_error +from tacticalrmm.helpers import get_certs, notify_error, get_nats_ports def generate_winagent_exe( @@ -193,6 +193,8 @@ def reload_nats() -> None: ) cert_file, key_file = get_certs() + nats_std_port, nats_ws_port = get_nats_ports() + config = { "tls": { "cert_file": cert_file, @@ -200,6 +202,11 @@ def reload_nats() -> None: }, "authorization": {"users": users}, "max_payload": 67108864, + "port": nats_std_port, # internal only + "websocket": { + "port": nats_ws_port, + "no_tls": True, # TLS is handled by nginx, so not needed here + }, } conf = os.path.join(settings.BASE_DIR, "nats-rmm.conf") diff --git a/docker/containers/tactical-nats/dockerfile b/docker/containers/tactical-nats/dockerfile index 85e0a03f..1a800c03 100644 --- a/docker/containers/tactical-nats/dockerfile +++ b/docker/containers/tactical-nats/dockerfile @@ -26,4 +26,4 @@ ENTRYPOINT [ "/entrypoint.sh" ] USER 1000 -EXPOSE 4222 +EXPOSE 4222 9235 diff --git a/docker/containers/tactical-nginx/entrypoint.sh b/docker/containers/tactical-nginx/entrypoint.sh index 2908c8bf..f50b5c5a 100644 --- a/docker/containers/tactical-nginx/entrypoint.sh +++ b/docker/containers/tactical-nginx/entrypoint.sh @@ -10,6 +10,7 @@ set -e : "${FRONTEND_SERVICE:=tactical-frontend}" : "${MESH_SERVICE:=tactical-meshcentral}" : "${WEBSOCKETS_SERVICE:=tactical-websockets}" +: "${NATS_SERVICE:=tactical-nats}" : "${DEV:=0}" : "${CERT_PRIV_PATH:=${TACTICAL_DIR}/certs/privkey.pem}" @@ -97,6 +98,19 @@ server { proxy_set_header X-Forwarded-Host \$server_name; } + location ~ ^/natsws { + set \$natswebsocket http://${NATS_SERVICE}:9235; + proxy_pass \$natswebsocket; + proxy_http_version 1.1; + + proxy_set_header Host \$host; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Host \$host:\$server_port; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + client_max_body_size 300M; listen 4443 ssl; diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 51615aec..8e0e53a1 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -86,6 +86,7 @@ services: API_HOST: ${API_HOST} ports: - "4222:4222" + - "9235:9235" volumes: - tactical_data:/opt/tactical networks: diff --git a/install.sh b/install.sh index cf7774e2..9a30c0dc 100644 --- a/install.sh +++ b/install.sh @@ -556,6 +556,18 @@ server { proxy_set_header X-Forwarded-Host \$server_name; } + location ~ ^/natsws { + proxy_pass http://127.0.0.1:9235; + proxy_http_version 1.1; + + proxy_set_header Host \$host; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Host \$host:\$server_port; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } + location / { uwsgi_pass tacticalrmm; include /etc/nginx/uwsgi_params; @@ -864,7 +876,7 @@ if [ "$BEHIND_NAT" = true ]; then echo -ne "${GREEN}If you will be accessing the web interface of the RMM from the same LAN as this server,${NC}\n" echo -ne "${GREEN}you'll need to make sure your 3 subdomains resolve to ${IPV4}${NC}\n" echo -ne "${GREEN}This also applies to any agents that will be on the same local network as the rmm.${NC}\n" - echo -ne "${GREEN}You'll also need to setup port forwarding in your router on ports 80, 443 and 4222 tcp.${NC}\n\n" + echo -ne "${GREEN}You'll also need to setup port forwarding in your router on port 443${NC}\n\n" fi printf >&2 "${YELLOW}Please refer to the github README for next steps${NC}\n\n"