1

The use case is: running isolated services, either as a hardened systemd unit file -- with close to a zero score on systemd-analyze security, or a linux container.

Both of those will place services listening on localnet (127.0.0.0/8-ish) on a high port (with minimum capabilities, namespaced network/users/proceses, etc).

The problem then is how to best route connections to them.

option A) is to route them to localnet with nftable prerouting/contrack and then offloading routing to kernel. But most security reviews i've seen assume net.ipv4.conf.eth0.route_localnet=0 (unless they are for a router, but then they exclude everything but ssh on the exposed surface) and I found little validated literature on the caveats. Will I have to worry about exploits on 802.Q and such? will malformed packages reach some service on localnet which i'm not intending to expose (maybe behind a ssh or wireguard tunnel only)? Will I have to make my input filter nftable rules as complex as an edge router for all servers?

Option B) Allow unpriviledged user process/container listen on the priviledged port by giving it CAP_NET_BIND_SERVICE (and maybe adding further restrictions such as SocketBindAllow=tcp:443 in the service's unit file) and, here is the part that really worries me, NOT using an isolated/namespaced network (or using one with routable ip). But systemD have even less validation by reputable organizations, that I can find. I'm thinking the only protection i will be losing is an exploit on the isolated service now can poke the network or worst be used on lateral movement? Which is not exactly prevented by namespaced network, but it does make it much easier to add the protection on nftables later.

Basically, I'm weighting ways to improve protection against user service, without making bigger holes on the system itself. Option A expose a larger surface on the kernel, and B on the service. But I can't objectively measure which is larger.

There's a third option which is Option A + routing in userland (that is, net.ipv4.conf.eth0.route_localnet remains set to zero), but I ran some tests with socat and it's very slow. Are there better established solutions for this pattern? I can edit the question to add them.

1 Answer 1

1

Let systemd create the listening socket. Systemd can create the listening socket:

[Unit]
Description=Foo Socket

[Socket]
ListenStream=/run/foo.sock
SocketMode=0660
# or: ListenStream=9000

[Install]
WantedBy=sockets.target

Systemd can pass this socket to your service. The socket and your service do not need to live in the same network namespace. Your service does not even need to have any access to the network.

1
  • oh I always assumed the [socket] section was for services to be spawned on socked signals, like inetd on demand. Will read the linked manual. Thanks!
    – gcb
    Commented Sep 2 at 17:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .