我正在尝试实现一个高度可用的内存缓存服务。启动需要阻止传入连接,直到数据从正在运行的实例中播种。但是,即使我设置了 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
执行所需的最低功能iptables
是CAP_NET_RAW
和CAP_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
特定规则可能需要额外的功能;但根据所提供的信息,我无法进一步挖掘。