How to Perform a Complete Server Port Security Audit with nmap

This guide walks ops engineers through installing nmap, understanding its scan techniques, executing single‑port, common‑port, full‑range, and script‑based scans, analyzing results, and applying remediation steps such as firewall rules, service hardening, and regular scanning schedules to keep server exposure minimal.

Raymond Ops
Raymond Ops
Raymond Ops
How to Perform a Complete Server Port Security Audit with nmap

Introduction

Every open port on a server is a potential attack surface. When taking over a new server, changing firewall rules, or launching a new service, ops engineers should run a port‑security check to ensure only required ports are listening.

Chapter 1: nmap Basics and Installation

1.1 What is nmap

nmap (Network Mapper) is a popular port‑scanning and network‑discovery tool that can probe port states, service versions, and OS types.

# Verify installation
which nmap

# Install if missing
# CentOS / RHEL
sudo yum install nmap -y
# Ubuntu / Debian
sudo apt install nmap -y
# macOS
brew install nmap
# Windows: download from https://nmap.org/download.html

1.2 Scan Techniques

TCP SYN scan ( -sS): sends SYN, receives SYN‑ACK for open ports; requires root.

TCP connect scan ( -sT): completes three‑way handshake; no root needed but more detectable.

UDP scan ( -sU): sends UDP packets; no response may mean open or filtered; slower.

FIN scan ( -sF): sends FIN packets to bypass some firewalls.

Ping scan ( -sn): only checks host liveness.

# Show nmap version and available scripts
nmap --version
ls /usr/share/nmap/scripts/ | wc -l  # hundreds of NSE scripts

Chapter 2: Basic Port Scanning

2.1 Single‑Port Scan

# Scan port 22 on a host
nmap -p 22 192.168.1.100
# Example output
# Starting Nmap 7.94 ( https://nmap.org )
# PORT   STATE SERVICE
# 22/tcp open  ssh

# Scan multiple ports or ranges
nmap -p 22,80,443 192.168.1.100   # list
nmap -p 22-100 192.168.1.100       # range
nmap -p -1000 192.168.1.100       # first 1000 ports
nmap -p 1-65535 192.168.1.100     # full scan

2.2 Common‑Port Quick Scan

# Scan the 20 most common ports
nmap --top-ports 20 192.168.1.100
# Common ports list (FTP 21, SSH 22, Telnet 23, … Elasticsearch 9200, MongoDB 27017)

2.3 Full‑Port Scan

# Full scan (may be slow)
nmap -p 1-65535 -T4 192.168.1.100
# Production recommendation: -T3 or -T4
# Faster subset
nmap -p- -T4 192.168.1.100
# Save results for later comparison
nmap -p 1-65535 -oA /tmp/portscan-$(date +%Y%m%d) 192.168.1.100

2.4 Host Discovery and Batch Scanning

# Ping sweep
nmap -sn 192.168.1.0/24
# Exclude specific IPs
nmap -sn 192.168.1.0/24 --exclude 192.168.1.1,192.168.1.2
# Scan multiple hosts
nmap -p 22,80,443 192.168.1.100,192.168.1.101,192.168.1.200
# Use an IP list file
nmap -p 22,80,443 -iL /tmp/servers.txt

Chapter 3: Service Version Detection

3.1 Detect Service Versions

# Version detection on selected ports
nmap -sV -p 22,80,443,3306,6379 192.168.1.100
# Sample output
# PORT   STATE SERVICE VERSION
# 22/tcp open  ssh     OpenSSH 8.4 (protocol 2.0)
# 80/tcp open  http    Apache httpd 2.4.51
# 443/tcp open ssl     nginx 1.21.4
# 3306/tcp open mysql   MySQL 8.0.32
# 6379/tcp open redis   Redis 6.0.16

# Why version matters?
# If OpenSSH 8.4 has CVE‑2022‑1234, upgrade immediately.
# If Redis 6.0.16 allows empty passwords, fix it.

3.2 OS Fingerprinting

# OS detection (requires root)
nmap -O 192.168.1.100
# Example output
# OS details: Linux 5.4 (Ubuntu 20.04)
# OS CPE: cpe:/o:linux:linux_kernel:5.4

3.3 Aggressive Scan (‑A)

# Comprehensive reconnaissance (OS + version + traceroute + scripts)
nmap -A -T4 192.168.1.100

Chapter 4: nmap Scripting Engine (NSE)

4.1 NSE Overview

