[Unit]
Description=Shroud — Shadowsocks + AmneziaWG VPN Server
Documentation=https://sourcecraft.dev/bigbes/shroud
After=network-online.target nss-lookup.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/shroud -c /etc/shroud/config.yaml
Restart=on-failure
RestartSec=5
WatchdogSec=60
# Logging — stdout/stderr go straight to journald.
# View with: journalctl -u shroud -f
# Filter errors: journalctl -u shroud -p err
StandardOutput=journal
StandardError=journal
SyslogIdentifier=shroud
# File descriptors
LimitNOFILE=65536
# Run as dedicated user (created by install script)
User=shroud
Group=shroud
# Capabilities — needed for:
# CAP_NET_BIND_SERVICE — bind to ports < 1024 (AWG on 443, ACME on 80)
# CAP_NET_ADMIN — create/configure TUN device (AWG)
# CAP_NET_RAW — raw socket for UDP listeners
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN CAP_NET_RAW
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=no
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
RestrictNamespaces=yes
RestrictRealtime=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
RemoveIPC=yes
SystemCallArchitectures=native
# Writable paths for state, certs, and TUN device
ReadWritePaths=/var/lib/shroud /etc/shroud /dev/net/tun
# Allow /dev/net/tun access for AWG
DeviceAllow=/dev/net/tun rw
[Install]
WantedBy=multi-user.target