Skip to content

Instantly share code, notes, and snippets.

@zoredache
Last active September 9, 2023 05:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoredache/08f571b9712ac8501a38649e6fcaae3d to your computer and use it in GitHub Desktop.
Save zoredache/08f571b9712ac8501a38649e6fcaae3d to your computer and use it in GitHub Desktop.
ip6tables-legacy check bug

From what I can tell the -C option ip6tables-legacy has broken between v1.8.7 and v1.8.9.

Using docker to use different builds and versions of ip6tables-legacy. Container is run against the host network and privileged. For each I show the version, use ip6tables-legacy-save to show that a specific rule exists and use the -C to check the rule that does exist, and for a rule that doesn't exist.

docker run --rm -it --privileged --net host debian:bookworm-slim /bin/sh

# # iptables installed (apt-get update && apt-get -y install iptables) ...
# ip6tables-legacy --version
ip6tables v1.8.9 (legacy)
# ip6tables-legacy-save | grep DNAT
-A DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443
# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443 ; echo $?
0
# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 80 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:80 ; echo $?
0

docker run --rm -it --privileged --net host debian:bullseye-slim /bin/sh

# # iptables installed (apt-get update && apt-get -y install iptables) ...
# ip6tables-legacy --version
ip6tables v1.8.7 (legacy)
# ip6tables-legacy-save | grep DNAT
-A DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443
# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443 ; echo $?
0
# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 80 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:80 ; echo $?
ip6tables: No chain/target/match by that name.
1

docker run --rm -it --privileged --net host archlinux:base /bin/sh

sh-5.1# ip6tables-legacy --version
ip6tables v1.8.9 (legacy)
sh-5.1# ip6tables-legacy-save | grep DNAT
-A DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443
sh-5.1# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443 ; echo $?
0
sh-5.1# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 80 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:80 ; echo $?
0

docker run --rm -it --privileged --net host archlinux:base-20211226.0.42348 /bin/sh

sh-5.1# ip6tables-legacy --version
ip6tables v1.8.7 (legacy)
sh-5.1# ip6tables-legacy-save | grep DNAT
-A DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443
sh-5.1# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 443 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:443 ; echo $?
0
sh-5.1# ip6tables-legacy -t nat -C DOCKER -p tcp -m tcp --dport 80 -j DNAT --to-destination [fd6c:d0ed:2749:2114::1:2]:80 ; echo $?
ip6tables: No chain/target/match by that name.
1

Start a container to build iptables from source

docker run --rm -it -w /srv/build \
    -v /srv/build/:/srv/build \
    -v /usr/local:/usr/local \
    debian:bookworm

In the container build iptabes

sed -i 's/^Types: deb$/Types: deb deb-src/g' /etc/apt/sources.list.d/debian.sources
apt-get update
</dev/null apt-get install --yes git build-essential debhelper
</dev/null apt-get build-dep --yes iptables

# rm -r git.netfilter.org_iptables
git clone git://git.netfilter.org/iptables git.netfilter.org_iptables
cd git.netfilter.org_iptables
git checkout v1.8.7 -b v1.8.7
git clean -f
export CFLAGS='-static'
export LDFLAGS='-static -dl'
./autogen.sh
./configure --disable-libipq --enable-devel --disable-shared
make
make install

Back on the host add an 'alternative' and set it active

update-alternatives \
  --install /usr/sbin/iptables iptables /usr/local/sbin/iptables-legacy 30 \
  --slave /usr/sbin/iptables-restore iptables-restore /usr/local/sbin/iptables-legacy-restore \
  --slave /usr/sbin/iptables-save iptables-save /usr/local/sbin/iptables-legacy-save
update-alternatives \
  --install /usr/sbin/ip6tables ip6tables /usr/local/sbin/ip6tables-legacy 30 \
  --slave /usr/sbin/ip6tables-restore ip6tables-restore /usr/local/sbin/ip6tables-legacy-restore \
  --slave /usr/sbin/ip6tables-save ip6tables-save /usr/local/sbin/ip6tables-legacy-save

update-alternatives --set iptables /usr/local/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/local/sbin/ip6tables-legacy

After doing the above, was able to restart the docker.service and all my container got their proper rules needed for published ports to work.

@zoredache
Copy link
Author

Apparently this bug has already been discovered upstream, and fixed in the master branch, but hasn't made it to a release.

https://git.netfilter.org/iptables/commit/?id=78850e7dba64a949c440dbdbe557f59409c6db48

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment