Ubuntu 14.04 から 16.04 にアップグレードした後、iptables モジュールがロードされない

Ubuntu 14.04 から 16.04 にアップグレードした後、iptables モジュールがロードされない

そこで、systemd について少し否定的な見方をしていたにもかかわらず、Ubuntu 16.04 を試してみることにしました。

アップグレード後、以前は持続していた OpenVPN 接続が機能しなくなりました。幸い、システム ログは根本原因を指摘するのに非常に役立ちます。

openvpn-up: + /sbin/iptables -t nat -D POSTROUTING -o tun0 -s 192.168.x.x -j SNAT --to-source 10.x.x.x
openvpn-up: modprobe: ERROR: could not insert 'ip_tables': Operation not permitted
openvpn-up: iptables v1.6.0: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
openvpn-up: Perhaps iptables or your kernel needs to be upgraded.
openvpn-up: + /sbin/iptables -t nat -A POSTROUTING -o tun0 -s 192.168.x.x -j SNAT --to-source 10.x.x.x
openvpn-up: modprobe: ERROR: could not insert 'ip_tables': Operation not permitted
openvpn-up: iptables v1.6.0: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
ovpn-conn[613]: WARNING: Failed running command (--up/--down): external program exited with error status: 3
openvpn-up: Perhaps iptables or your kernel needs to be upgraded.
ovpn-conn[613]: Exiting due to fatal error

注: これらは、スクリプトopenvpn-upの 2 行目のコメントを解除することによって生成されました/etc/openvpn/openvpn-up.sh(行の読み取り: exec &> >(logger -s -t openvpn-up) && set -x)。

うーん、何らかの理由でip_tablesモジュールをロードできなかったようです。 でカーネル モジュールがすべて揃っていることを確認した後apt-get install --reinstall linux-image-$(uname -r)、 を使用しようとしたところ、でロードされたことが確認できましたが、システム ログにも次のようmodprobe ip_tablesに表示されています。lsmod

kernel: [  446.293882] ip_tables: (C) 2000-2006 Netfilter Core Team

そして、この時点以降に実行すると、確かにsystemctl restart openvpn接続が確立され、iptables-save出力によって適切な SNAT ルールが追加されたことが証明されます。

私の推測OpenVPN ユニットが、使用するための十分な権限を持たないユーザー コンテキストで実行されるようになりましたmodprobe

しかし、私はこの疑惑を確認することができませんでした。実際、出力はsystemctl cat openvpn私を非常に混乱させます。

# systemctl cat [email protected]
# /lib/systemd/system/[email protected]
[Unit]
Description=OpenVPN connection to %i
PartOf=openvpn.service
ReloadPropagatedFrom=openvpn.service
Before=systemd-user-sessions.service
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO

[Service]
PrivateTmp=true
KillMode=mixed
Type=forking
ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid
PIDFile=/run/openvpn/%i.pid
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/etc/openvpn
ProtectSystem=yes
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_AUDIT_WRITE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw

[Install]
WantedBy=multi-user.target

ありますか能力スクリプトがinsmod/を正常に呼び出すためにこれを有効にする必要がありますかmodprobe? これはかなり粗雑に思えるので追加を避けたいと思います。 または、を にドロップすることによってモジュールCAP_SYS_ADMINをロードする唯一の方法ですか?ip_tables.conf/etc/modprobe.d

私が尋ねているのは、基本的に次のことです。標準のUbuntu 16.04(ない14.04からアップグレードされました)このタスクを達成しますか?つまり、正規の(そしてどのようにすればそれを実行できるでしょうか (標準的な方法)? そして最後に、特定のユニットがどのユーザー コンテキストで実行されるか (より正確には、どの機能で実行されるか) をどのように判断すればよいでしょうか?

答え1

systemd ディレクティブのドキュメントは、 から調べることができますman system.directives。そこから、CapabilityBoundingSet=が にドキュメント化されていることが分かりましたman systemd.exec

そこから、さまざまな機能が文書化されている場所にたどり着きましたman 7 capabilities。そこで「モジュール」を検索すると、必要な機能と思われる次のものを見つけました。

CAP_SYS_MODULE カーネルモジュールのロードとアンロード

この機能がデフォルトで含まれていない理由は不明です。おそらく、OpenVPN の一般的な使用例ではこの機能は必要ないのでしょう。

この機能をパッケージの systemd 設定に追加する最小限の方法は、「ドロップイン ユニット」を使用することです。次のファイルを作成します。

/etc/systemd/system/[email protected]/add-module-loading.conf

このコンテンツでは:

[Service]
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_AUDIT_WRITE CAP_SYS_MODULE

これにより、既存の機能に加えてサービスが拡張されますCAP_SYS_MODULE

私も躊躇していましたsystemdが、気に入る点がたくさん見つかりました。このtimerシステムは、20 年以上前の cron システムに対する歓迎すべきアップデートです。

関連情報