refactor(linux-client): remove FIREZONE_ID from example systemd file (#4714)

For tests it doesn't hurt, but this will be used as a template for the
systemd service we ship to production, and that can't have the ID there.

So I'm also cleaning up a few other problems I noticed:
- I wanted to split the service files as part of #4531, so that the GUI
Client and headless Client can have separate sandbox rules. e.g, the
headless Client won't be allowed to create Unix domain sockets
- I'm punting more things to systemd, which allows us to tighten down
the sandbox further, e.g. creating `/var/lib/dev.firezone.client` and
`/run/dev.firezone.client` for us
- Closes #4461

---------

Signed-off-by: Reactor Scram <ReactorScram@users.noreply.github.com>
This commit is contained in:
Reactor Scram
2024-04-25 18:08:06 -05:00
committed by GitHub
parent a011a443e7
commit bc940784bd
6 changed files with 84 additions and 29 deletions

View File

@@ -7,18 +7,17 @@ source "./scripts/tests/lib.sh"
BINARY_NAME=firezone-linux-client
FZ_GROUP="firezone"
SERVICE_NAME=firezone-client
SERVICE_NAME=firezone-client-ipc
export RUST_LOG=info
# Copy the Linux Client out of the build dir
ls . ./rust ./rust/target ./rust/target/debug
sudo cp "rust/target/debug/firezone-headless-client" "/usr/bin/$BINARY_NAME"
sudo cp "scripts/tests/systemd/$SERVICE_NAME.service" /usr/lib/systemd/system/
# The firezone group must exist before the daemon starts
sudo groupadd "$FZ_GROUP"
sudo systemctl start "$SERVICE_NAME"
sudo systemctl start "$SERVICE_NAME" || systemctl status "$SERVICE_NAME"
# Add ourselves to the firezone group
sudo gpasswd --add "$USER" "$FZ_GROUP"

View File

@@ -4,7 +4,7 @@
source "./scripts/tests/lib.sh"
BINARY_NAME=firezone-linux-client
SERVICE_NAME=firezone-client
SERVICE_NAME=firezone-client-headless
# Copy the Linux Client out of its container
docker compose exec client cat firezone-linux-client > "$BINARY_NAME"
@@ -22,12 +22,12 @@ HTTPBIN=dns.httpbin
DOCKER_IFACE="docker0"
FZ_IFACE="tun-firezone"
# Accessing a resource should fail before the client is up
echo "# Accessing a resource should fail before the client is up"
# Force curl to try the Firezone interface. I can't block off the Docker interface yet
# because it may be needed for the client to reach the portal.
curl --interface "$FZ_IFACE" $HTTPBIN/get && exit 1
# Start Firezone
echo "# Start Firezone"
resolvectl dns tun-firezone && exit 1
stat /usr/bin/firezone-linux-client
sudo systemctl start "$SERVICE_NAME" || systemctl status "$SERVICE_NAME"

View File

@@ -0,0 +1,47 @@
[Unit]
Description=Firezone Client
[Service]
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
DeviceAllow=/dev/net/tun
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateMounts=true
PrivateTmp=true
# We need to be real root, not just root in our cgroup
PrivateUsers=false
ProcSubset=pid
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
# Docs say it's useless when running as root, but defense-in-depth
ProtectProc=invisible
ProtectSystem=strict
# Netlink needed for the tunnel interface, Unix needed for `systemd-resolved`
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
StateDirectory=dev.firezone.client
SystemCallArchitectures=native
# TODO: Minimize
SystemCallFilter=@aio @basic-io @file-system @io-event @network-io @signal @system-service
UMask=077
Environment="FIREZONE_API_URL=ws://localhost:8081"
Environment="FIREZONE_DNS_CONTROL=systemd-resolved"
Environment="RUST_LOG=info"
ExecStart=firezone-linux-client standalone
Type=notify
# Unfortunately we may need root to control DNS
User=root
[Install]
WantedBy=default.target

View File

@@ -3,7 +3,6 @@ Description=Firezone Client
[Service]
AmbientCapabilities=CAP_NET_ADMIN
# TODO: Get rid of `CAP_CHOWN` here by asking systemd to make our runtime dir on our behalf
CapabilityBoundingSet=CAP_CHOWN CAP_NET_ADMIN
DeviceAllow=/dev/net/tun
LockPersonality=true
@@ -23,23 +22,23 @@ ProtectKernelModules=true
ProtectKernelTunables=true
# Docs say it's useless when running as root, but defense-in-depth
ProtectProc=invisible
ProtectSystem=full
ProtectSystem=strict
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
RuntimeDirectory=dev.firezone.client
StateDirectory=dev.firezone.client
SystemCallArchitectures=native
# TODO: Minimize
SystemCallFilter=@aio @basic-io @file-system @io-event @ipc @network-io @signal @system-service
UMask=177
UMask=077
Environment="FIREZONE_API_URL=ws://localhost:8081"
Environment="FIREZONE_DNS_CONTROL=systemd-resolved"
Environment="FIREZONE_ID=D0455FDE-8F65-4960-A778-B934E4E85A5F"
Environment="RUST_LOG=info"
# TODO: Make subcommands explicit once PR #4628 merges
ExecStart=firezone-linux-client
ExecStart=firezone-linux-client ipc-service
Type=notify
# Unfortunately we may need root to control DNS
User=root