When I scan the ports of an opensuse machine with nmap (e.g. nmap -sS remotehost) it reports most of the ports which are supposed to be closed as “filtered”. If I understand it correctly, this means that the system just drops all packages which come in on this port (the ominous “stealth mode”).
I didn’t find a way to change this behaviour with the firewall configuration tool. How can I configure the firewall to report these ports as closed instead?
Btw., before opening the firewall configuration tool from Yast, one must manually start the firewalld service, although it is set to enabled. Should this be considered a bug?
Relatively recently TW migrated from Susefirewall to firewalld. For my installation I had to stop and disable the susefirewall srevices and then start and configure firewalld.
Could you explain what “closed” means? Do not assume everyone knows nmap by heart.
Closed ports reject all packages sent to them. That means the sender is notified that noone accepts his packages on this port. If the port is filtered, the packages are dropped. This tells you nothing about if the port is closed or open (rsp. if a service is listening on the port). Some people prefer to filter ports so that potential attackers have to spend more time finding out which ports are actually open. I have no intentions starting a discussion about if this is a good idea or not. In my local network I just find it more convenient to get an instant open/closed reply from nmap (and not needing to use root for scans).
Note that this is not specific to nmap. nmap is just the tool used here to check what is the status of the ports.
For my installation I had to stop and disable the susefirewall srevices and then start and configure firewalld.
@doscott
Right, I had SuSEfirewall2 and SuSEfirewall2_init still enabled and running. firewalld was enabled, but didn’t start. Now that I disabled the SuSEfirewall2 services, firewalld starts automatically. So this problem is solved.
Well, “reject” is ambiguous here. If you mean iptables REJECT target, this is default action of firewalld as far as I can tell - it configures fall-back iptables target REJECT with “host prohibited”. The only exception are packets with invalid connection tracking state which are unconditionally dropped. So either nmap expects different ICMP type as indication of “closed” port, or you have modified configuration to default to DROP target. So you still need to know what “closed” means exactly for nmap or how nmap tests for it
Well, I don’t know what nmap is doing on a technical level, so I just answered with the prose version of what I picked up in the nmap man page and other places ;).
According to the iptables man page, REJECT defaults to icmp-port-unreachable (type 3, code 3). In my iptables config (on tumbleweed), REJECT is set to icmp-host-prohibited as you said. If this is the same as type 3, code 10, “host administratively prohibited” it is clear why nmap reports the port as filtered: quote from the nmap man page (under TCP SYN scan): “The port is also marked filtered if an ICMP unreachable error (type 3, code 1, 2, 3, 9, 10, or 13) is received”.
If this is correct, I think I’m starting to understand the problem (first step to solving it myself). Thanks for your help!
Ok, I got it. What I actually wanted to do is to create an iptables rule to reject incoming tcp connections with TCP RST. This is done the following way:
where position 7 in my case inserts the rule right before “REJECT all …] reject-with icmp-host-prohibited” in the INPUT chain. Thanks for pointing me in the right direction, arvidjaar!
In case anyone is interested: since we’re using firewalld on tumbleweed (and leap 15), we shouldn’t edit iptables directly. Unfortunately, firewalld does not let us modify the default target (see https://github.com/firewalld/firewalld/issues/252). I.e. the solution above is not feasible due to the lack of a clean way to make the rule permanent. Btw., the REJECT rule with “host-prohibited” on ports 80 and 443 is the reason why nmap host discovery (nmap -sn <iprange>) as non-root does not find running hosts.
It also hardcodes ICMP type used for %%REJECT%% without any way to override it.
the solution above is not feasible due to the lack of a clean way to make the rule permanent.
Well … you can add rules to any chain using firewalld.direct although priority handling may become rather hairy. You could also add rich rule with catch all source and suitable reject action to zone definition (see firewalld.zone and firewalld.richlanguage).
I haven’t looked at this in iptables (I usually set up something more robust for business class firewalls),
But I’d guess that the iptables solution should be pretty straight forward…
Re-configure the default rules only from REJECT to DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
i don’t visualize any other changes that need to be made and then you can continue to use firewalld or SuSEFW2 since typical rules allow and don’t deny connections.
AFAIK if you modify your rules manually using a text editor, the rules would be lost only with a clean re-install or possibly a distro upgrade (which could mean that testing is needed for TW which upgrades about every 2 weeks)