10 Essential Port Scanners Every Network Admin Should Know

Building a Custom Port Scanner with Python: Step-by-Step

This guide walks through building a simple, effective TCP port scanner in Python. It’s intended for educational use (network troubleshooting, asset discovery on networks you own or have permission to test). Do not scan networks without authorization.

What you’ll build

A command-line Python script that:

  • Accepts a target IP or hostname
  • Scans a range of TCP ports (configurable)
  • Returns open, closed, and filtered status (basic)
  • Runs scans concurrently for speed

Requirements

  • Python 3.8+
  • Modules: socket, argparse, concurrent.futures, datetime (All are in the standard library; no external packages required.)

Step 1 — Script outline

Create a file named scan.py and structure it with:

  • argument parsing
  • a worker function to test one port
  • a concurrent executor to run many workers
  • result aggregation and simple reporting

Step 2 — Argument parsing

Use argparse to accept:

  • target (positional): IP or hostname
  • –start (optional, default 1): start port
  • –end (optional, default 1024): end port
  • –timeout (optional, default 1.0): socket timeout in seconds
  • –workers (optional, default 100): concurrency level

Example code:

python

#!/usr/bin/env python3 import argparse def parse_args(): p = argparse.ArgumentParser(description=“Simple TCP port scanner”) p.add_argument(“target”, help=“IP address or hostname to scan”) p.add_argument(”–start”, type=int, default=1, help=“Start port (default 1)”) p.add_argument(”–end”, type=int, default=1024, help=“End port (default 1024)”) p.add_argument(”–timeout”, type=float, default=1.0, help=“Socket timeout seconds”) p.add_argument(”–workers”, type=int, default=100, help=“Concurrent workers”) return p.parse_args()

Step 3 — Port test worker

Use socket.createconnection to attempt a TCP connect. Return a simple status string.

python

import socket def scan_port(target, port, timeout): try: with socket.createconnection((target, port), timeout=timeout): return port, “open” except socket.timeout: return port, “filtered” except ConnectionRefusedError: return port, “closed” except Exception: return port, “filtered”

Notes:

  • ConnectionRefused usually means closed.
  • Timeout or other network errors can indicate filtered/unreachable.
  • This is a basic heuristic — advanced scanners use TCP/IP stack tricks.

Step 4 — Concurrency

Use ThreadPoolExecutor for I/O-bound tasks to scan many ports quickly.

python

from concurrent.futures import ThreadPoolExecutor, as_completed def run_scan(target, start, end, timeout, workers): results = [] with ThreadPoolExecutor(max_workers=workers) as exe: futures = {exe.submit(scan_port, target, port, timeout): port for port in range(start, end + 1)} for fut in ascompleted(futures): results.append(fut.result()) return sorted(results, key=lambda x: x[0])

Step 5 — DNS resolution and validation

Resolve hostname to IP and validate port range before scanning.

python

import socket import sys def resolvetarget(target): try: return socket.gethostbyname(target) except socket.gaierror as e: print(f”DNS resolution failed: {e}) sys.exit(1)

Step 6 — Reporting

Print a concise summary including elapsed time and each open port.

python

from datetime import datetime def report(results, target, ip, start, end, elapsed): open_ports = [p for p, s in results if s == “open”] print(f”Scan of {target} ({ip}) ports {start}-{end} completed in {elapsed:.2f}s”) if open_ports: print(“Open ports:”) for p in openports: print(f” - {p}) else: print(“No open ports found.”)

Step 7 — Main function

Put it together and run.

python

def main(): args = parse_args() ip = resolve_target(args.target) start, end = args.start, args.end if start < 1 or end > 65535 or start > end: print(“Invalid port range.”) return t0 = datetime.now() results = run_scan(ip, start, end, args.timeout, args.workers) elapsed = (datetime.now() - t0).total_seconds() report(results, args.target, ip, start, end, elapsed) if name == main: main()

Step 8 — Usage examples

  • Scan common ports on example.com: python3 scan.py example.com –start 1 –end 1024
  • Faster scan with higher concurrency and shorter timeout: python3 scan.py 192.0.2.10 –start 1 –end 5000 –workers 200 –timeout 0.5

Security & legal reminders

  • Only scan systems you own or have explicit permission to test.
  • Frequent or broad scans can trigger intrusion detection systems and may violate policies or laws.

Next steps / improvements

  • Add UDP scanning (requires raw sockets or external libs).
  • Implement SYN scan using raw sockets (needs root and more complex handling).
  • Parse service banners for identified open ports.
  • Output in formats (CSV, JSON) for integration with asset inventories.

This script provides a practical, extensible foundation for building more advanced scanning tools.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *