systemd: tight sandboxing (#103)

wireproxy needs very little permissions, we can restrict it to basically
nothing. DynamicUser means the system will generate a UID on demand
for service, also CAP_NET_BIND_SERVICE can be used to allow this user
to bind to a port < 1024 if desired. Also LoadCredential lets us read
a file with tight permissions i.e. root:root 0400 and pass it to only
wireproxy in an ephemeral and constrained manner.

Signed-off-by: J. Dekker <jdek@itanimul.li>
This commit is contained in:
J. Dekker 2024-03-18 17:42:03 +01:00 committed by GitHub
parent c710def46d
commit 4f066d050a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 22 deletions

View file

@ -13,24 +13,12 @@ The provided systemd unit assumes you have the wireproxy executable installed on
2. If necessary, customize the unit.
Edit the parts with `ExecStartPre=` and `ExecStart=` to point to the executable and the configuration file. For example, if wireproxy is installed on `/usr/bin` and the configuration file is located in `/opt/myfiles/wireproxy.conf` do the following change:
Edit the parts with `LoadCredential`, `ExecStartPre=` and `ExecStart=` to point to the executable and the configuration file. For example, if wireproxy is installed on `/usr/bin` and the configuration file is located in `/opt/myfiles/wireproxy.conf` do the following change:
```service
ExecStartPre=/usr/bin/wireproxy -n -c /opt/myfiles/wireproxy.conf
ExecStart=/usr/bin/wireproxy -c /opt/myfiles/wireproxy.conf
LoadCredential=conf:/opt/myfiles/wireproxy.conf
ExecStartPre=/usr/bin/wireproxy -n -c ${CREDENTIALS_DIRECTORY}/conf
ExecStart=/usr/bin/wireproxy -c ${CREDENTIALS_DIRECTORY}/conf
```
#### 2.2 Drop root privileges (optional, but recommended)
Without any modifications, this Wireproxy service will run as root. You might want to drop those privileges. One way to do this is to simply create a system account for Wireproxy (or just use your own user account to run it instead).
```bash
sudo useradd --comment "Wireproxy tunnel" --system wireproxy
```
Then uncomment these lines from the wireproxy.service:
```service
#User=wireproxy
#Group=wireproxy
```
Caveats:
1) Make sure `wireproxy` user can read the wireproxy configuration file.
2) Also note that unprivileged user cannot bind to ports below 1024 by default.
4. Reload systemd and enable the unit.
```bash

View file

@ -4,15 +4,43 @@ Wants=network-online.target
After=network-online.target
[Service]
#Uncomment and/or change these if you don't want to run Wireproxy as root
#User=wireproxy
#Group=wireproxy
User=wireproxy
Group=wireproxy
SyslogIdentifier=wireproxy
Type=simple
Restart=on-failure
RestartSec=30s
ExecStartPre=/opt/wireproxy/wireproxy -n -c /etc/wireproxy.conf
ExecStart=/opt/wireproxy/wireproxy -c /etc/wireproxy.conf
SyslogIdentifier=wireproxy
DynamicUser=yes
LoadCredential=conf:/etc/wireproxy.conf
ExecStartPre=/opt/wireproxy/wireproxy -n -c ${CREDENTIALS_DIRECTORY}/conf
ExecStart=/opt/wireproxy/wireproxy -c ${CREDENTIALS_DIRECTORY}/conf
# Required if <1024 port
#AmbientCapabilities=CAP_NET_BIND_SERVICE
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
LimitNPROC=64
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
PrivateUsers=true
ProcSubset=pid
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK
RestrictNamespaces=true
RestrictRealtime=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
[Install]
WantedBy=multi-user.target