Home > Coding > Build your own Port Scanner for Internal Network Testing

Build your own Port Scanner for Internal Network Testing

Hey everyone! If you’re like me and spend way too much time tinkering with network gear—especially Cisco appliances—you know how handy it is to quickly check what’s open on a device without firing up a full-blown tool like Nmap. Today, I’m sharing a lightweight Python port scanner I whipped up for internal testing. It’s super simple, uses only built-in libraries, and is perfect for spotting those common ports like SSH (22), HTTP (80), or SNMP (161) on your lab setup.

This isn’t production-grade (no UDP, no fancy service versioning), but it’s fast, threaded for efficiency, and gets the job done for quick audits. Important: This is for ethical, internal use only—get permission before scanning anything!

Why Build This?

  • No Dependencies: Runs on any Python 3.6+ setup—no installs needed.
  • Customizable: Scan any range, tweak timeouts, and focus on Cisco-friendly ports.
  • Interactive: Just input an IP and go.

I originally needed this to poke around a Cisco router in my home lab. Now, it’s yours to play with.

The Code

Here’s the full script. Save it as port_scanner.py and run with python port_scanner.py.

import socket
import threading
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed

def scan_port(target, port):
    """
    Scan a single port to check if it's open.
    """
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(1)  # 1 second timeout
        result = sock.connect_ex((target, port))
        if result == 0:
            print(f"Port {port}: Open")
            # Optional: Try to identify service
            try:
                sock.close()
                # You can add service detection here if needed, e.g., using socket.getservbyport
                service = socket.getservbyport(port)
                print(f"  Service: {service}")
            except OSError:
                print(f"  Service: Unknown")
        sock.close()
    except Exception as e:
        pass  # Silently ignore errors for speed

def port_scan(target, start_port=1, end_port=1024, max_workers=100):
    """
    Perform a port scan on the target IP from start_port to end_port.
    Uses threading for faster scanning.
    """
    print(f"Scanning {target} from port {start_port} to {end_port}...")
    open_ports = []

    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # Submit all port scan tasks
        future_to_port = {
            executor.submit(scan_port, target, port): port for port in range(start_port, end_port + 1)
        }

        # Collect results
        for future in as_completed(future_to_port):
            port = future_to_port[future]
            try:
                # The scan_port function prints directly, but we can collect if needed
                pass
            except Exception as exc:
                print(f"Port {port} generated an exception: {exc}")

    print("Scan completed.")

if __name__ == "__main__":
    target_ip = input("Enter the target IP address: ").strip()
    if not target_ip:
        print("No IP provided. Exiting.")
        sys.exit(1)

    # Validate IP format (basic check)
    try:
        socket.inet_aton(target_ip)
    except socket.error:
        print("Invalid IP address format. Please enter a valid IPv4 address.")
        sys.exit(1)

    # For Cisco appliances, common ports to check: 22 (SSH), 23 (Telnet), 80 (HTTP), 443 (HTTPS), 161 (SNMP), etc.
    # Scan top 1024 ports for a general scan, or customize the range
    port_scan(target_ip, start_port=1, end_port=1024)

How to Use It

  1. Run the Script: Fire it up in your terminal. It’ll prompt for the IP (e.g., 192.168.1.100).
  2. Watch the Magic: It scans ports 1-1024 by default, printing open ones with basic service names.
  3. Tweak for Cisco: Edit the port_scan call to narrow it down—try start_port=1, end_port=1000 or just common ones like 22, 80, 443.

Sample Output (scanning a test device):

Enter the target IP address: 192.168.1.100
Scanning 192.168.1.100 from port 1 to 1024...
Port 22: Open
  Service: ssh
Port 80: Open
  Service: http
Port 443: Open
  Service: https
Scan completed.

Pro Tip: For even faster runs on known ports, hardcode a list instead of a range.

Caveats and Next Steps

  • Limitations: TCP-only, basic detection. For deeper dives, grab Nmap.
  • Legal/Ethical Note: Only scan what you own or have explicit permission for. This could trip IDS/IPS.
  • Enhance It: Add UDP support? Output to JSON? Fork it on GitHub and let me know!

If you’re into this stuff, check out my GitHub repo for the full project (with a shiny README): github.com/www-lazy-xyz/port-scanner. Drop a comment below—what’s your go-to tool for network recon?

Leave a Comment