[Unit] Description=Jumphost Gateway Application After=network.target guacd.service Wants=guacd.service [Service] Type=simple User={{ jumphost_app_user }} Group={{ jumphost_app_group }} WorkingDirectory={{ jumphost_home }} Environment=JUMPHOST_ENV=production Environment=JUMPHOST_DATA_DIR={{ jumphost_data_dir }} Environment=JUMPHOST_LISTEN_UDS={{ jumphost_listen_uds }} Environment=JUMPHOST_GUACD_HOST=127.0.0.1 Environment=JUMPHOST_GUACD_PORT={{ guacd_port }} {% if not enable_nginx_proxy %} Environment=JUMPHOST_DIRECT_TLS=1 {% endif %} {% if _creds_check.rc == 0 %} LoadCredentialEncrypted=jumphost_kek:/etc/jumphost/jumphost_kek.cred LoadCredentialEncrypted=jumphost_session_secret:/etc/jumphost/jumphost_session_secret.cred {% else %} EnvironmentFile=/etc/jumphost/env {% endif %} # E.4 (Umsetzungsauftrag Teil E): --limit-concurrency/--backlog waren # vorher gar nicht gesetzt (uvicorn-Standardwerte). Ohne Obergrenze kann ein # Ansturm an Verbindungen (absichtlich oder nicht) den einzigen Worker- # Prozess ueberlasten, bevor die anwendungsseitigen Sitzungsgrenzen # (settings.max_sessions_*, app/security/active_sessions.py) je greifen # koennen -- die laufen erst NACH Annahme der Verbindung. Werte ueber # group_vars konfigurierbar (siehe ansible/inventory/group_vars/all.yml). {% if enable_nginx_proxy %} ExecStart={{ jumphost_venv }}/bin/uvicorn app.main:app --uds {{ jumphost_listen_uds }} \ --limit-concurrency {{ jumphost_uvicorn_limit_concurrency }} --backlog {{ jumphost_uvicorn_backlog }} {% else %} ExecStart={{ jumphost_venv }}/bin/uvicorn app.main:app --host 0.0.0.0 --port {{ jumphost_app_port }} \ --ssl-certfile /etc/jumphost/tls/server.crt --ssl-keyfile /etc/jumphost/tls/server.key \ --limit-concurrency {{ jumphost_uvicorn_limit_concurrency }} --backlog {{ jumphost_uvicorn_backlog }} {% endif %} Restart=on-failure RestartSec=5 # E.4 (Umsetzungsauftrag Teil E): kein LimitNOFILE gesetzt bedeutet den # ererbten systemd-Standard (i.d.R. 1024) statt eines bewusst gesetzten, # dokumentierten Werts. Jede Sitzung kostet mindestens zwei Sockets # (Browser-WebSocket, Ziel), RDP zusaetzlich die guacd-Verbindung, dazu # die Aufzeichnungsdatei -- der Standardwert reicht fuer den geplanten # Betrieb rechnerisch aus, gehoert aber explizit gesetzt statt geerbt. LimitNOFILE={{ jumphost_limit_nofile }} # --- Hardening (Konzept 6.7/8.1) --------------------------------------------- NoNewPrivileges=true ProtectSystem=strict ProtectHome=true PrivateTmp=true PrivateDevices=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true RestrictNamespaces=true RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 RestrictSUIDSGID=true MemoryDenyWriteExecute=true LockPersonality=true SystemCallFilter=@system-service SystemCallErrorNumber=EPERM CapabilityBoundingSet= ReadWritePaths={{ jumphost_data_dir }} /run/jumphost /var/log/jumphost UMask=0077 [Install] WantedBy=multi-user.target