A comprehensive Python wrapper for nmap with enhanced features
Project description
nust-nmap
A robust, type-safe Python library providing an intuitive interface to the Nmap network scanning tool. Designed for security professionals, network administrators, and developers who need reliable network discovery and security auditing capabilities.
🚀 Key Features
- 🛡️ Type Safety: Comprehensive type hints with enhanced error handling
- ⚡ Performance: Asynchronous scanning with generator-based processing
- 📊 Multiple Output Formats: CSV export and raw XML access
- 🔍 Comprehensive Analysis: OS detection, service enumeration, and script execution
- 🔄 Flexible Scanning: Synchronous, asynchronous, and yield-based scan modes
- 📈 Production Ready: Robust error handling and logging for enterprise use
📦 Installation
Prerequisites
System Requirements:
- Python 3.8 or higher
- Nmap 7.0+ installed on your system
Install nust-nmap
pip install nust-nmap
Install Nmap
Ubuntu/Debian
sudo apt update && sudo apt install nmap
CentOS/RHEL/Fedora
sudo dnf install nmap # Fedora
sudo yum install nmap # CentOS/RHEL
macOS
brew install nmap
Windows
Download and install from nmap.org/download.html
🔧 Quick Start
Basic Network Scanning
import nmap
# Initialize scanner
scanner = nmap.PortScanner()
# Perform basic host discovery
result = scanner.scan('192.168.1.0/24', '22,80,443,8080')
# Analyze results
for host in scanner.all_hosts():
if scanner[host].state() == 'up':
print(f"🟢 {host} ({scanner[host].hostname()}) - {scanner[host].state()}")
for protocol in scanner[host].all_protocols():
ports = scanner[host][protocol].keys()
for port in sorted(ports):
state = scanner[host][protocol][port]['state']
service = scanner[host][protocol][port]['name']
print(f" Port {port}/{protocol}: {state} ({service})")
Service Version Detection
# Comprehensive service and version detection
scanner.scan('target.example.com', '1-1000', '-sV -sC -O')
for host in scanner.all_hosts():
print(f"\n=== {host} ===")
for port in scanner[host]['tcp']:
service_info = scanner[host]['tcp'][port]
print(f"Port {port}: {service_info['state']} "
f"({service_info['name']} {service_info.get('version', '')})")
📖 Comprehensive Usage Guide
Advanced Scanning Techniques
Stealth Scanning
# SYN stealth scan with timing optimization
scanner.scan('target-network.com', '1-65535', '-sS -T4 --min-rate 1000')
Service and OS Detection
# Comprehensive reconnaissance
scanner.scan('target.com', arguments='-sV -sC -O -A --script vuln')
Custom Nmap Scripts
# Execute specific NSE scripts
scanner.scan('web-server.com', '80,443', '--script http-title,http-headers,ssl-cert')
Asynchronous Scanning for Performance
import time
import threading
class NetworkScanner:
def __init__(self):
self.results = []
self.scan_complete = threading.Event()
def scan_callback(self, host, scan_result):
"""Callback function for async scan results"""
if scan_result:
self.results.append((host, scan_result))
print(f"✅ Completed scan for {host}")
else:
print(f"❌ Failed to scan {host}")
def scan_network_async(self, network, ports):
"""Perform asynchronous network scan"""
scanner = nmap.PortScannerAsync()
scanner.scan(
hosts=network,
ports=ports,
arguments='-sS -sV',
callback=self.scan_callback
)
# Monitor scan progress
while scanner.still_scanning():
print(f"⏳ Scanning in progress... ({len(self.results)} hosts completed)")
time.sleep(2)
print(f"🎉 Network scan completed! Found {len(self.results)} responsive hosts")
return self.results
# Usage
network_scanner = NetworkScanner()
results = network_scanner.scan_network_async('192.168.1.0/24', '22,80,443,8080')
Generator-Based Processing
def process_large_network(network_range, ports):
"""Efficiently process large network ranges"""
scanner = nmap.PortScannerYield()
active_hosts = []
for host, result in scanner.scan(network_range, ports=ports, arguments='-sS'):
if result and result['nmap']['scanstats']['uphosts'] != '0':
active_hosts.append(host)
print(f"📡 Active host discovered: {host}")
# Process immediately to save memory
yield host, result
print(f"🔍 Discovery complete: {len(active_hosts)} active hosts found")
# Process enterprise network efficiently
for host, data in process_large_network('10.0.0.0/16', '22,80,443'):
# Handle each host as discovered
pass
Data Export and Analysis
import csv
from datetime import datetime
def export_scan_results(scanner, filename=None):
"""Export scan results to multiple formats"""
if not filename:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"nmap_scan_{timestamp}"
# Export to CSV
csv_data = scanner.csv()
with open(f"{filename}.csv", 'w', newline='') as f:
f.write(csv_data)
# Export raw XML
xml_data = scanner.get_nmap_last_output()
with open(f"{filename}.xml", 'w') as f:
f.write(xml_data)
print(f"📄 Results exported:")
print(f" CSV: {filename}.csv")
print(f" XML: {filename}.xml")
return filename
# Usage
scanner.scan('192.168.1.0/24', '22,80,443,8080', '-sV')
export_scan_results(scanner, "network_audit_2024")
🔧 API Reference
Core Classes
PortScanner
Primary synchronous scanning interface.
scanner = nmap.PortScanner()
Key Methods:
scan(hosts, ports=None, arguments='-sV', sudo=False, timeout=0)- Execute scanlistscan(hosts)- Host discovery without port scanningall_hosts()- Retrieve all discovered hostshas_host(host)- Check if host exists in resultscsv()- Export results as CSVget_nmap_last_output()- Get raw XML output
PortScannerAsync
High-performance asynchronous scanning.
async_scanner = nmap.PortScannerAsync()
async_scanner.scan(hosts, ports, arguments, callback)
PortScannerYield
Memory-efficient generator-based scanning.
yield_scanner = nmap.PortScannerYield()
for host, result in yield_scanner.scan(hosts, ports):
process_host(host, result)
Host Data Access
# Access host information
host = scanner['192.168.1.1']
# Host properties
host.hostname() # DNS hostname
host.state() # Host state (up/down)
host.all_protocols() # Available protocols
host.all_tcp() # TCP ports
host.all_udp() # UDP ports
# Port-specific data
host.has_tcp(80) # Check TCP port existence
port_info = host.tcp(80) # Get port details
🛡️ Security Best Practices
Ethical Scanning Guidelines
import ipaddress
def validate_scan_target(target):
"""Validate scan targets against ethical guidelines"""
# Define restricted networks
restricted_networks = [
ipaddress.ip_network('169.254.0.0/16'), # Link-local
ipaddress.ip_network('224.0.0.0/4'), # Multicast
ipaddress.ip_network('127.0.0.0/8'), # Loopback (allow for testing)
]
try:
target_network = ipaddress.ip_network(target, strict=False)
for restricted in restricted_networks:
if target_network.overlaps(restricted) and not target.startswith('127.'):
raise ValueError(f"Scanning {target} is not recommended")
except ValueError as e:
print(f"⚠️ Target validation warning: {e}")
return False
return True
# Always validate targets
if validate_scan_target('192.168.1.0/24'):
scanner.scan('192.168.1.0/24', '22,80,443')
Error Handling and Resilience
import logging
from contextlib import contextmanager
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@contextmanager
def safe_scan_context():
"""Context manager for safe scanning with cleanup"""
scanner = None
try:
scanner = nmap.PortScanner()
yield scanner
except nmap.PortScannerError as e:
logger.error(f"Scan error: {e}")
raise
except nmap.PortScannerTimeout as e:
logger.warning(f"Scan timeout: {e}")
raise
except Exception as e:
logger.error(f"Unexpected error: {e}")
raise
finally:
if scanner:
logger.info("Scan context cleanup completed")
# Robust scanning implementation
def robust_network_scan(network, ports, max_retries=3):
"""Perform network scan with retry logic"""
for attempt in range(max_retries):
try:
with safe_scan_context() as scanner:
result = scanner.scan(network, ports, arguments='-sS -T3')
return scanner, result
except nmap.PortScannerTimeout:
if attempt < max_retries - 1:
logger.warning(f"Timeout on attempt {attempt + 1}, retrying...")
continue
raise
except nmap.PortScannerError as e:
logger.error(f"Scan failed: {e}")
if "permission" in str(e).lower():
logger.info("Try running with sudo for raw socket access")
raise
# Usage
try:
scanner, results = robust_network_scan('192.168.1.0/24', '22,80,443')
logger.info(f"Successfully scanned {len(scanner.all_hosts())} hosts")
except Exception as e:
logger.error(f"Network scan failed: {e}")
📊 Common Scan Patterns
| Scan Type | Command | Use Case |
|---|---|---|
| Host Discovery | -sn |
Network reconnaissance |
| Stealth Scan | -sS |
Firewall evasion |
| Version Detection | -sV |
Service enumeration |
| OS Detection | -O |
Operating system fingerprinting |
| Aggressive Scan | -A |
Comprehensive analysis |
| Script Scan | --script <category> |
Vulnerability assessment |
| UDP Scan | -sU |
UDP service discovery |
| Fast Scan | -T4 --min-rate 1000 |
Time-sensitive scanning |
🤝 Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Development Setup
# Clone repository
git clone https://github.com/codeNinja62/nust-nmap.git
cd nust-nmap
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/
📜 License
This project is licensed under the MIT License - see the LICENSE file for details.
👤 Author
Sameer Ahmed
- Email: sameer.cs@proton.me
- GitHub: @codeNinja62
🙏 Acknowledgments
- Built upon the robust Nmap Security Scanner
- Inspired by the original python-nmap library
- Special thanks to the cybersecurity community for feedback and contributions
🔗 Links
⚠️ Legal Disclaimer
IMPORTANT: This tool is designed for authorized security testing and network administration only.
- ✅ Authorized Use: Own networks, approved penetration testing, security research
- ❌ Prohibited Use: Unauthorized scanning, malicious activities, illegal reconnaissance
Users are solely responsible for compliance with applicable laws and regulations. Always obtain explicit permission before scanning networks you do not own or administer.
"Know your network, secure your future." 🛡️
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nust_nmap-1.2.tar.gz.
File metadata
- Download URL: nust_nmap-1.2.tar.gz
- Upload date:
- Size: 30.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04ee7f51fa75e4a50550d3eabb7470d74bfea4848b0aab045f0f81e0a4ccb221
|
|
| MD5 |
02187874195eaea502ceb570ea6fead0
|
|
| BLAKE2b-256 |
6da8deec8eabc53f60f98a7697c5ccf334a8987a7996db240aac10bdf758af31
|
Provenance
The following attestation bundles were made for nust_nmap-1.2.tar.gz:
Publisher:
publish.yml on codeNinja62/nust-nmap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nust_nmap-1.2.tar.gz -
Subject digest:
04ee7f51fa75e4a50550d3eabb7470d74bfea4848b0aab045f0f81e0a4ccb221 - Sigstore transparency entry: 267521233
- Sigstore integration time:
-
Permalink:
codeNinja62/nust-nmap@f5409ce26f67f7d37178b3f062938d2fe4bbf5aa -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/codeNinja62
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f5409ce26f67f7d37178b3f062938d2fe4bbf5aa -
Trigger Event:
release
-
Statement type:
File details
Details for the file nust_nmap-1.2-py3-none-any.whl.
File metadata
- Download URL: nust_nmap-1.2-py3-none-any.whl
- Upload date:
- Size: 25.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2040b299b53c5cb57e37c801d264b01e335306d98e727e07b525aac8b4476e7
|
|
| MD5 |
c93184a62545ebc3302b1396b1729dbf
|
|
| BLAKE2b-256 |
48423ffbdbce509dbb34c804d181918e2484f276fac287957fe6096810246d56
|
Provenance
The following attestation bundles were made for nust_nmap-1.2-py3-none-any.whl:
Publisher:
publish.yml on codeNinja62/nust-nmap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nust_nmap-1.2-py3-none-any.whl -
Subject digest:
e2040b299b53c5cb57e37c801d264b01e335306d98e727e07b525aac8b4476e7 - Sigstore transparency entry: 267521243
- Sigstore integration time:
-
Permalink:
codeNinja62/nust-nmap@f5409ce26f67f7d37178b3f062938d2fe4bbf5aa -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/codeNinja62
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f5409ce26f67f7d37178b3f062938d2fe4bbf5aa -
Trigger Event:
release
-
Statement type: