drogonframework / drogonframework/drogon
Add support for systemd socket activation
- Dominant language
- C++
- Stars
- 14.3k
- Forks
- 1.4k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 14
Description
**Is your feature request related to a problem? Please describe.**
I would like to run a Drogon web server (for instance the [helloworld example](https://github.com/drogonframework/drogon/tree/master/examples/helloworld)) on a Linux computer in such a way that if (hypothetically) the web server would be compromised, then the intruder should not be able to use the computer to connect to other computers on the internet.
**Describe the solution you'd like**
Add support for _systemd socket activation_ (see man page [sd_listen_fds()](https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html) and man page [systemd.socket](https://www.freedesktop.org/software/systemd/man/systemd.socket.html)).
It would then be possible to add the systemd directives [`RestrictAddressFamilies`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictAddressFamilies=) and [`PrivateNetwork`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateNetwork=) to a systemd service unit file.
```
RestrictAddressFamilies=none
PrivateNetwork=yes
```
If the web server does not need to connect to the internet (i.e, to make outbound TCP/UDP connections),
there is no need to list `AF_INET AF_INET6` in the value for `RestrictAddressFamilies`.
An intruder would then not have the permission to connect to web servers on other computers on the internet. Having this feature improves security.
This works for both of these situations:
* running the Drogon web server directly on the host in a systemd service
* running the Drogon web server as a container with Podman in a systemd service
Podman supports [socket activation of containers](https://github.com/containers/podman/blob/main/docs/tutorials/socket_activation.md#socket-activation-of-containers). (Docker does not support it).
I wrote an article with of how to run a socket-activated echo server with restricted network access (see https://www.redhat.com/sysadmin/podman-systemd-limit-access).
There is also a performance benefit of using _systemd socket activation_ with rootless Podman.
The traffic over a socket-activated socket has native network performance (i.e. the same performance as if you would run the web server directly on the host without any container). If you run rootless Podman the standard way (`podman run --publish 8080:80 ...`) there is some slowdown.
A sidenote: I wrote some docs about rootless Podman and networking:
https://github.com/eriksjolund/podman-networking-docs
__About the library "user interface" in Drogon:__
I suggest using the file descriptor names from the environment variable `LISTEN_FDNAMES` when referring to the sockets in the Drogon library functions. For example, adding a socket-activated socket could be done like this:
(this syntax does not yet exist)
```
app().addSystemdSocket("helloworld.socket");
```
__systemd__ has recently added the directive [`OpenFile=`](https://www.freedesktop.org/software/systemd/man/systemd.service.html#OpenFile=) that also makes use of the environment variable `LISTEN_FDNAMES` and the same file descriptor passing method (inheritance).
Drogon may get file descriptors of different types at the same time (socket file descriptors from socket activation and normal file descriptors from `OpenFile=`). Using the file descriptor names from `LISTEN_FDNAMES` in the Drogon library functions will make it easier to identify which file descriptors to use.
A sidenote: Systemd also supports passing Unix sockets with socket activation, so this feature could be useful for
* https://github.com/drogonframework/drogon/issues/1153
Contributor guide
Assessment
This issue has not been assessed yet.