iptables で [unsupported revision] が出る

問題

kube-proxy が設定したルールを iptables コマンドで表示すると、[unsupported revision] になる。

]# iptables -nL -t nat
Chain KUBE-SEP-AAJZQ5YHVGUCPI77 (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  10.200.192.87        0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp DNAT [unsupported revision]

環境

Ubuntu 18.04 LTS。

]# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

iptables は v1.6.1。

]# iptables --version
iptables v1.6.1

解決方法

iptables 1.8.0 以上にする。

]# wget https://netfilter.org/projects/iptables/files/iptables-1.8.0.tar.bz2
]# tar -jxvf iptables-1.8.0.tar.bz2
]# cd iptables-1.8.0/
]# apt-get install libnftnl-dev
]# ./configure
]# make
]# make install

すると次のように [unsupported revision] が解消される。自分でビルドするのか、とかディストリビューションが提供するパッケージじゃないしな、とか考えることはあるが、今回はお勉強が目的のためこれで良しとする。

Chain KUBE-SEP-AAJZQ5YHVGUCPI77 (1 references)
target     prot opt source               destination
KUBE-MARK-MASQ  all  --  10.200.192.87        0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp to:10.200.192.87:53

なんで?

どのバージョンで表示がまともになるかを人力で二分探索していくと、v1.6.2 と v1.8.0 が境目だった。

git のログを辿ると、次のパッチで修正されたっぽい。revision の扱いによるバグらしい。表示上の問題だけのよう。

]# git log v1.6.2..v1.8.0 -p iptables/iptables.c
...
commit 12a52ff9cc9944345204d3e429dd4414448fbcd2
Author: Serhey Popovych <serhe.popovych@gmail.com>
Date:   Wed Mar 7 11:10:43 2018 +0200

    xtables: Fix rules print/save after iptables update

    Updating iptables from 1.4.x to 1.6.x brokes rules print/save output
    and causes rules load after reboot to fail. Here is example from
    iptables-save(8) output after update:

      -A CHAIN1 -m set [unsupported revision] -j DROP
      -A CHAIN1 -m set [unsupported revision] -j DROP

    Similar output could be obtained via iptables -L CHAIN1. While issue
    reproduced with xt_set match it is not specific to any match or
    target module: it is related on how xtables handles revisions.

    In this particular case we have following situation:

      1) Kernel supports revisions from 1 to 4.

      2) Rules configured with iptables 1.4.x supporting only
         revisions from 1 to 3. Choosen highest possible revision 3.

      3) Rules printed/saved with iptables 1.6.x supporting revisions
         from 1 to 4.

      4) Xtables registers matches/targets with highest supported
         revision by the kernel. This is 4 in our case after update to
         iptables 1.6.x.

      5) When printing/saving kernel submits match/target with revision
         it is configured (3), while iptables thinks that rules configured
         with highest supported (4). That's causes revision mismatch in
         during print and "[unsupported revision]" output.

    To fix this issue we now store all supported by kernel and xtables
    revisions in xt_matches/xt_targets list sorted in descending order.

    Introduce helper routines to find match/target with given revision
    and use them to find right revision to print submitted by kernel
    entry.