1

I am trying to implement a highly available memcache service. The startup needs to block incoming connections until the data has been seeded from a running instance. However, even though I have set CAP_NET_ADMIN the iptables rules fail "iptables v1.6.1: can't initialize iptables table `filter': Permission denied (you must be root)".

My override file is:

[Service]
Type=forking
ExecStart=
ExecStart=/etc/memcache/memcache-repl-start.sh start
ExecStop=/etc/memcache/memcache-repl-start.sh stop
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE CAP_NET_ADMIN

(where the /etc/memcache/memcache-repl-start.sh start runs the iptables command) And the file it is overriding contains....

[Unit]
Description=memcached daemon
After=network.target
Documentation=man:memcached(1)

[Service]
ExecStart=/usr/share/memcached/scripts/systemd-memcached-wrapper /etc/memcached.conf
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
MemoryDenyWriteExecute=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictNamespaces=true
PIDFile=/var/run/memcached/memcached.pid
Restart=always

[Install]
WantedBy=multi-user.target

How can I invoke iptables from a unit file?

update Disabling ALL the options as per below did not change the outcome; iptables still fails

MemoryDenyWriteExecute=false
ProtectKernelModules=false
ProtectKernelTunables=false
ProtectControlGroups=false
RestrictRealtime=false
RestrictNamespaces=false
PrivateTmp=false
ProtectSystem=false
NoNewPrivileges=false
PrivateDevices=false

If I run the start script from the command line, it works as expected. I checked and the script is being run as the root user when invoked via systemctl.

1
  • Ubuntu 18.04. Apparmor is not reporting anything in the logs. Will get back to you on the variant.
    – symcbean
    Mar 14, 2022 at 18:41

1 Answer 1

1

The bare minimum Capabilties required to execute iptables are CAP_NET_RAW and CAP_NET_ADMIN (At least tested on my RHEL instance, but this should be a general thing). I wasn't able to dig up anything relevant in a quick search as to why CAP_NET_RAW was also required; But an educated best guess would be that iptables uses raw sockets to handle MAC filtering/any filtering that would occur at Layer 2.

This means your override file should look something like this; Provided there aren't any additional Capabilities the script you are executing in it requires.

[Service]
Type=forking
ExecStart=
ExecStart=/etc/memcache/memcache-repl-start.sh start
ExecStop=/etc/memcache/memcache-repl-start.sh stop
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE CAP_NET_ADMIN CAP_NET_RAW

It's possible that particular rules could require additional Capabilities; But with the information provided I can't dig very much further.

1
  • 1
    Doing strace on iptables tells why: socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER) = 3. So it's a RAW socket, but for the netlink API (for iptables-nft). iptables-legacy using the legacy API does: socket(AF_INET, SOCK_RAW, IPPROTO_RAW) = 3 .
    – A.B
    Mar 14, 2022 at 22:20

You must log in to answer this question.

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