nmap ships with hundreds of scripts for vulnerability detection, weak‑credential checks, and brute‑force testing.

# List script categories
ls /usr/share/nmap/scripts/
# Categories include auth, broadcast, brute, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, vuln

4.2 Common Script Scans

# Default script set
nmap -sC -p 22,80,443,3306,6379 192.168.1.100

# SSH auth methods
nmap -p 22 --script ssh-auth-methods 192.168.1.100
# MySQL info and empty‑password check
nmap -p 3306 --script mysql-info,mysql-empty-password,mysql-users 192.168.1.100
# Redis info and brute‑force
nmap -p 6379 --script redis-info,redis-brute 192.168.1.100
# HTTP enumeration and robots.txt
nmap -p 80,443 --script http-enum,http-robots.txt,http-title 192.168.1.100
# SSL/TLS checks
nmap -p 443 --script ssl-enum-ciphers,ssl-cert,ssl-known-key 192.168.1.100

4.3 Vulnerability Scripts

# Generic vuln scan on web ports
nmap -p 80,443 --script vuln 192.168.1.100
# Specific SSH vulnerability
nmap -p 22 --script ssh-vuln-* 192.168.1.100
# Heartbleed test
nmap -p 443 --script ssl-heartbleed 192.168.1.100

4.4 Brute‑Force Checks

# FTP anonymous login test
nmap -p 21 --script ftp-anon 192.168.1.100
# MySQL empty root password
nmap -p 3306 --script mysql-empty-password 192.168.1.100
# Redis weak password (requires dict)
nmap -p 6379 --script redis-brute --script-args userdb=users.txt,passdb=pass.txt 192.168.1.100

Chapter 5: Production‑Environment Scanning Considerations

5.1 Impact on Business

Network bandwidth consumption.

Potential IDS/IPS alerts.

Brief server load spikes.

Recommendations:

Avoid peak business hours.

Use slower timing templates (‑T1 or ‑T2).

Test commands in a staging environment first.

Notify the security team to prevent false alarms.

# Low‑speed scan for production
nmap -T2 -p 1-1000 192.168.1.100
# Skip host discovery if host is known online
nmap -Pn -T2 -p 1-1000 192.168.1.100

5.2 Scanning Your Own Server vs. Others

Own server : legal and routine.

Other servers (must have written authorization; illegal without it). In CTF or authorized pen‑test scenarios it is allowed.

# Scan localhost with SYN (requires root)
sudo nmap -sS -p 1-1000 localhost
# Scan localhost with connect scan (no root)
nmap -sT -p 1-1000 localhost

5.3 Regular Scan Schedule

# Monthly scan via cron
0 3 1 * * /usr/local/bin/portscan-check.sh

#!/bin/bash
DATE=$(date +%Y%m%d)
LOG_DIR="/var/log/security"
SERVERS_FILE="/etc/security/scan-hosts.txt"
REPORT="${LOG_DIR}/portscan-${DATE}.html"
mkdir -p "$LOG_DIR"
# Full scan and HTML report
nmap -sV -sC -p- -oA "$LOG_DIR/portscan-${DATE}" -iL "$SERVERS_FILE"
# Compare with previous month
if [ -f "${LOG_DIR}/portscan-$(date -d '1 month ago' +%Y%m%d).gnmap" ]; then
  diff <(grep "Ports:" "${LOG_DIR}/portscan-$(date -d '1 month ago' +%Y%m%d).gnmap" | cut -d: -f2) \
       <(grep "Ports:" "${LOG_DIR}/portscan-${DATE}.gnmap" | cut -d: -f2) || true
fi

Chapter 6: Result Analysis and Remediation

6.1 Common High‑Risk Ports

22 (SSH) – Medium risk: weak passwords enable brute‑force.

23 (Telnet) – High risk: clear‑text transmission.

445 (SMB) – High risk: EternalBlue (CVE‑2017‑0144).

3306 (MySQL) – Medium risk: exposed without password.

6379 (Redis) – High risk: default no password.

27017 (MongoDB) – High risk: unauthenticated access.

9200 (Elasticsearch) – High risk: unauthenticated read/write.

6.2 Self‑Check Checklist

# SSH check
nmap -p 22 --script ssh-auth-methods 192.168.1.100
# If password auth is allowed, enforce key‑only login in /etc/ssh/sshd_config

# Database ports check (3306, 5432, 6379, 27017)
nmap -p 3306,6379 --script redis-info,mysql-info 192.168.1.100

