如何从 systemd 单元文件调用 iptables?

如何从 systemd 单元文件调用 iptables?

我正在尝试实现一个高度可用的内存缓存服务。启动需要阻止传入连接,直到数据从正在运行的实例中播种。但是,即使我设置了 CAP_NET_ADMIN,iptables 规则也会失败“iptables v1.6.1:无法初始化 iptables 表‘过滤器’:权限被拒绝(您必须是 root)”

我的覆盖文件是:

[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

(其中/etc/memcache/memcache-repl-start.sh start运行 iptables 命令)并且它覆盖的文件包含......

[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

如何从单元文件调用 iptables?

更新 按照以下方式禁用所有选项不会改变结果; iptables 仍然失败

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

如果我从命令行运行启动脚本,它会按预期工作。我检查过,当通过 systemctl 调用时,脚本正在以 root 用户身份运行。

答案1

执行所需的最低功能iptablesCAP_NET_RAWCAP_NET_ADMIN(至少在我的 RHEL 实例上进行了测试,但这应该是一个普遍现象)。我无法在快速搜索中找到任何相关的内容来解释为什么CAP_NET_RAW还需要这样做;但有根据的最佳猜测是 iptables 使用原始套接字来处理 MAC 过滤/任何在第 2 层发生的过滤。

这意味着您的覆盖文件应该如下所示;前提是您在其中执行的脚本不需要任何其他功能。

[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

特定规则可能需要额外的功能;但根据所提供的信息,我无法进一步挖掘。

相关内容