IPTables on AlmaLinx8

Hello,
I installed iptables on AlmaLinux8 and allowed port 5000/tcp
I can see rules when i issue iptables -L -n

Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 tcp dpt:5000

Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 tcp spt:5000

However nmap shows port is closed

Starting Nmap 6.40 ( http://nmap.org ) at 2023-09-13 09:39 +11
setup_target: failed to determine route to 5000 (0.0.19.136)
Nmap scan report for 103.72.90.137
Host is up (0.000039s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE
80/tcp open http
443/tcp open https
5000/tcp closed upnp
MAC Address: C4:37:72:98:D6:D1 (Unknown)

AlmaLinux 8 has three mutually exclusive services that set up firewall rules into the kernel:
firewalld.service, nftables.service, and iptables.service. The iptables.service is deprecated.

The kernel of AlmaLinux 8 has nf-tables subsystem that replaces most of the netfilter.
The user tool iptables is no longer the legacy iptables that did talk to netfilter, but a wrapper to nft that translates “iptables syntax” into “nftables syntax”. It may not be able to translate everything.

The point is that even though you seem to be able to set/read rules with iptables, you really should use nft. In order to see all rules, do:

nft list ruleset

If you are not using the default service, firewalld, then make sure that it is not and cannot run:

systemctl stop firewalld
systemctl disable firewalld
systemctl mask firewalld

The masking is important, because disabled but unmasked services can still be started.


Since you are not using the FirewallD, do use nftables.service (rather than iptables.service).
It is the “native” and equivalent. You just have to learn the new syntax.
(The nftables.service is recommended by Red Hat “for real use” – FirewallD is only for simple cases …)


Finally, do run:

ss -tlpn | grep 5000

Do you see a process that does listen to 5000/tcp? If no program does listen on the port, then it is “closed”. IIRC, nmap says “filtered” if firewall drops packets.

1 Like

I was using iptables, so i deleted it with command

dnf remove iptables

Now i can see other ports open

nmap localhost

Starting Nmap 7.70 ( https://nmap.org ) at 2023-09-14 08:33 +11
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000040s latency).
Other addresses for localhost (not scanned): ::1
Not shown: 991 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
443/tcp open https
465/tcp open smtps
587/tcp open submission
3306/tcp open mysql

When i run nmap for specific port 5000

nmap localhost 5000

Starting Nmap 7.70 ( https://nmap.org ) at 2023-09-14 08:33 +11
setup_target: failed to determine route to 5000 (0.0.19.136)

Also no output when i run

ss -tlpn | grep 5000

Read the man nmap on how to specify port. Your command tries to scan two hosts:
name: “localhost”, and IP address: 0.0.19.136 (because 19*256+136 == 5000).

Besides, if you run nmap on the host, whose firewall you are looking at, then even with the default FirewallD ruleset all ports can be open, because you scans would be picked up by rule:

iifname "lo" accept

In other words, if you want to know how others see you, you have to look from outside.


As I did suspect. You don’t have any program running that would be listen on port 5000.
When no program listens, the kernel sends the “closed”. If someone listens and replies, then you do get the “open”.


Do run the nft list ruleset now. What do you get?

This is the output now

nft list ruleset

table ip filter {
chain INPUT {
type filter hook input priority filter; policy drop;
iifname != “lo” meta l4proto tcp ip saddr 1.1.1.1 tcp dport 53 counter packets 0 bytes 0 accept
iifname != “lo” meta l4proto udp ip saddr 1.1.1.1 udp dport 53 counter packets 0 bytes 0 accept
iifname != “lo” meta l4proto tcp ip saddr 1.1.1.1 tcp sport 53 counter packets 0 bytes 0 accept
iifname != “lo” meta l4proto udp ip saddr 1.1.1.1 udp sport 53 counter packets 1080 bytes 190262 accept
iifname != “lo” counter packets 104420 bytes 76497615 jump LOCALINPUT
iifname “lo” counter packets 14724 bytes 7189059 accept
iifname != “lo” meta l4proto tcp counter packets 23444 bytes 30311813 jump INVALID
iifname != “lo” meta l4proto icmp icmp type echo-request limit rate 1/second counter packets 19598 bytes 732105 accept
iifname != “lo” meta l4proto icmp icmp type echo-request counter packets 1852 bytes 70581 jump LOGDROPIN
iifname != “lo” meta l4proto icmp counter packets 1 bytes 72 accept
iifname != “lo” ct state related,established counter packets 16846 bytes 31113450 accept
iifname != “lo” meta l4proto tcp ct state new tcp dport 80 counter packets 197 bytes 9491 accept
iifname != “lo” meta l4proto tcp ct state new tcp dport 443 counter packets 329 bytes 15200 accept
iifname != “lo” meta l4proto udp ct state new udp dport 80 counter packets 2 bytes 104 accept
iifname != “lo” meta l4proto udp ct state new udp dport 443 counter packets 2 bytes 1295 accept
iifname != “lo” counter packets 9121 bytes 535109 jump LOGDROPIN
}

Chain Forward

    > chain FORWARD {
            type filter hook forward priority filter; policy drop;
    }

Chain OUTPUT

   chain OUTPUT {
            type filter hook output priority filter; policy drop;
            oifname != "lo" meta l4proto tcp ip daddr 1.1.1.1 tcp dport 53 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ip daddr 1.1.1.1 udp dport 53 counter packets 1080 bytes 72413 accept
            oifname != "lo" meta l4proto tcp ip daddr 1.1.1.1 tcp sport 53 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ip daddr 1.1.1.1 udp sport 53 counter packets 0 bytes 0 accept
            oifname != "lo" counter packets 75303 bytes 8333342 jump LOCALOUTPUT
            oifname != "lo" meta l4proto tcp tcp dport 53 counter packets 553 bytes 32804 accept
            oifname != "lo" meta l4proto udp udp dport 53 counter packets 2041 bytes 141939 accept
            oifname != "lo" meta l4proto tcp tcp sport 53 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp udp sport 53 counter packets 0 bytes 0 accept
            oifname "lo" counter packets 14724 bytes 7189059 accept
            oifname != "lo" meta l4proto tcp counter packets 15865 bytes 2768111 jump INVALID
            oifname != "lo" meta l4proto icmp counter packets 19605 bytes 733720 accept
            oifname != "lo" ct state related,established counter packets 15447 bytes 2742552 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 20 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 21 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 22 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 25 counter packets 4 bytes 240 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 37 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 43 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 53 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 80 counter packets 166 bytes 9960 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 110 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 113 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 443 counter packets 94 bytes 5640 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 587 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 853 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 873 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 993 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 995 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 2086 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 2087 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 2089 counter packets 152 bytes 9120 accept
            oifname != "lo" meta l4proto tcp ct state new tcp dport 2703 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 20 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 21 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 53 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 113 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 123 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 853 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 873 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 6277 counter packets 0 bytes 0 accept
            oifname != "lo" meta l4proto udp ct state new udp dport 24441 counter packets 0 bytes 0 accept
            oifname != "lo" counter packets 0 bytes 0 jump LOGDROPOUT
    }

I checked nftables but status is also inactive

systemctl status nftables

● nftables.service - Netfilter Tables
Loaded: loaded (/usr/lib/systemd/system/nftables.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:nft(8)

If all services are disabled, then nothing loads the rules to kernel on boot.

With nftables.service you want to save your rules in /etc/nftables/ and
add appropriate include statement into /etc/sysconfig/nftables.conf.
Then the service will load your rules when/if it starts.


Note on forum syntax.
This is quoted (with > ):

nft list ruleset

table ip filter {
chain INPUT {
type filter hook input priority filter; policy drop;

This is in code block (with ``` ):

# nft list ruleset

table ip filter {
  chain INPUT {
    type filter hook input priority filter; policy drop;

Almost every rule in your set has iifname != "lo". None of them needs it, if you move the

iifname "lo" counter accept

to be first in chain. You can move it before all the “not lo” rules, because from lo and not from lo are two distinct sets.
Once you have the from lo rule as first, only packets that are not from lo get past it.
Therefore the other rules do not have to explicitly test for that condition.

You have jumps to chains that you don’t show.

On output you do have tcp dport 53 three times. I don’t think that any packet will reach the third. Less is more clear and efficient.


The FirewallD would set up something similar to:

	chain INPUT {
		type filter hook input priority filter; policy accept;
		ct state invalid counter drop
		ct state { established, related } accept
		iif "lo" accept
		iif != "lo" ip daddr 127.0.0.0/8 counter
		ip protocol icmp counter accept
		# here rules/chains that allow something in from outside
		counter reject with icmp host-prohibited
	}
  • Majority of packets are ESTABLISHED or RELATED. They are part of existing connections that we have already allowed. Therefore it is most efficient to allow them up front.
  • Same with localhost traffic. Note the iif, rather than iifname. The iif is more efficient, but really safe only with the “lo” interface – the kernel indices of other interfaces can change.
  • These rules are “polite”, they allow ICMP and tell clients when they reject connections.
  • The comment line is jumps to chains of “zones” in FirewallD.
  • The state { established, related } does use unnamed set. The nft has also named sets and maps
  • The output is accept by default and forward is reject…

With set and buitin aliases the:

iifname != “lo” meta l4proto tcp ct state new tcp dport 80 counter accept
iifname != “lo” meta l4proto tcp ct state new tcp dport 443 counter accept

could simplify to:

tcp dport { 80, 443 } ct state new counter accept

Or, considering these are well-known services:

tcp dport { http, https } ct state new counter accept