index : static-web-server.git

ascending towards madness

author Tim Small <tim@seoss.co.uk> 2021-05-23 10:24:49.0 +00:00:00
committer Tim Small <tim@seoss.co.uk> 2021-05-31 10:52:35.0 +00:00:00
commit
24ea110489210044c3495d3ebc3589e5291e216a [patch]
tree
231b258ce7c0dcf11876c9874d9a396497549ecf
parent
b91ad87b928c86643c5e1ef124f8cc1818a55c5c
download
24ea110489210044c3495d3ebc3589e5291e216a.tar.gz

Add example systemd unit files, for socket activation.

Example systemd unit files which implement security sandboxing with
systemd, including the use of socket activation (in which systemd binds
TCP network socket listeners, and passes them to static-web-server in
the form of inherited file descriptors).

Diff

 src/config.rs                         |   4 +-
 systemd/etc_default_static-web-server |   5 ++-
 systemd/static-web-server.service     | 107 +++++++++++++++++++++++++++++++++++-
 systemd/static-web-server.socket      |  18 ++++++-
 4 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/src/config.rs b/src/config.rs
index b60e250..5966f1a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -21,7 +21,9 @@ pub struct Config {
    /// socket listener on the specified file descriptor number (usually zero). Requires that the
    /// parent process (e.g. inetd, launchd, or systemd) binds an address and port on behalf of
    /// static-web-server, before arranging for the resulting file descriptor to be inherited by
    /// static-web-server. Cannot be used in conjunction with the port and host arguments.
    /// static-web-server. Cannot be used in conjunction with the port and host arguments. The
    /// included systemd unit file utilises this feature to increase security by allowing the
    /// static-web-server to be sandboxed more completely.
    pub fd: Option<usize>,

    #[structopt(
diff --git a/systemd/etc_default_static-web-server b/systemd/etc_default_static-web-server
new file mode 100644
index 0000000..1e0e952
--- /dev/null
+++ b/systemd/etc_default_static-web-server
@@ -0,0 +1,5 @@
SERVER_ROOT=/var/www/html
SERVER_HTTP2_TLS=true
SERVER_HTTP2_TLS_CERT=/etc/static-web-server/example_org_fullchain.pem
SERVER_HTTP2_TLS_KEY=/etc/static-web-server/example_org_privkey.pem
SERVER_LOG_LEVEL=warn
diff --git a/systemd/static-web-server.service b/systemd/static-web-server.service
new file mode 100644
index 0000000..e9a7f02
--- /dev/null
+++ b/systemd/static-web-server.service
@@ -0,0 +1,107 @@
# Example systemd service unit file (see systemd.service(5) man page) for use
# with the --fd option of static-web-server.  This allows e.g. binding the
# server to a TCP port number 0 - 1023 without running the server as root,
# and/or running sws in an isolated network name space.
#
# This also allows sws to be started on-demand.  If sws is restart (e.g. after
# updating its SSL certificates, or reconfiguring its content directory), new
# inbound connections will be queued until sws is up and running again.
#
# A comprehensive description can be found in:
# http://0pointer.de/blog/projects/socket-activation.html
# ...and the linked articles.

[Unit]
Description=Static Web Server
Wants=static-web-server.socket
After=static-web-server.socket

# The options below reflect a reasonably comprehensive sandboxing based on the
# features available in systemd v247.  Newer versions of systemd may offer
# additional options for sandboxing.
#
# The options below focus on security, when making changes to this unit file
# you may wish to evaluated the output of:
# systemd-analyze security static-web-server.service
#
# Beyond the limits used here, additional limits can be placed on CPU, memory,
# and disk I/O, as well as network traffic filters (via eBPF and other
# mechanisms), and implemented for this server using the systemd override
# facilities.  See systemd.resource-control(5) for details.

[Service]
Type=simple

# An example environment file for static-web-server is included in the file:
# systemd/etc_default_static-web-server
EnvironmentFile=/etc/default/static-web-server

# File descriptor 0 corresponds to the standard input...
ExecStart=/usr/local/bin/static-web-server --fd 0

# ...so the following line attaches fd 0 of the static web server process to
# the socket defined by the corresponding `static-web-server.socket` unit file.
# Each instance of static-web-server currently only supports listening on a
# single socket.
StandardInput=fd:static-web-server.socket

# Debug and tracing output goes to stderr, and can be viewed with e.g.
# `journalctl -u static-web-server.service`.
StandardError=journal

Restart=always
RestartSec=5
DynamicUser=true
SupplementaryGroups=www-data
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
CapabilityBoundingSet=
RestrictNamespaces=true

#RestrictAddressFamilies=none
# ☟ workaround to implement ☝in older versions of systemd.
#   see: https://github.com/systemd/systemd/issues/15753
RestrictAddressFamilies=AF_UNIX
RestrictAddressFamilies=~AF_UNIX

PrivateDevices=true
PrivateUsers=true
PrivateNetwork=true
ProtectClock=true
ProtectControlGroups=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProcSubset=pid
RestrictSUIDSGID=true
SystemCallArchitectures=native
RestrictRealtime=true
LockPersonality=true
RemoveIPC=true
MemoryDenyWriteExecute=true
UMask=077
ProtectHostname=true

# Restrict the use of exotic system calls (bugs in seldom-used syscalls are a
# historical source of kernel vulnerabilities)...
SystemCallFilter=@system-service
# ... It may be possible to restrict this further.  e.g.
#SystemCallFilter=@signal @basic-io @io-event @network-io @process statx fstat sched_getaffinity getrandom
# but a process to discover the set of system calls used (e.g. as part of the
# unit tests) will probably be needed to avoid regressions e.g. due to changes
# in crates which are used by static-web-server. The following may be useful to
# record system calls performed:
# "/usr/bin/strace --summary-only -o sws.syscallstats -- static-web-server [...]"
# You can view the sets of system calls defined by systemd using:
# "systemd-analyze syscall-filter"

DevicePolicy=strict
DeviceAllow=/dev/null rw
DeviceAllow=/dev/random r
DeviceAllow=/dev/urandom r

[Install]
WantedBy=multi-user.target
diff --git a/systemd/static-web-server.socket b/systemd/static-web-server.socket
new file mode 100644
index 0000000..d2f8b26
--- /dev/null
+++ b/systemd/static-web-server.socket
@@ -0,0 +1,18 @@
# Example systemd socket unit file (see systemd.socket(5) man page) for use
# with the --fd option of static-web-server.  This allows e.g. binding the
# server to a TCP port number 0 - 1023 without running the server as root,
# and/or running sws in an isolated network name space.
#
# A comprehensive description can be found in:
# http://0pointer.de/blog/projects/socket-activation.html
# ...and the linked articles.

[Unit]
Description=Static Web Server Socket

[Socket]
ListenStream=443
Accept=no

[Install]
WantedBy=sockets.target