Systemd (Linux)
Ghostunnel integrates with systemd on Linux for service management, socket activation, readiness notification, and automatic restart via the watchdog timer.
Basic Service Unit
The simplest way to run Ghostunnel under systemd is a Type=simple service:
[Unit]
Description=Ghostunnel
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ghostunnel server \
--listen=localhost:8443 \
--target=localhost:8080 \
--keystore=/etc/ghostunnel/server-keystore.p12 \
--cacert=/etc/ghostunnel/cacert.pem \
--allow-cn=client
Restart=always
[Install]
WantedBy=default.target
Notify and Watchdog
Available since v1.8.0.
Ghostunnel supports systemd’s notify and watchdog functionality. This allows systemd to know when Ghostunnel is ready and to automatically restart it if it becomes unresponsive.
When running as a Type=notify-reload service:
- Notify: Ghostunnel signals readiness to systemd after it has successfully loaded certificates and started listening. Systemd will not consider the service “started” until this signal is received.
- Watchdog: Ghostunnel periodically sends a heartbeat to systemd at the
interval specified by
WatchdogSec. If systemd does not receive a heartbeat within the configured interval, it considers the process hung and takes the action specified byRestart(typically restarting the service). - Reload: When you run
systemctl reload ghostunnel, systemd sendsSIGHUPto the process, which triggers a certificate reload (same as sendingSIGHUPmanually).
Example Unit File
[Unit]
Description=Ghostunnel
After=network.target
[Service]
Type=notify-reload
ExecStart=/usr/bin/ghostunnel server \
--listen=localhost:8443 \
--target=localhost:8080 \
--keystore=/etc/ghostunnel/server-keystore.p12 \
--cacert=/etc/ghostunnel/cacert.pem \
--allow-cn=client
WatchdogSec=5
Restart=always
[Install]
WantedBy=default.target
Notes
Type=notify-reloadrequires systemd v253 or later. If you are on an older version, useType=notifyinstead (reload viasystemctl reloadwill not work, but you can still sendSIGHUPmanually).- The
WatchdogSecvalue should be set based on your tolerance for downtime. A value of5(5 seconds) is a reasonable default. Very low values (e.g.1) may cause spurious restarts under heavy load. - Watchdog and notify functionality is only available on Linux. On other
platforms, use
Type=simpleand manage restarts via your service manager’s native mechanisms.
Socket Activation
Ghostunnel supports systemd socket activation for on-demand
startup. Socket activation is supported for the --listen and --status
flags by passing an address of the form systemd:<name>, where <name>
matches the FileDescriptorName in the socket unit.
Socket Unit
A ghostunnel.socket unit for listening on *:8443:
[Unit]
Description=Ghostunnel Socket
PartOf=ghostunnel.service
[Socket]
FileDescriptorName=ghostunnel
ListenStream=0.0.0.0:8443
[Install]
WantedBy=sockets.target
Corresponding Service Unit
A ghostunnel.service that forwards to localhost:8080:
[Unit]
Description=Ghostunnel
After=network.target ghostunnel.socket
Requires=ghostunnel.socket
[Service]
Type=simple
ExecStart=/usr/bin/ghostunnel server \
--listen=systemd:ghostunnel \
--target=localhost:8080 \
--keystore=/etc/ghostunnel/server-keystore.p12 \
--cacert=/etc/ghostunnel/cacert.pem \
--allow-cn=client
[Install]
WantedBy=default.target
The FileDescriptorName in ghostunnel.socket must match the name passed to
--listen. If multiple sockets are needed (e.g. for a status port), use the
name to distinguish them.
UNIX Socket Variant
To restrict access to a specific local user (see Security), have systemd create a UNIX domain socket with the desired ownership and mode instead of binding to TCP:
[Socket]
FileDescriptorName=ghostunnel
ListenStream=/run/ghostunnel.sock
SocketUser=root
SocketGroup=root
SocketMode=0600
systemd applies SocketUser/SocketGroup/SocketMode at socket creation
time, so only the intended user can connect(2) to it; no firewall rules
required. See systemd.socket(5) for the full list of
options.
Installing
# Copy unit files into place
sudo cp ghostunnel.socket ghostunnel.service /etc/systemd/system/
# Reload, enable, and start the socket
sudo systemctl daemon-reload
sudo systemctl enable --now ghostunnel.socket
systemd will start ghostunnel.service on demand when a connection arrives
on the socket.
Security Hardening
systemd provides sandboxing options that complement Ghostunnel’s built-in Landlock support. These settings restrict the service to the privileges it needs:
[Service]
# Dedicated unprivileged user. Use User=ghostunnel if you need persistent
# state or specific file ownership instead.
DynamicUser=yes
# Filesystem: most of the system becomes read-only outside /dev, /proc, /sys.
# Ghostunnel only needs read access to certs, which still works from standard
# readable locations such as /etc. Note that ProtectHome=yes makes /home and
# /root inaccessible, so certs should not be stored there unless you relax
# ProtectHome or add an explicit exception with ReadOnlyPaths=.
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectProc=invisible
# Network: only allow AF_INET/AF_INET6/AF_UNIX
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
# Capabilities: drop everything. Add CAP_NET_BIND_SERVICE if binding to a
# privileged port (< 1024) without socket activation.
CapabilityBoundingSet=
NoNewPrivileges=yes
# System call filter: allow only networking and basic I/O
SystemCallFilter=@system-service
SystemCallArchitectures=native
# Misc
LockPersonality=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
RemoveIPC=yes
UMask=0077
Run systemd-analyze security ghostunnel.service to audit the effective
security posture of your unit file.