Raspbianをbuster化したら、iptablesでちょっとだけハマる

ちょっとしたお仕事用に、Paspberry Pi3 をルータ代わりに使っていたりしてるんですけど、stretch ベースのものにアップデート重ねて使い続けていたのを、最近になって buster ベースのイメージに入れ直し。
そんなこともあって、環境作り直しの一環で iptabes の設定をやり直そうとしていたら、

pi@blackbox:~ $ sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j MASQUARADE
iptables/1.8.2 Failed to initialize nft: Protocol not supported

上のような、エラーメセージが出て、設定ができない。

調べてみたところ、 Debian buster から、 iptables から nftables への置き換えがあったことが影響していたらしい…。

NOTE: iptables is being replaced by nftables starting with Debian Buster

[From iptables - Debian Wiki]

置き換えられたと言っても、iptables パッケージ自体がなくなったわけではないので、素の Debian のほうでは、特に iptables 絡みでのトラブルがなかったので気づいていなかった(sid とか stretch → buster にバージョンアップしたとかだと、 nftables パッケージが依存関係の解決のために自動的にインストールされてた)のですよ。

update-alternatives コマンド使って、旧来の iptables と nftables 対応のもののどちらにするのかを選択する事ができるので、そこで旧来の iptables を使うようにしてもいいのですが、いずれ iptables パッケージ自体が廃止されることなるのでしょうから、 nftables を有効にしつつ、 iptables コマンドで設定する、という方式で行くことにします。
ちなみに、 Raspbian buster では、以下のような設定がデフォルトのようです。

pi@blackbox:~ $ sudo update-alternatives --display iptables
iptables - 自動モード
最適なリンクのバージョンは '/usr/sbin/iptables-nft' です
リンクは現在 /usr/sbin/iptables-nft を指しています
リンク iptables は /usr/sbin/iptables です
スレーブ iptables-restore は /usr/sbin/iptables-restore です
スレーブ iptables-save は /usr/sbin/iptables-save です
/usr/sbin/iptables-legacy - 優先度 10
スレーブ iptables-restore: /usr/sbin/iptables-legacy-restore
スレーブ iptables-save: /usr/sbin/iptables-legacy-save
/usr/sbin/iptables-nft - 優先度 20
スレーブ iptables-restore: /usr/sbin/iptables-nft-restore
スレーブ iptables-save: /usr/sbin/iptables-nft-save

実際のコマンドがどうなっているのか調べてみると、 iptables コマンドを実行すると最終的には xtables-nft-multi が実行されるように設定されていました。

pi@blackbox:~ $ sudo ls -l `which iptables`
lrwxrwxrwx 1 root root 26 7月 10 09:06 /usr/sbin/iptables -> /etc/alternatives/iptables
pi@blackbox:~ $ ls -l /etc/alternatives/iptables
lrwxrwxrwx 1 root root 22 7月 10 09:06 /etc/alternatives/iptables -> /usr/sbin/iptables-nft
pi@blackbox:~ $ ls -l /usr/sbin/iptables-nft
lrwxrwxrwx 1 root root 17 3月 1 21:28 /usr/sbin/iptables-nft -> xtables-nft-multi

で、 Raspbian の場合、"with desktop and recommended software" のイメージを使っても nftables パッケージがインストールされていなかったので、これを改めてインストール。

>pi@blackbox:~ $ sudo aptitude install nftables
以下の新規パッケージがインストールされます:
libnftables0{a} nftables
更新: 0 個、新規インストール: 2 個、削除: 0 個、保留: 0 個。
アーカイブの 219 kB を取得する必要があります。展開後に 674 kB のディスク領域が新たに消費されます。
先に進みますか? [Y/n/?] y
取得: 1 http://ftp.tsukuba.wide.ad.jp/Linux/raspbian/raspbian buster/main armhf libnftables0 armhf 0.9.0-2 [174 kB]
取得: 2 http://ftp.tsukuba.wide.ad.jp/Linux/raspbian/raspbian buster/main armhf nftables armhf 0.9.0-2 [44.8 kB]
219 kB を 2秒 秒で取得しました (106 kB/s)
以前に未選択のパッケージ libnftables0:armhf を選択しています。
(データベースを読み込んでいます ... 現在 166847 個のファイルとディレクトリがインストールされています。)
.../libnftables0_0.9.0-2_armhf.deb を展開する準備をしています ...
libnftables0:armhf (0.9.0-2) を展開しています...
以前に未選択のパッケージ nftables を選択しています。
.../nftables_0.9.0-2_armhf.deb を展開する準備をしています ...
nftables (0.9.0-2) を展開しています...
libnftables0:armhf (0.9.0-2) を設定しています ...
nftables (0.9.0-2) を設定しています ...
man-db (2.8.5-2) のトリガを処理しています ...
libc-bin (2.28-10+rpi1) のトリガを処理しています ...

nftables を Raspbian 起動時に有効にするために、systemd を以下のように設定。

pi@blackbox:~ $ sudo systemctl mask nftables.service
Created symlink /etc/systemd/system/nftables.service → /dev/null.

これで、一度 Raspbian を再起動することで、 iptables コマンドが正しく動作するようになるので、いつものように iptables コマンドで設定をすれば、OK。

実際に設定する前に、iptables の状態を確認すると、全く設定されていないので、ルールが何もない状態。

pi@blackbox:~ $ sudo iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

この状態のときの nftables は、以下のような状態で、こちらもなんのルールも設定されてない。

pi@blackbox:~ $ sudo nft list table ip nat
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
}

chain INPUT {
type nat hook input priority 100; policy accept;
}

chain POSTROUTING {

type nat hook postrouting priority 100; policy accept;
}

chain OUTPUT {
type nat hook output priority -100; policy accept;
}
}

ここで、 iptables コマンドを使ってルール(今回は、 IP マスカレード)を設定したあとに

pi@blackbox:~ $ sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j MASQUERADE
pi@blackbox:~ $ sudo iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.16.0.0/16 0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

nftables の状態を確認すると、 iptables で設定した内容が自動的に変換されて、下のようにルールが追加されているのがわかります。( ”chain POSTROUTING" の部分。)

pi@blackbox:~ $ sudo nft list table ip nat
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
}

chain INPUT {
type nat hook input priority 100; policy accept;
}

chain POSTROUTING {
type nat hook postrouting priority 100; policy accept;
ip saddr 172.16.0.0/16 counter packets 0 bytes 0 masquerade
}

chain OUTPUT {
type nat hook output priority -100; policy accept;
}
}

あとは、 iptables-persistent パッケージをインストールして、iptables のルールを保存しておけば

pi@blackbox:~ $ sudo netfilter-persistent save
run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables save
# Warning: iptables-legacy tables present, use iptables-legacy-save to see them
run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables save
# Warning: ip6tables-legacy tables present, use ip6tables-legacy-save to see them

Raspberry を再起動しても再起動前と同じ設定になる、と…。

おそらく現状は移行期間ということで、iptables でのルールで設定すれば、細かいことを気にしなくても自動的に nftables の設定に変換されるようになっているようです。(他に Debian で動いているサーバで 直接 nftables をいじってないのに、 iptables で設定したルールが変換されて適用されてことから考えても…。)
そのうち nftables のルールで設定しないといけない時期が来るんだろうな〜。

トラックバック(0)

コメントする