SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration
SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration

This guide is for developers, sysadmins, and technical managers who want to harden their servers and web infrastructure by eliminating unnecessary network exposure. By the end of these steps you will know how to discover every port listening on your system, decide which ones genuinely need to be open, shut down the rest, and put monitoring in place so new risks do not silently appear over time.

01

Audit Your Currently Open Ports

Before you can close anything, you need a complete and accurate picture of what is currently listening for connections. Many servers accumulate open ports over time as software is installed and forgotten. Start from the server itself to get the ground truth, then verify from the outside.

  • Run ss -tlnup (or netstat -tlnup on older systems) on Linux to list every TCP and UDP port in a listening state, along with the process name and PID responsible.
  • On Windows Server, run netstat -ano in an elevated command prompt, then cross-reference PIDs with Task Manager or Get-Process in PowerShell.
  • Record the results in a spreadsheet: columns for port number, protocol (TCP/UDP), service name, and process owner.
  • Run an external port scan against your public IP address to see exactly what an attacker on the internet sees — Sensagraph continuously checks your exposed ports from the outside and highlights unexpected findings.
  • Compare the internal list with the external scan results; discrepancies often reveal firewall misconfigurations or cloud security-group gaps.
02

Identify Which Ports Are Necessary

Not every open port is a problem, but every open port needs a justification. Map each listening port to a business or operational requirement. If you cannot state a clear reason why a port must be reachable, it should be closed or at minimum restricted.

  • Common legitimately open ports on a web server: 80 (HTTP), 443 (HTTPS). Everything else should require an explicit reason.
  • Database ports such as 3306 (MySQL), 5432 (PostgreSQL), and 27017 (MongoDB) should never be exposed to the public internet — they should only be reachable on localhost or a private network interface.
  • Remote administration ports such as 22 (SSH) and 3389 (RDP) should be open only when strictly required and restricted by IP allowlist.
  • Development or debug ports (e.g., 8080, 8443, 9000, 4000) left running in production are a common risk — verify none are exposed.
  • Mail ports (25, 110, 143, 587, 993, 995) should only be open if your server is a mail server; otherwise close them entirely.
  • Mark each port in your spreadsheet as Required, Restricted (open but only to specific IPs), or Close.
03

Disable Unnecessary Services

Closing a port at the firewall level is good, but stopping the underlying service is better — it eliminates the listener entirely, reducing the risk of firewall misconfigurations re-exposing it. Disable services you do not need rather than just blocking them.

  • On systemd-based Linux: sudo systemctl stop <service> to stop immediately, then sudo systemctl disable <service> to prevent it starting on reboot.
  • Common services to review and disable if unused: telnet, ftp, rsh, rlogin, finger, talk, chargen, daytime, echo, discard.
  • Review and disable SNMP (port 161/162) if not used for monitoring; if SNMP is required, change default community strings and use SNMPv3 with authentication.
  • Disable Telnet (port 23) universally — it transmits credentials in plain text and has no legitimate use on modern systems.
  • On Windows, audit and disable services via services.msc or Set-Service -StartupType Disabled in PowerShell for services like Remote Registry, Routing and Remote Access, or NetBIOS helper if not required.
  • After stopping a service, re-run ss -tlnup to confirm the port is no longer listed before proceeding.
04

Configure Your Firewall Rules

Even for ports where the underlying service cannot be stopped, a properly configured firewall provides an important safety net. Adopt a default-deny approach: block everything, then explicitly allow only what is required.

  • Linux (iptables): Set the default policy to DROP for INPUT and FORWARD chains — iptables -P INPUT DROP and iptables -P FORWARD DROP — then add explicit ACCEPT rules for 80, 443, and your SSH port.
  • Linux (ufw): Run ufw default deny incoming, then ufw allow 443/tcp, ufw allow 80/tcp, and so on. Enable with ufw enable.
  • Linux (firewalld): Use firewall-cmd --set-default-zone=drop and then add only required services with firewall-cmd --permanent --add-service=https.
  • Windows Firewall: Open Windows Defender Firewall with Advanced Security, set the default inbound action to Block, and create specific Inbound Allow rules for required ports only.
  • Cloud environments (AWS, Azure, GCP): Review and tighten Security Groups / Network Security Groups / VPC Firewall Rules — these operate independently of the OS firewall and are often misconfigured.
  • Ensure your firewall rules are persisted across reboots (use iptables-save / netfilter-persistent on Debian/Ubuntu, or rely on firewalld/ufw which persist by default).
  • Block all ICMP timestamp requests and address mask replies to reduce information leakage, while allowing basic ping for legitimate diagnostics if required.
05

Restrict Administrative Ports by IP Allowlist

Some ports — most commonly SSH (22) and RDP (3389) — must remain open for legitimate administration but should never be accessible from arbitrary internet addresses. Restrict these to known, trusted IP ranges only.

  • Identify the static IP addresses or CIDR ranges used by your team for remote administration.
  • In your firewall, replace any broad ACCEPT rule for port 22 or 3389 with a source-restricted rule, e.g. iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT.
  • In cloud security groups, set the Source of SSH/RDP inbound rules to your specific office or VPN IP — never 0.0.0.0/0.
  • Consider moving SSH to a non-standard port (e.g., 2222) as a low-friction measure that reduces automated brute-force noise, though this is not a substitute for proper authentication and firewall rules.
  • Use a VPN or bastion host to avoid exposing administrative ports directly; require all admins to connect to the VPN before SSH or RDP becomes reachable.
  • Enable SSH key-based authentication and disable password login: set PasswordAuthentication no and PermitRootLogin no in /etc/ssh/sshd_config.
