[Unit] Description=lchat control daemon (local provisioning API) After=network-online.target Wants=network-online.target [Service] # The router's env FIRST: controld executes add-instance, whose mesh route # replication (fanOutMeshRoute) must see the box's mesh identity exactly as # the router does (LCHAT_MESH_SELF/_TOKEN/_DOMAINS, the hibernate bucket + # store credentials). Without this line the fan-out silently no-ops and any # create HRW-placed on a peer box is born dark — the peer answers "unknown # host" for it. control.env second, so control-specific values still win. EnvironmentFile=-/data/router.env # Optional overrides: LCHAT_MAX_INSTANCES / LCHAT_MIN_FREE_GB (capacity policy). EnvironmentFile=-/data/control.env ExecStart=/opt/lchat/lchat controld Restart=always RestartSec=1 # --- hardening (see docs/instance-router.md § Hardening) --- # Runs as ROOT deliberately: this is the one process allowed to call systemctl # and write the version store (/opt/lchat), which is why it serves a local unix # socket only and is never routed publicly. NoNewPrivileges and the syscall # filter are omitted for the systemctl child; the rest of the sandbox applies. ProtectHome=yes PrivateTmp=yes PrivateDevices=yes ProtectClock=yes ProtectHostname=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectKernelLogs=yes RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictNamespaces=yes RestrictRealtime=yes LockPersonality=yes MemoryDenyWriteExecute=yes MemoryMax=256M TasksMax=64 [Install] WantedBy=multi-user.target