Firewalld blocks an unblocked port

I’m trying to get shellinabox running but always get a blank page. By enabling log output in both the program and firewalld I can see that the latter is blocking the program. But I don’t understand why.

Program has been started:

# shellinaboxd -u shellinabox -g shellinabox --disable-ssl -s:LOGIN --no-beep --pidfile=/var/run/shellinabox.pid --debug 2>/var/log/shellinabox.log

Program is listening:

# tail -f shellinabox.log
[server] Version 2.20 (revision 4f0ecc3)
[server] Command line: shellinaboxd -u shellinabox -g shellinabox --disable-ssl -s /:LOGIN --no-beep --pidfile=/var/run/shellinabox.pid --debug
[server] Listening on port 4200...
sudo netstat -tlpn | grep shellinabox
tcp        0      0 0.0.0.0:4200            0.0.0.0:*               LISTEN      103097/shellinaboxd

Port 4200 has been unblocked:

# firewall-cmd --add-port=4200/tcp
success
# firewall-cmd --reload
success

In desperation I even did:

# firewall-cmd --complete-reload
success

The default zone for the interface is public:

# firewall-cmd --get-default-zone
public
# firewall-cmd --list-interfaces
eth0

After enabling logging for firewall I can see that connections on port 4200 are being blocked:

# tail -f /var/log/firewall
2023-04-08T19:57:35.480663+02:00 leap kernel: [29373.031972][    C3] FINAL_REJECT: IN=eth0 OUT= MAC=00:0c:29:19:fa:3e:00:0c:29:bb:e7:71:08:00 SRC=192.168.10.37 DST=192.168.10.10 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=6980 DF PROTO=TCP SPT=51728 DPT=4200 WINDOW=8192 RES=0x00 SYN URGP=0
2023-04-08T19:57:47.491558+02:00 leap kernel: [29385.042666][    C3] FINAL_REJECT: IN=eth0 OUT= MAC=00:0c:29:19:fa:3e:00:0c:29:bb:e7:71:08:00 SRC=192.168.10.37 DST=192.168.10.10 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=6987 DF PROTO=TCP SPT=51730 DPT=4200 WINDOW=8192 RES=0x00 SYN URGP=0
2023-04-08T19:57:47.741906+02:00 leap kernel: [29385.292935][    C3] FINAL_REJECT: IN=eth0 OUT= MAC=00:0c:29:19:fa:3e:00:0c:29:bb:e7:71:08:00 SRC=192.168.10.37 DST=192.168.10.10 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=6989 DF PROTO=TCP SPT=51731 DPT=4200 WINDOW=8192 RES=0x00 SYN URGP=0
2023-04-08T19:57:50.491238+02:00 leap kernel: [29388.042300][    C3] FINAL_REJECT: IN=eth0 OUT= MAC=00:0c:29:19:fa:3e:00:0c:29:bb:e7:71:08:00 SRC=192.168.10.37 DST=192.168.10.10 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=6991 DF PROTO=TCP SPT=51730 DPT=4200 WINDOW=8192 RES=0x00 SYN URGP=0

What should I check now? Any suggestions are appreciated.

Also I don’t understand the output of these commands–I’d expect some rules:

# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

# sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

It was not.

It only changes run-time configuration.

And this throws away the result of the previous command. You need to use --permanent flag to store configuration changes permanently. Besides, the previous command adds this port to the default zone, and you may not be using the default zone.

There is no indication that eth0 is bound to the zone public. “Default zone” is the zone used

  • by fiewall-cmd when no explicit zone is given, and
  • for an interface when no other zone is otherwise requested

We know nothing about the configuration of the interface eth0 so we have no reason to assume it is bound to the default zone.

firewalld has switched to nft as default backend.

Thank you for immediately spotting the obvious, Arvid :pray:

I used that fw reload command as always in auto mode not considering that I just had set up a transient fw rule.

But in one point I do not agree with you. You wrote “There is no indication that eth0 is bound to the zone public. “Default zone” is the zone used. … We know nothing about the configuration of the interface eth0 so we have no reason to assume it is bound to the default zone.

But this clearly indicates that a) public is the default zone and b) eth0 is bound to the default zone which according to the first command’s output is public. Which can easily be verified by

# firewall-cmd --zone=public --query-interface=eth0
yes

“The “iptables-nft” command can be used to run the iptables equivalent commands while using the nftables API.”

Source: https://www.suse.com/support/kb/doc/?id=000020643

But I get the very same output for the commands as above:

# iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

# iptables-nft -L -n
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Run

nft list ruleset

Thank you again, Andrei. Happy Easter! I also found that command but consider the output much too long. Anyway.

Please allow a follow-up question: I was about to remove the IMO useless iptables package but if I did so, zypper would also remove the firewalld package :neutral_face:

$ sudo zypper rm iptables
Reading installed packages...
Resolving package dependencies...

The following 2 packages are going to be REMOVED:
  firewalld iptables

2 packages to remove.
$ sudo zypper install rpmorphan
$ rpmdep -depending iptables 2>/dev/null
iptables is needed by firewalld

Why does firewalld still depend on the iptables package when the backend has been replaced with nft?

This would be nice to understand.

firewalld still uses iptables for direct rules.

Ok. My understanding after reading through man firewalld.direct is that if there would be any direct rules in /etc/firewalld/direct.xml then those would actually be listed by iptables -L and/or firewall-cmd --direct --get-all-rules .

But usually there won’t be any direct rules and I still think the legacy tools are pretty much useless.