Using "none" instead of "AF_INET AF_INET6" for RestrictAddressFamilies= in systemd unit rest-server.service

Does the rest-server need to create outbound TCP connections?

If not it might be possible to remove AF_INET AF_INET6 from the RestrictAddressFamilies= line

--- a/examples/systemd/rest-server.service
+++ b/examples/systemd/rest-server.service
@@ -51,7 +51,7 @@ ProtectProc=invisible
 ProtectHostname=true
 RemoveIPC=true
 RestrictNamespaces=true
-RestrictAddressFamilies=AF_INET AF_INET6
+RestrictAddressFamilies=none
 RestrictSUIDSGID=true
 RestrictRealtime=true
 # if your service crashes with "code=killed, status=31/SYS", you probably tried to run linux_i386 (32bit) binary on a amd64 host

That would improve security.

(I haven’t tried it out yet)

Quote from systemd.exec man page

Sockets passed into the process by other means
(for example, by using socket activation with socket
units, see systemd.socket(5)) are unaffected.

I’ve previously used Podman to run a socket-activated network server container. It worked fine and I didn’t need to use AF_INET AF_INET6 in the RestrictAddressFamilies list.

Podman supports socket activation of containers. (Docker does not have that feature)

I did a minimal test and it worked!

In the test the systemd unit files were modified like this

--- a/examples/systemd/rest-server.service
+++ b/examples/systemd/rest-server.service
@@ -11,7 +11,7 @@ Type=simple
 # You may prefer to use a different user or group on your system.
 User=www-data
 Group=www-data
-ExecStart=/usr/local/bin/rest-server --path /path/to/backups
+ExecStart=/usr/local/bin/rest-server --path /usr/local/backups --no-auth
 Restart=always
 RestartSec=5
 
@@ -25,7 +25,7 @@ RestartSec=5
 
 # IMPORTANT!
 # The following line must be customised to your individual requirements.
-ReadWritePaths=/path/to/backups
+ReadWritePaths=/usr/local/backups
 
 # Makes created files group-readable, but inaccessible by others
 UMask=027
@@ -51,7 +51,7 @@ ProtectProc=invisible
 ProtectHostname=true
 RemoveIPC=true
 RestrictNamespaces=true
-RestrictAddressFamilies=AF_INET AF_INET6
+RestrictAddressFamilies=none
 RestrictSUIDSGID=true
 RestrictRealtime=true
 # if your service crashes with "code=killed, status=31/SYS", you probably tried to run linux_i386 (32bit) binary on a amd64 host
diff --git a/examples/systemd/rest-server.socket b/examples/systemd/rest-server.socket
index ba3262a..24990c7 100644
--- a/examples/systemd/rest-server.socket
+++ b/examples/systemd/rest-server.socket
@@ -1,5 +1,5 @@
 [Socket]
-ListenStream = 8080
+ListenStream = 127.0.0.1:8080
 
 [Install]
 WantedBy = sockets.target

Test

  • restic init
  • restic backup
  • restic snapshots
[test@localhost ~]$ restic -r rest:http://127.0.0.1:8080/ init
enter password for new repository: 
enter password again: 
created restic repository ddb72c517c at rest:http://127.0.0.1:8080/

Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.
[test@localhost ~]$ restic -r rest:http://127.0.0.1:8080/  --verbose backup ~/mydata
open repository
enter password for repository: 
repository ddb72c51 opened (version 2, compression level auto)
created new cache in /var/home/test/.cache/restic
lock repository
no parent snapshot found, will read all files
load index files
start scan on [/var/home/test/mydata]
start backup on [/var/home/test/mydata]
scan finished in 0.217s: 1 files, 6 B

Files:           1 new,     0 changed,     0 unmodified
Dirs:            4 new,     0 changed,     0 unmodified
Data Blobs:      1 new
Tree Blobs:      5 new
Added to the repository: 2.310 KiB (1.928 KiB stored)

processed 1 files, 6 B in 0:00
snapshot 2be041f9 saved
[test@localhost ~]$ restic -r rest:http://127.0.0.1:8080/  --verbose snapshots
enter password for repository: 
repository ddb72c51 opened (version 2, compression level auto)
ID        Time                 Host                   Tags        Paths
-----------------------------------------------------------------------------------------
2be041f9  2023-07-07 05:23:58  localhost.localdomain              /var/home/test/mydata
-----------------------------------------------------------------------------------------
1 snapshots
[test@localhost ~]$

I created a git branch

that could become a PR

I repeated the test with the only difference that I also added this line

PrivateNetwork=yes

It also worked.

The command
systemd-analyze security rest-server.service
recommends using such a configuration.

That makes it mandatory to also uncomment Requires=rest-server.socket in rest-server.service.

It might be a good idea to also add one or two sentences that the PrivateNetwork works due to the use of a socket unit.

Created a PR