06

Handle Application-Level Ports Carefully

Web applications often expose additional ports for APIs, admin panels, development servers, or monitoring dashboards. These deserve the same scrutiny as infrastructure ports and are frequently overlooked during hardening.

  • Audit all listening ports above 1024 — applications commonly bind to 3000, 4000, 8080, 8443, 8888, 9000, 9090, and similar.
  • Proxy all application traffic through your main web server (Nginx or Apache) on port 443 using reverse proxy configuration, then bind application processes to 127.0.0.1 only so they are never directly reachable from outside.
  • In Node.js, configure your app to listen on 127.0.0.1:3000 rather than 0.0.0.0:3000 to prevent external exposure.
  • For Docker environments, avoid publishing ports with -p 0.0.0.0:PORT:PORT; bind to 127.0.0.1:PORT:PORT instead, and be aware that Docker bypasses iptables INPUT rules by default — use Docker's --iptables=false with a dedicated firewall ruleset or tools like ufw-docker.
  • Remove or password-protect monitoring dashboards (Grafana, Kibana, Prometheus) and never expose them on public interfaces without authentication.
  • Review /etc/nginx/sites-enabled/ and /etc/apache2/sites-enabled/ for any virtual hosts that may be serving content on unexpected ports.
07

Validate Your Changes

After making changes, verify them rigorously before considering the work done. It is common for a service to restart after an OS update and re-open a port, or for a cloud security group change to not save correctly.

  • Re-run ss -tlnup on the server and confirm only expected ports appear in the output.
  • Perform an external port scan immediately after applying firewall rules to confirm the changes are visible from outside the server — Sensagraph can be used to trigger a rescan and verify your exposed port profile.
  • Attempt to connect directly to ports that should be closed using telnet <IP> <PORT> or nc -zv <IP> <PORT> — a connection refusal or timeout confirms the port is inaccessible.
  • Test that required services (HTTPS, SSH from allowed IPs) still work correctly after firewall changes.
  • Document the final approved port list and store it in your runbook or infrastructure wiki for future reference.
08

Monitor Continuously for Port Drift

Port exposure is not a one-time fix. Software updates, new deployments, developer testing, container orchestration changes, and OS patches can all introduce new listening services without anyone noticing. Continuous monitoring is the only reliable defence against port drift.

  • Schedule recurring port scans — at minimum weekly, ideally daily — and alert on any port that appears in the results which was not present in the last scan.
  • Integrate port auditing into your CI/CD pipeline so that deployments that open new ports trigger a review step before going live.
  • Use intrusion detection tools such as auditd on Linux to log when processes bind to new network sockets.
  • Sensagraph performs continuous automated scanning of your attack surface and will alert you whenever a new port becomes visible externally, giving you immediate visibility into port drift without manual scheduling.
  • Review your open port list quarterly as part of a formal security review, updating the approved list to reflect legitimate infrastructure changes.
  • After any major infrastructure event — new server provisioning, cloud migration, Kubernetes cluster update — run a full port audit before treating the environment as production-ready.

Frequently asked questions

A typical web server should only have ports 80 (HTTP) and 443 (HTTPS) open to the public internet. Port 22 (SSH) may be open if needed for administration but should be restricted to specific IP addresses. All other ports — including database ports, monitoring dashboards, and development servers — should be closed or accessible only on internal/loopback interfaces.

No. Blocking a port with a firewall hides it from external access but the underlying service is still running and listening. If the firewall is misconfigured or bypassed (which can happen in Docker environments, for example), the port may become accessible again. The most secure approach is to stop and disable the underlying service so the port is not listening at all, and then also block it at the firewall as a defence-in-depth measure.

Every open port represents an attack surface. Attackers continuously scan the internet for open ports and attempt to exploit the services behind them using known vulnerabilities, default credentials, or brute force. An unused service that is never updated is particularly dangerous because it may contain known critical vulnerabilities that are never patched.

Yes, by default Docker directly manipulates iptables and adds rules that bypass the INPUT chain, meaning a container port published with -p can be accessible from the internet even if you have an iptables or ufw rule that appears to block it. To address this, bind published ports to 127.0.0.1 (e.g., -p 127.0.0.1:8080:8080), use a tool like ufw-docker, or run Docker with --iptables=false and manage rules manually.

At minimum, scan weekly. However, for production web applications, daily automated scanning is recommended because infrastructure changes — deployments, updates, new containers — can open ports at any time. Continuous scanning platforms like Sensagraph monitor your external attack surface around the clock so you are alerted immediately when something changes.

Moving SSH to a non-standard port (such as 2222 or 22222) reduces the volume of automated brute-force and scanning noise in your logs, which can make genuine threats easier to spot. However, it is not a security control in itself — a determined attacker will find the port with a full port scan. It should be combined with IP allowlisting, key-based authentication, and disabling password login.