Over a million developers have joined DZone.

Automate Insecure Ports Check By Nmap

DZone's Guide to

Automate Insecure Ports Check By Nmap

In this article, you will learn how to automate the audit process of insecure TCP Ports.

· Performance Zone ·
Free Resource

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

While Go Cloud is a prevailing trend, security is something we can't afford to ignore; people hate malicious access. Periodically checking all widely open TCP Ports is one good practice to secure our system in cloud. Obviously, DB ports can't be exposed to the whole internet, but our internal REST API also need to be protected.

We should always make sure our firewall is properly configured. What's more important, we need to be always on top of these security holes with minimal effort. So let's automate the audit process of insecure TCP Ports.


Permanent Link: http://dennyzhang.com/nmap_port_scan

Episode 1: Identity Insecure Ports Exported In My Servers.

Here are some general principles for firewall configuration.

  • Only allow public access to very few ports, like http(80), https(443), etc.
  • For sshd(22), only selective source ip can connect.
  • For DB ports, like mysql(3306), elasticsearch(9200), we don't expose them directly. Key members can connect through ssh protocol by ssh tunnel.
  • For traffic within the cluster, the default policy is always accept. If we can configure them with more limited privilege, that's nice but not always practical. Developers are usually too busy to list all traffic rules correctly and precisely. Even if they do, the rules will change constantly from time to time.

Our first step is listing all TCP ports which are open to the world. If some are against the above principles, we raise an alert. Here we can use Nmap, which is an open source tool for network exploration and security auditing.

# Install Nmap package
sudo apt-get install nmap
# Scan all TCP ports for a given host
sudo nmap -sS -PN
# === Run: sudo nmap -sS -PN
# Starting Nmap 6.40 ( http://nmap.org )
# Nmap scan report for
# Host is up (0.00051s latency).
# Not shown: 997 filtered ports
# 22/tcp  open  ssh
# 80/tcp  open  http
# 443/tcp open  https

In this post, we won't introduce the detailed usage of Nmap, which is definitely a versatile tool. We want to run the check as fast as possible. Thus we use TCP SYN(-sS) to test. And skip host discovery (-PN), assuming the sever is up.

By default, Nmap scans the top 1000 most popular ports according to the statistics generated from Internet-wide scans and large internal network scans from the summer of 2008. We may have some extra ports to scan.

Here is how:

# Check certain TCP ports
sudo nmap -p T:9200-9500,8090-8100 \

Episode 2: Automate Check Process And Get Alerts Automatically.

Now we can list all open Ports. Mostly there are a bunch of servers to check. And we need to check the output careful to detect potential issues. We definitely don't want to do that manually. What's more, things will change all the time. This means we will have to do it again and again. It's way too much for a human — boring and error-prone!

To automate the process, we need to provide 3 things:

  • Server list to check. The list might be stable or dynamic which can be retrieved from other systems.
  • Whitelist for open ports. The rule may apply to all servers or only certain servers.
  • Extra ports to scan, other than the default 1000 ports.

Put It All Together.

Here comes Jenkins job (TCPScanReport), which runs daily. If it fails, we will be notified by emails or slacks!


What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

security ,devops ,devops best practices

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}