Blocking NMAP scanning

Hello everyone! I’ve been going through self hosting as much as I can, experimenting and testing configurations. While doing so I remembered using NMAP to scan my network so I thought: “what if I find a way to block that from happen to my server and prevent automatic scans from detecting open ports?”. I tried to dig around on the internet but there are conflicting informations about it and, in general, I couldn’t find any firewall rules thorougly explained.
Has anyone ever done that to mitigate unwated knocks on open ports?


Don’t open that port in the first place?

The problem is that you cannot distinguish wanted from unwanted traffic. If you set the firewall rule not to respond to a request on that port (so it appears not to be there) then all traffic will be affected. Allowing only known clients (addresses!) requires a filter in the firewall config.


I can’t else I cannot connect to the service I want to. VPN is out of the question unfortunately.

Sure, but I’ve seen online people throwing around IP tables rules that apparently can distinguish between NMAP scans and regular traffic.
To block unwanted traffic I’m already using fail2ban with a very aggresive policy.

Deny Any

Allow inbound only the ports you need everyone on the planet seeing.

The point is that I’d like my server to appear without open ports to an NMAP scan. Deny connections to all ports don’t make sense, in my opinion since I don’t have 65K ports open on my router. Maybe I’m missing something.

There’s nothing that distinguishes an NMAP scan from “Not an NMAP scan, totally legitimate traffic, please let me through”.


These are my findings BEFORE writing this post and I can’t understand a damn thing about it. Looks like IT IS possible, but I’d like to know if these methods work or make sense, if anyone has ever used them.

If they try to knock on ports too quickly, the script will automagically block the attacker’s IP address in the iptable.

-T paranoid


I fingered out, at least a solid attempt, at at least detecting a scan.

Really neat git you linked, go figure there should be a way to script similar detection and then proactively block similar to fail2ban.



This would be reactionary, no?
Seems like it would be trivial to detect prior network scans, especially if you’re rolling Splunk, after-the-fact by seeing if a host has hit x ports over an unbounded period of time. Stopping a Paranoid/Sneaky or some custom >20s delay map isn’t going to be picked up easily (if at all) by an IDS/IPS in real-time though.

You can do it with something like snort or suricata. An IDS/IPS will look for patterns rather than just individual packets so it can block an IP performing a port scan before they attempt to do anything else.

1 Like

Not really. There’s a good write-up of this on the Nmap docs here.

The simplest (if slow) solution would be to send one probe every 20.1 seconds. […] You could speed this up by an order of magnitude by sending 14 packets really fast, waiting 20 seconds for the window to expire, then repeating with another 14 probes.

True but it’s going to stop most of the normal noise. My mail server used to get constant log in attempts with standard usernames and brute force attempts but since using snort and changing some other things it’s dropped to zero.


I’m not sure how to answer, I just posted a little project to detect, I’m not trying to say I’ve solved “the” problem. Having logs and being able to create a picture after the fact is still a highly sought after capability so I like to keep learning on this front.

@Dexter_Kane I run snort on pfSense, what tips do you have on the settings your are talking about? I just have it setup to block any IP that triggers an alert from the assorted rules I have enabled. Is there a rule set that is not definition based but port, src_ip and timing based?

I think I’m just using ET SCAN and the snort community rules for detecting port scans. It seems to work okay.

1 Like

I didn’t even have that rule set enabled. Enabled it-



1 Like

These 5 lines are the meat of that github shell script, the rest is random fluff I wouldn’t bother with, and would only look at these five lines to adapt/incorporate into my firewall rulesets:

IPSET1='port_scanners hash:ip family inet hashsize 32768 maxelem 65536 timeout 600'
IPSET2='scanned_ports hash:ip,port family inet hashsize 32768 maxelem 65536 timeout 60'
IPTABLE1='INPUT -m state --state INVALID -j DROP'
IPTABLE2='INPUT -m state --state NEW -m set ! --match-set scanned_ports src,dst -m hashlimit --hashlimit-above 1/hour --hashlimit-burst 5 --hashlimit-mode srcip --hashlimit-name portscan --hashlimit-htable-expire 10000 -j SET --add-set port_scanners src --exist'
IPTABLE3='INPUT -m state --state NEW -m set --match-set port_scanners src -j DROP'
IPTABLE4='INPUT -m state --state NEW -j SET --add-set scanned_ports src,dst'

IPTABLE2 above is interesting … and weird in mixing ipsets and hashlimit.

It assumes any incoming connection that reaches the rule must be a result of a port scan, probably because all legitimate traffic has already been accepted. If there’s more than 1 scanned missed port per hour from a source ip (the hashlimit matcher), the source ip is added to a cool down penalty box - the “port_scanners” ipset.

The ! --match-set scanned_ports src,dst runs before hashlimit matcher , if there’s already an entry in scanned_ports the last 60s, hashlimit doesn’t run at all. So it’s more like first port miss is allowed by ipset and hashlimit and gets you an entry (could be dropped later), second port miss gets dropped in a subsequent rule. Third and subsequent port miss gets dropped by scanned_ports ipset - presumably a performance optimization.

btw, hashlimit is kind of nice if you want to keep running ssh on port 22 - especially since ssh can reuse connections. It’s much simpler than log parsing with fail2ban.


@risk Thanks a lot for the explaination, I really appreciate it. That’s what I was looking for more than just a turn key solution. I’ve seen those lines repeat in some posts regarding how to block NMAP scans but I wasn’t sure about them.

@Dexter_Kane I know I can count on you answering when it comes to network security. Thanks for suggesting Snort or Suricata! I looked at Suricata, but I didn’t find anything regarding automatic creation of rules for iptables when suspicious traffic is detected.

@Token That’s really interesting! You creted rules to catch spoofed local IP addresses, right? Also if you feel like this thread is helpful go ahead and ask everything you want to. I’d like the conversation to get more in depth and more detailed.

P.S. I’m resorting to this also because I don’t know how to make fail2ban work with Docker containers (ban IPs that try to connect to my Docker containers). And if I Google the topic I only find how to install fail2ban on Docker, which is useless to me.

Blocking “nmap” isn’t a good idea. The professional bad guys don’t use nmap, but custom written port-scanning solutions.

If you want a basic port-scan blocker, you can set-up a listening process on a common port you aren’t using for anything. When anyone connects to that port, block their IP for an hour. The rest of their scan won’t see anything else open.

Often, port scanning is done in a distributed fashion, each IP address will only make one connection to one port on your server. You can try tracking down idiosyncrasies of each botnet’s distributed port scanners and try to block them, but that would be a real waste of time.

One option is to move your services to random, high numbered ports which don’t run any common services. Few people are dedicated enough to look for and find those. What’s more it could be just one service, like a VPN or SSH, which allows you to access all the real services once you authenticate.

Another option I don’t recommend but it sounds like you might be interested in is:


From what I’ve been told the iptables rules that I linked are not specific to NMAP but to scanning tools in general. If someone is trying to see what ports are open they’re gonna knock more than once with one IP per port so they’re gonna get blocked. This is my understanding of the matter.

I’m already not using standard ports for any of the services I’m self hosting, basic security. But they’re not high numbered. VPN and port knocking is out of the question since port knocking is not supported and I’m gonna have guests on it (VPN might be too cumbersome).
Isn’t SSH tunneling less secure than just exposing a port for each service? I don’t have the SSH port open and it’s not on 22.