DEV Community

tuncay kebeli
tuncay kebeli

Posted on

Building a Free Port Scanner with Python, Flask, and Nmap πŸ›‘οΈ

Hello devs! πŸ‘‹

I recently built a comprehensive security tool suite called CyberScanTool, and I wanted to share the technical journey of building the Port Scanner module.

If you're interested in cybersecurity or backend development with Python, this guide is for you.

πŸš€ The Goal

I wanted to create a fast, web-based port scanner that:

  1. Is completely free (no login required).
  2. Runs on a lightweight Flask backend.
  3. Uses Nmap for reliable scanning.
  4. Returns results instantly via AJAX.

You can try the live demo here: πŸ‘‰ Free Port Scanner Tool

πŸ› οΈ The Tech Stack

  • Backend: Python 3.13 + Flask 3.1
  • Scanner Engine: Nmap (Network Mapper)
  • Frontend: Vanilla JS + CSS3 (No heavy frameworks)
  • Server: Nginx + Gunicorn on DigitalOcean

πŸ’» The Code Logic

Here is the simplified core logic of how the scanner works.

1. The Route Handler

We use Flask to handle the POST request. It's crucial to validate the input to prevent command injection.

import subprocess
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/scan', methods=['POST'])
def scan_ports():
    target = request.form.get('target')

    # 1. Input Validation (Crucial!)
    if not is_valid_domain(target):
        return jsonify({'error': 'Invalid domain'}), 400

    # 2. Run Nmap
    try:
        # -Pn: Treat host as online (skip ping)
        # -T4: Aggressive timing (faster)
        # --top-ports 20: Scan only most common ports
        cmd = ['nmap', '-Pn', '-T4', '--top-ports', '20', target]

        result = subprocess.run(
            cmd, 
            capture_output=True, 
            text=True, 
            timeout=30
        )

        return jsonify({'output': result.stdout})

    except subprocess.TimeoutExpired:
        return jsonify({'error': 'Scan timed out'}), 504
Enter fullscreen mode Exit fullscreen mode

2. Optimizing Performance ⚑

One of the biggest challenges was speed. Nmap can be slow if not configured correctly.

Tips for speed:

  • Skip DNS Resolution (-n): If you already have the IP, skip the reverse DNS lookup.
  • Limit Ports: Scanning all 65k ports takes forever. I limited the free tool to the top 20 critical ports (HTTP, HTTPS, SSH, FTP, etc.) for the fast scan mode.
  • Async Processing: For a production app, you should use a task queue like Celery. For this MVP, I used Gunicorn with gevent workers to handle concurrent requests without blocking.

πŸ”’ Security Considerations

Allowing users to run Nmap on your server is risky. Here is how I secured it:

  1. Input Sanitization: I wrote a strict regex to allow only valid domain names and IPs.
  2. Rate Limiting: I used Flask-Limiter to prevent abuse (e.g., 5 scans per minute per session).
  3. Private Network Blocking: The scanner is configured to block scanning of local IPs (127.0.0.1, 192.168.x.x) to prevent SSRF (Server-Side Request Forgery) attacks.

🌟 The Result

The final result is a snappy, responsive tool that helps developers and sysadmins quickly check their external exposure.

You can check out the full suite of tools, including SSL Checker, DNS Enumeration, and Whois Lookup here:

πŸ‘‰ https://www.trwebs.com

Let me know if you have any questions about the implementation! Happy coding. 🐍

python #security #flask #webdevelopment #showdev

Top comments (0)