# Memcached check
nmap -p 11211 --script memcached-info 192.168.1.100

# RDP check
nmap -p 3389 192.168.1.100

6.3 Firewall Example

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Allow established connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
-A INPUT -i lo -j ACCEPT
# Allow SSH from specific IP
-A INPUT -p tcp -s 1.2.3.4/32 --dport 22 -j ACCEPT
# Allow HTTP/HTTPS
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allow DB ports only from internal network
-A INPUT -p tcp -s 10.0.0.0/8 --dport 3306 -j ACCEPT
-A INPUT -p tcp -s 10.0.0.0/8 --dport 6379 -j ACCEPT
# Drop everything else
-A INPUT -j DROP
COMMIT

6.4 Cloud Security‑Group Check (Alibaba Cloud example)

# List security groups
aliyun ecs DescribeSecurityGroups
# Show inbound rules for a group
aliyun ecs DescribeSecurityGroupPolicy --SecurityGroupId sg-xxxxxx --Direction ingress
# Common mistake: allowing 0.0.0.0/0 to DB ports
# Correct: restrict to internal IP ranges

Chapter 7: Report Interpretation and Follow‑Up

7.1 Reading nmap Output

# Convert XML to HTML
nmap -oX /tmp/scan.xml 192.168.1.100
xsltproc /tmp/scan.xml -o /tmp/scan.html
# Or grep the grepable format
nmap -oG /tmp/scan.gnmap 192.168.1.100
grep "Ports:" /tmp/scan.gnmap

7.2 Remediation Workflow

Step 1: Verify necessity – Is the open port required for business?

Step 2: Validate access control – Check firewall rules, test external connectivity.

Step 3: Apply fixes

Close unnecessary ports or block them with firewall.

For SSH, enforce key‑only login and disable password auth.

Set strong passwords or bind Redis/MySQL to internal networks.

Upgrade services with known CVEs.

Step 4: Document – Record findings, responsible personnel, remediation actions, and timestamps in a security log or CMDB.

7.3 Automation Example

#!/bin/bash
TARGET=${1:-localhost}
OUTPUT_DIR="/var/www/html/nmap-reports"
DATE=$(date +%Y%m%d)
mkdir -p $OUTPUT_DIR

echo "Scanning $TARGET..."
# Quick scan
nmap -sV -sC -F -T4 -oA "$OUTPUT_DIR/quick-$DATE" "$TARGET"
# Full scan (slow)
nmap -sV -p- -T2 -oA "$OUTPUT_DIR/full-$DATE" "$TARGET"
# Vulnerability scan on key ports
nmap -sV --script vuln -p 22,80,443,3306,6379 -oA "$OUTPUT_DIR/vuln-$DATE" "$TARGET"
# Generate HTML reports
xsltproc "$OUTPUT_DIR/quick-$DATE.xml" -o "$OUTPUT_DIR/quick-$DATE.html"
xsltproc "$OUTPUT_DIR/vuln-$DATE.xml" -o "$OUTPUT_DIR/vuln-$DATE.html"
# Detect newly opened ports compared to last month
if [ -f "$OUTPUT_DIR/full-$(date -d '1 month ago' +%Y%m%d).gnmap" ]; then
  diff <(grep "Ports:" "$OUTPUT_DIR/full-$(date -d '1 month ago' +%Y%m%d).gnmap" | cut -d: -f2) \
       <(grep "Ports:" "$OUTPUT_DIR/full-$DATE.gnmap" | cut -d: -f2) > "$OUTPUT_DIR/changes-$DATE.txt" || true
fi

echo "Reports generated:"; ls -la "$OUTPUT_DIR"/*-$DATE.*

Appendix A: nmap Parameter Quick Reference

-sn

: Ping‑only host discovery (fast). -sS: TCP SYN (default, requires root). -sT: TCP connect (no root). -sU: UDP scan. -sV: Service version detection. -O: OS detection (root). -A: Aggressive scan (OS, version, traceroute, scripts). -sC: Default script set. --script=vuln: Run vulnerability scripts. -p 1-1000: Scan specific range. -p-: Scan all ports (1‑65535). -T1~5: Timing template (use T2‑T3 in production). -oA: Output in all formats (nmap, XML, grepable). -iL: Read targets from file. --exclude: Omit specified hosts. -6: IPv6 scan.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

firewallLinuxsysadminport scanningvulnerability scanningnmapsecurity audit
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.