Repository: moby/moby (language: go)

Issue:
iptables (legacy) doesn't work with swarm published ports; iptables (nf_tables) is required
### Description

...that's `iptables` built with `--enable-nftables`.

I found this bug on [Lightwhale](https://lightwhale.asklandd.dk/), which is a custom Linux distro I'm building from scratch.  Now bare with me...!

This took some time to debug, because classic `docker run` and `docker compose` works, and so do most swarm features. But I specifically wanted to play with the [routing mesh](https://docs.docker.com/engine/swarm/ingress/) and that's when I discovered that I cannot connected from the host to a published port on the host (please see test case).

So I started comparing with a working, main stream Linux desktop.  I compared  `docker inspect this` and `than`.  Then I install the official [static binary](https://docs.docker.com/engine/install/binaries/) build of docker, and followed the [prerequisites](https://docs.docker.com/engine/install/binaries/#prerequisites) carefully, even ran the [check-config.sh](https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh) script, but it kept failing.  I finally found a difference in the output of `iptables-save` and eventually discovered that `iptables` isn't just `iptables`!

Apparently I needed to enable `--enable-nftables` flag when compiling `iptables`.


It would be helpful if...:
1. docker tested if the installed `iptables` that [it finds](https://github.com/moby/moby/blob/master/libnetwork/iptables/iptables.go#L111) is actually of the correct build. Maybe run `iptables --version` and expect  `"(nf_tables)"` as in e.g. `iptables v1.8.9 (nf_tables)`.
2. [check-config.sh](https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh) similarly tested for a working `iptables` command. 
3. `docker info` printed the path for `iptables` and output of `iptables --version` since it's obviously heavily depending on it, and for it to be in a supported version and build.
4. it was specifically stated in the docs, that `iptables (nf_tables)` is required, and not just "iptables version 1.4 or higher".  I already did [file a request](https://github.com/docker/docs/issues/18418) for that change.

You won't find any hints in the `docker version` and `docker info` below. But I've added two session logs of a failing and successful test.  It includes output of `iptables --version` and `iptables-save`. 

### Reproduce

sudo iptables --version  # (legacy) or (nf_tables)
docker swarm init --default-addr-pool 10.22.0.0/16
docker service create --publish published=8088,target=80 --name=www nginx:1.25.2-alpine
curl 127.0.0.1:8088  # Connection refused or HTML
sudo iptables-save --version
sudo iptables-save  # (legacy) or (nf_tables)


### Expected behavior

iptables v1.8.9 (nf_tables)

curl to output response from nginx.

### docker version

```bash
Client:
 Version:           23.0.5
 API version:       1.42
 Go version:        go1.19.10
 Git commit:        23.0.5
 Built:             unknown-buildtime
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          23.0.5
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.10
  Git commit:       buildroot
  Built:            
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        
 runc:
  Version:          1.1.7
  GitCommit:
```


### docker info

```bash
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  compose: Docker Compose (Docker Inc.)
    Version:  2.15.1
    Path:     /usr/lib/docker/cli-plugins/docker-compose

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 23.0.5
 Storage Driver: overlay2
  Backing Filesystem: tmpfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 
 runc version: 
 init version: N/A
 Security Options:
  seccomp
   Profile: builtin
 Kernel Version: 6.1.32
 Operating System: Lightwhale 2.0.4
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 1.946GiB
 Name: lightwhale
 ID: e5308f03-9b08-4362-801d-ba768c7bbf8c
 Docker Root Dir: /mnt/lightwhale-data/docker
 Debug Mode: true
  File Descriptors: 22
  Goroutines: 39
  System Time: 2023-10-13T00:44:46.498736037+02:00
  EventsListeners: 0
 Registry: https://index.docker.io/v1/
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
```


### Additional Info

Notice the difference in `iptables v1.8.9 (legacy)` and `iptables v1.8.9 (nf_tables)`, and also how the `iptables-save` output is reversed but also has other subtle, critical differences;

[test-fail.log](https://github.com/moby/moby/files/12887801/test-fail.log)
[test-success.log](https://github.com/moby/moby/files/12887802/test-success.log)



Discussion / hints:
Swarm and overlay networks don't have strong opinions about the flavor of iptables used, so I suspect this is a partial misdiagnosis. Instead what seems likely to me is that you ended up in a split-brain situation, where some rules were defined on the system using the nftables (iptables-nft or nft), and dockerd was using iptables-legacy.

This would be similar to a Kubernetes "bug"/footgun that has been known for some time: https://github.com/kubernetes/kubernetes/issues/112477

In general I would say dockerd works better with iptables-legacy (see https://github.com/moby/moby/issues/39590); there is significantly less overhead in each call to the binary (as each separate call is essentially an iptables-save -> modify -> iptables-restore operation).

We're trying to work towards native nftables support (https://github.com/moby/moby/issues/26824) or even a more aggressive evolution/replacement of our networking stack (https://github.com/moby/moby/issues/39338); however that's not the core issue here. I'm reasonably sure that the issue is a "split brain" netfilter layer, and that the solution works because it resolves the "split brain" and not because all other things being equal, iptables-nft is suddenly required for the very simple rules we generate.
![CleanShot 2023-10-13 at 13 09 44](https://github.com/moby/moby/assets/1049222/2a7b8dec-455d-4a36-af5f-de9627fdf054)

The `iptables-save` output is identical, though it's interesting that you don't have any packet counters for iptables-nft. We can see something odd is happening in any case, as the `FORWARD` chain packet counters are also zero.
@neersighted As requested, the output of `sudo nft -s list ruleset` while iptables-legacy is the default implementation.

TL; DR: It's empty.

```
lightwhale login: op
Password: 



op@lightwhale:~$ ls -l /usr/sbin/{x,ip*}tables*
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/ip6tables -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            14 Oct 14 10:57 /usr/sbin/ip6tables-apply -> iptables-apply
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/ip6tables-legacy -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/ip6tables-legacy-restore -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/ip6tables-legacy-save -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/ip6tables-restore -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/ip6tables-save -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/iptables -> xtables-legacy-multi
-rwxr-xr-x    1 root     root          7037 Oct 14 10:57 /usr/sbin/iptables-apply
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/iptables-legacy -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/iptables-legacy-restore -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/iptables-legacy-save -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/iptables-restore -> xtables-legacy-multi
lrwxrwxrwx    1 root     root            20 Oct 14 10:57 /usr/sbin/iptables-save -> xtables-legacy-multi
-rwxr-xr-x    1 root     root         96064 Oct 14 10:59 /usr/sbin/xtables-legacy-multi



op@lightwhale:~$ iptables -V
iptables v1.8.9 (legacy)



op@lightwhale:~$ iptables-save -V
iptables-save v1.8.9 (legacy)



op@lightwhale:~$ iptables-restore -V
iptables-restore v1.8.9 (legacy)



op@lightwhale:~$ nft -V
nftables v1.0.7 (Old Doc Yak)
  cli:		readline
  json:		no
  minigmp:	yes
  libxtables:	no



op@lightwhale:~$ sudo iptables-save
Password: 
# Generated by iptables-save v1.8.9 on Sat Oct 14 11:12:09 2023
*nat
:PREROUTING ACCEPT [1:576]
:INPUT ACCEPT [1:576]
:OUTPUT ACCEPT [14:872]
:POSTROUTING ACCEPT [14:872]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
COMMIT
# Completed on Sat Oct 14 11:12:09 2023
# Generated by iptables-save v1.8.9 on Sat Oct 14 11:12:09 2023
*filter
:INPUT ACCEPT [47:4913]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [45:3228]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
COMMIT
# Completed on Sat Oct 14 11:12:09 2023



op@lightwhale:~$ sudo iptables -t filter -L -v -n
Chain INPUT (policy ACCEPT 49 packets, 5065 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-USER  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 DOCKER-ISOLATION-STAGE-1  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 47 packets, 3380 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       0    --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           



op@lightwhale:~$ sudo nft -s list ruleset



op@lightwhale:~$ docker swarm init --default-addr-pool 10.22.0.0/16
Swarm initialized: current node (nj292carinx9dm5wz1qwml5p8) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-3jkksapgap2nrjkk4ipzhdsbiyok3y2p17kcvcnknic3s2l3n5-64wmkcg556xn4f04go1tufzdb 10.0.2.15:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

op@lightwhale:~$ docker service create --publish published=8088,target=80 --name=www nginx:1.25.2-alpine
mrnuvt7302rudn06r8gv0g3is
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 



op@lightwhale:~$ docker service ps www
ID             NAME      IMAGE                 NODE         DESIRED STATE   CURRENT STATE           ERROR     PORTS
p28oe1g4jx2j   www.1     nginx:1.25.2-alpine   lightwhale   Running         Running 8 seconds ago             



op@lightwhale:~$ docker service logs www
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
www.1.p28oe1g4jx2j@lightwhale    | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
www.1.p28oe1g4jx2j@lightwhale    | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
www.1.p28oe1g4jx2j@lightwhale    | /docker-entrypoint.sh: Configuration complete; ready for start up
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: using the "epoll" event method
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: nginx/1.25.2
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: built by gcc 12.2.1 20220924 (Alpine 12.2.1_git20220924-r10) 
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: OS: Linux 6.4.14
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:4096
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: start worker processes
www.1.p28oe1g4jx2j@lightwhale    | 2023/10/14 09:13:06 [notice] 1#1: start worker process 30



op@lightwhale:~$ docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS     NAMES
47eb412b1560   nginx:1.25.2-alpine   "/docker-entrypoint.…"   35 seconds ago   Up 33 seconds   80/tcp    www.1.p28oe1g4jx2jp360f0cml4t9d



op@lightwhale:~$ sudo iptables-save
# Generated by iptables-save v1.8.9 on Sat Oct 14 11:13:53 2023
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DOCKER - [0:0]
:DOCKER-INGRESS - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER-INGRESS
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -m addrtype --dst-type LOCAL -j DOCKER-INGRESS
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -o docker_gwbridge -m addrtype --src-type LOCAL -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o docker_gwbridge -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER -i docker_gwbridge -j RETURN
-A DOCKER -i docker0 -j RETURN
-A DOCKER-INGRESS -p tcp -m tcp --dport 8088 -j DNAT --to-destination 172.18.0.2:8088
-A DOCKER-INGRESS -j RETURN
COMMIT
# Completed on Sat Oct 14 11:13:53 2023
# Generated by iptables-save v1.8.9 on Sat Oct 14 11:13:53 2023
*filter
:INPUT ACCEPT [16:1216]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [16:1216]
:DOCKER - [0:0]
:DOCKER-INGRESS - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-INGRESS
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker_gwbridge -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker_gwbridge -j DOCKER
-A FORWARD -i docker_gwbridge ! -o docker_gwbridge -j ACCEPT
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -i docker_gwbridge -o docker_gwbridge -j DROP
-A DOCKER-INGRESS -p tcp -m tcp --dport 8088 -j ACCEPT
-A DOCKER-INGRESS -p tcp -m state --state RELATED,ESTABLISHED -m tcp --sport 8088 -j ACCEPT
-A DOCKER-INGRESS -j RETURN
-A DOCKER-ISOLATION-STAGE-1 -i docker_gwbridge ! -o docker_gwbridge -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker_gwbridge -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
COMMIT
# Completed on Sat Oct 14 11:13:53 2023



op@lightwhale:~$ sudo iptables -t filter -L -v -n
Chain INPUT (policy ACCEPT 16 packets, 1216 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-USER  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 DOCKER-INGRESS  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    1   330 DOCKER-ISOLATION-STAGE-1  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  *      docker_gwbridge  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    1   330 DOCKER     0    --  *      docker_gwbridge  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  docker_gwbridge !docker_gwbridge  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     0    --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
    1   330 DROP       0    --  docker_gwbridge docker_gwbridge  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 16 packets, 1216 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-INGRESS (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8088
    0     0 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED tcp spt:8088
    0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  0    --  docker_gwbridge !docker_gwbridge  0.0.0.0/0            0.0.0.0/0           
    0     0 DOCKER-ISOLATION-STAGE-2  0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    1   330 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       0    --  *      docker_gwbridge  0.0.0.0/0            0.0.0.0/0           
    0     0 DROP       0    --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    1   330 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0           



op@lightwhale:~$ sudo nft -s list ruleset 



op@lightwhale:~$ curl 127.0.0.1:8088
curl: (7) Failed to connect to 127.0.0.1 port 8088 after 0 ms: Error
```

Fix patch:
diff --git a/contrib/check-config.sh b/contrib/check-config.sh
index 175370ea7b86a..7f57c7bb3973b 100755
--- a/contrib/check-config.sh
+++ b/contrib/check-config.sh
@@ -218,7 +218,7 @@ check_flags \
 	CGROUPS CGROUP_CPUACCT CGROUP_DEVICE CGROUP_FREEZER CGROUP_SCHED CPUSETS MEMCG \
 	KEYS \
 	VETH BRIDGE BRIDGE_NETFILTER \
-	IP_NF_FILTER IP_NF_TARGET_MASQUERADE \
+	IP_NF_FILTER IP_NF_MANGLE IP_NF_TARGET_MASQUERADE \
 	NETFILTER_XT_MATCH_ADDRTYPE \
 	NETFILTER_XT_MATCH_CONNTRACK \
 	NETFILTER_XT_MATCH_IPVS \


Test patch: