Is it possible to prevent nmap from observing my machine entirely? After dropping all incoming connections with iptables port scans return as "filtered". It'd prefer if nmap couldn't see what ports existed at all. Is this possible?

The below solutions don't seem to work:




If it's not possible to keep nmap from seeing my device, would it be possible to rate-limit so that nmap takes a REALLY long time to fully scan my IP?

  • What OS are you using? The first link you provided should work if your OS is actually using iptables. If it's a RHEL 7.x derivative, then it would need to be edited to use firewalld or iptables would need enabling and firewalld disabling Feb 15 '17 at 12:46
  • 1
    What do you think 'filtered' means? Add --reason to see why, and I bet they all say "no response." You can't get more silent than no response. Feb 15 '17 at 13:52
  • @bonsaiviking, my goal (for example) is to keep nmap from learning I have SSH configured on port 43245. By dropping all INPUT, an attacker can still identify an SSH server on my machine. I'm trying to prevent that identification from happening. Feb 15 '17 at 14:35
  • @RobotJohnny, I'm using Ubuntu 16 :) Feb 15 '17 at 14:36
  • You seem to have a fundamental misunderstanding of TCP. If a host with a given address responds in any way to any remote request, the requester knows that a host at that address exists. If the host exists, that host will have a port 22, will have a port 43245 -- will have all valid TCP ports. If no service is listening on a port, TCP will, by design, send a rejection response. You can configure a firewall to suppress that response, but again, if any other service on any other port responds, the requester knows the host exists. Feb 15 '17 at 16:21

Simple rate limit is not enough because nmap increases scan delay when it hits rate limit. Here is what you can do best with iptables.

First create ipset lists

ipset create port_scanners hash:ip family inet hashsize 32768 maxelem 65536 timeout 600
ipset create scanned_ports hash:ip,port family inet hashsize 32768 maxelem 65536 timeout 60

And iptables rules

iptables -A INPUT -m state --state INVALID -j DROP
iptables -A 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
iptables -A INPUT -m state --state NEW -m set --match-set port_scanners src -j DROP
iptables -A INPUT -m state --state NEW -j SET --add-set scanned_ports src,dst

How this works:

Here we store scanned ports in scanned_ports set and we only count newly scanned ports on our hashlimit rule. If a scanner send packets to 5 different port(see --hashlimit-burst 5) that means it is a probably scanner so we will add it to port_scanners set.

Timeout of port_scanners is the block time of scanners(10 minutes in that example). It will start counting from beginning (see --exist) till attacker stop scan for 10 seconds (see --hashlimit-htable-expire 10000)

You can set these parameters to most proper values for you.

Be aware of that someone can make any IP blocked by just make scan as spoofing. I suggest you don't set block timeout too long.


If you want to add a whitelist, create a whitelisted list

ipset create whitelisted hash:net

and change drop rule with that

iptables -A INPUT -m state --state NEW -m set --match-set port_scanners src -m set ! --match-set whitelisted src -j DROP
  • 6
    This should be the accepted answer.
    – pa4080
    Oct 14 '18 at 12:28
  • How can I add an IP to ignore/do not block by these rules?
    – Feriman
    Feb 1 at 13:17
  • I updated answer
    – ibrahim
    Feb 5 at 8:57

If you want a service (such as SSH) to be available and able to be used, then Nmap will be able to find it. Generally speaking, port scans are not a threat; your security should not depend on an attacker not knowing what services are running. Using a non-standard port for SSH is mainly useful for log noise reduction, since there is so much automated brute-forcing done on the default port 22.

Your primary goals from a security standpoint should be: Know/Predict, Prevent, Detect, Respond, and Recover. Here's how port scanning relates to these:

Know/Predict: Know what assets you have and what attackers will go for. Port scan yourself to see your exposure. Understand what port scans can and cannot do; they are not magical hacking fairy dust.

Prevent: Use a firewall to prevent access to ports/services that should not be public. Restrict access to known IP addresses. Move sensitive data and servers behind the network perimeter and control access with a VPN or other access control. Rate limiting is not prevention, only delay.

Detect: Monitor logs for port scan, brute force, and other indications of attack. Understand what is normal background noise and what actually constitutes a threat. Set up alerts for indications of compromise.

Respond: Have a plan for dealing with a security breach. Set up automated defenses like fail2ban to respond to threats. Rate limiting can be a response here, but does it really prevent anything?

Recover: Have a recovery plan. Make regular backups and test restoring from backup.


Here is what nmap's documentation says about the "filtered" state:

The state is either open, filtered, closed, or unfiltered. Open means that an application on the target machine is listening for connections/packets on that port. Filtered means that a firewall, filter, or other network obstacle is blocking the port so that Nmap cannot tell whether it is open or closed. Closed ports have no application listening on them, though they could open up at any time. Ports are classified as unfiltered when they are responsive to Nmap's probes, but Nmap cannot determine whether they are open or closed. Nmap reports the state combinations open|filtered and closed|filtered when it cannot determine which of the two states describe a port.

It seems that the normal behavior of a "closed" (i.e., a reachable port, but where no server is listening), is closer to the iptables REJECT action than to DROP, and that nmap's "filtered" diagnostic recognizes DROP (where the connection eventually times out, because of total silence from the server being examined, instead of being closed immediately, as would happen with REJECT.)

So I would suggest trying with REJECT instead of DROP, and seeing if the scan results are more to your liking.

  • Thank you for your answer! I forgot to mention I also tried REJECT instead of DROP. Rejecting input also returns "filtered" in nmap scans. Feb 15 '17 at 15:51

Based on ibrahim answer, I created a script to configure and keep these firewall rules always in iptable. By default these iptable rules lost after system restart. This script will run these iptable commands immediately after reboot.

You can reach this one on GitHub, the script name is Portscan Protection

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.