Skip to content

Instantly share code, notes, and snippets.

@rany2
Last active May 8, 2023 07:25
Show Gist options
  • Save rany2/330c8fe202b318cacdcb54830c20f98c to your computer and use it in GitHub Desktop.
Save rany2/330c8fe202b318cacdcb54830c20f98c to your computer and use it in GitHub Desktop.
Hardened systemd service for PPP
[Unit]
Description=PPP connection for %I
Documentation=man:pppd(8)
StartLimitIntervalSec=0
Before=network.target
Wants=network.target
After=network-pre.target
[Service]
# https://github.com/ppp-project/ppp/commit/d34159f417620eb7c481bf53f29fe04c86ccd223
# otherwsise you can use 'forking' and replace 'up_sdnotify' with 'updetach'
Type=notify
ExecStart=/usr/sbin/pppd up_sdnotify nolog call %I
ExecStop=/bin/kill $MAINPID
ExecReload=/bin/kill -HUP $MAINPID
StandardOutput=null
# https://github.com/systemd/systemd/issues/481#issuecomment-544341423
Restart=always
RestartSec=1
# Sandboxing options to harden security
PrivateMounts=yes
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=strict
# ProtectKernelTunables breaks IPv6 negotiation for PPP. Further PPP
# needs to set some kernel settings if certain options were applied.
ProtectKernelTunables=no
ProtectControlGroups=yes
# allow /etc/ppp/resolv.conf to be written when using 'usepeerdns'
ReadWritePaths=/run/ /etc/ppp/
AmbientCapabilities=CAP_SYS_TTY_CONFIG CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN
CapabilityBoundingSet=CAP_SYS_TTY_CONFIG CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN
KeyringMode=private
NoNewPrivileges=yes
# AF_NETLINK is needed to add an entry to the IP route table
RestrictAddressFamilies=AF_NETLINK AF_PACKET AF_UNIX AF_PPPOX AF_ATMPVC AF_ATMSVC AF_INET AF_INET6 AF_IPX
ProtectProc=invisible
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
RemoveIPC=yes
ProtectHostname=yes
ProtectClock=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
LockPersonality=yes
SecureBits=no-setuid-fixup-locked noroot-locked
SystemCallFilter=@system-service
SystemCallArchitectures=native
# All pppd instances on a system must share a runtime
# directory in order for PPP multilink to work correctly. So
# we give all instances the same /run/pppd directory to store
# things in.
#
# For the same reason, we can't set PrivateUsers=yes, because
# all instances need to run as the same user to access the
# multilink database.
RuntimeDirectory=pppd
RuntimeDirectoryPreserve=yes
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment