A fast, async port scanner with banner grabbing
Project description
Socket Scout
A high-performance, concurrent port scanner written in Python that focuses on correct asynchronous design, per-host isolation, and extensibility. This project demonstrates systems-oriented software engineering with an asyncio-based pipeline for efficient multi-host and large-range scanning.
Ethical Disclaimer
This tool is intended for educational purposes and should only be used on systems you own or have explicit permission to test. Unauthorized scanning of networks or systems may be illegal or unethical. Always ensure you have proper authorization before using this tool.
Notice
- This project is designed to run on Linux, macOS, and Windows systems with Python 3.10 or later installed.
- Root/sudo privileges required: Raw socket operations require elevated privileges, so you must run this tool with sudo or as root. Use with caution and only on authorized systems.
- This project is a work in progress, and I am open to suggestions for improvement. Please let me know if you have any ideas or feedback.
Devices Supported
- Linux distributions (Ubuntu, Debian, Fedora, etc.)
- Windows 10 (WSL) or later
- macOS
MAC Limitations
- Due to the way of how macOS handles raw sockets, the SYN scan mode may not work as expected
- SYN scan is still available on macOS, but may produce unreliable results. TCP connect scan is recommended for macOS users.
- Possible fixes for more consistent results (not guaranteed):
- Increase the timeout (
-Tflag) to allow more time for responses - Set retry count (
-rflag) to 1 or higher to allow for multiple attempts - Use a smaller port range to reduce the number of packets sent
- Increase the timeout (
Dependencies
System Requirements
- Python 3.10 or later
- libpcap library (required for packet manipulation)
Install libpcap:
# Ubuntu/Debian
sudo apt-get install libpcap-dev
# Fedora/RHEL
sudo dnf install libpcap-devel
# macOS (usually pre-installed, or via Homebrew)
brew install libpcap
Python Packages
- See
pyproject.tomlfor Python package dependencies (automatically installed with pip)
Installation
Note: Due to PEP 668 (externally managed environments), it's recommended to use pipx for CLI tools or install in a virtual environment.
Recommended: Using pipx
# Install pipx with apt if you don't have it (or use your package manager)
sudo apt-get install pipx
pipx ensurepath
source ~/.bashrc # or ~/.zshrc to refresh your shell environment
# Install socketscout
pipx install socketscout
# Create a symbloic link for sudo usage (since pipx installs to ~/.local/bin whiVch is not in the sudo PATH)
sudo ln -s ~/.local/bin/socketscout /usr/local/bin/socketscout
# Run with sudo (required)
sudo socketscout -t localhost
Alternative: From PyPI with pip
# Create a virtual environment
python3 -m venv ~/socketscout-env
source ~/socketscout-env/bin/activate
pip install socketscout
# Run with sudo
sudo ~/socketscout-env/bin/socketscout -t localhost
From GitHub Release
# In a virtual environment
python3 -m venv ~/socketscout-env
source ~/socketscout-env/bin/activate
pip install https://github.com/JoelBeau/socketscout/releases/latest/download/socketscout-1.0.3-py3-none-any.whl
From Source
# Clone and install in development mode
git clone https://github.com/JoelBeau/socketscout.git
cd socketscout
sudo ./build.sh
Features
- Concurrent scanning across multiple hosts and large port ranges
- Asyncio-based pipeline to maximize throughput and avoid blocking
- Per-host state isolation to prevent cross-target interference
- TCP connect scanning as the default method
- Optional SYN-based scanning for reduced connection overhead
- Modular banner-grabbing stage for service metadata extraction
- Configurable timeouts, retries, and concurrency limits
- Clean separation between scan logic, networking primitives, and output
How to Use
Note: Sudo is required to use this tool due to the need for raw socket operations. Make sure to run with appropriate permissions and only on systems you own or have explicit permission to test.
-
Basic scan of a single host (default port range is 1-1025):
sudo socketscout -t localhost
-
Scan specific ports:
sudo socketscout -t localhost -p 22,80,443
-
Scan a port range:
sudo socketscout -t localhost -p 1-1024
-
Scan with banner grabbing & increased verbosity:
sudo socketscout -t localhost -v 2 -b
-
Output to text file (other formats are available):
sudo socketscout -t localhost -o test.txt
-
View all available options:
sudo socketscout --help
Output Examples
-
Default output format (text, to console):
sudo socketscout -t localhost -p 22,80,443 -b
-
JSON output format to console:
sudo socketscout -t localhost -p 22,80,443 -b -o json
-
CSV output format to console:
sudo socketscout -t localhost -p 22,80,443 -b -o csv
For each output type, they can be written to a file instead of the console by providing a filename instead of "json" or "text" to the -o flag. For example:
sudo socketscout -t localhost -p 22,80,443 -b -o results.txt
Note that the file will be renamed by adding on the hostname (if applicable) to the end of the filename, so the above command will actually write to results-localhost.txt. This is to prevent overwriting results when scanning multiple hosts.
Usage Examples
Programmatic Usage
You can also import and use the scanner in your own Python scripts:
import asyncio
from port_scanner import Scanner
async def main():
flags = {
"scan_type": "tcp",
"target": "example.com",
"ports": [80, 443]
}
scanner = SCANNER_CLASS[flags["scan_type"]](**flags)
results = await scanner.scan(**flags)
for port in results:
print(f"{port}")
asyncio.run(main())
Logging
The port scanner includes a centralized logging system that tracks all operations and events during scanning.
Location: port_scanner/log.py
Features:
- File-based logging to
port_scanner.log - Configurable log directory via
port_scanner/config.py - Automatic log flushing on program exit
- Timestamp, logger name, and log level included in each message
- Default logging level: INFO
Log Output:
Logs are written to the configured log directory (typically ~/.config/port_scanner/logs/ or your custom LOG_DIR setting in config.py).
Using the Logger in Your Code:
from port_scanner.log import setup_logger
# Create a logger for your module
logger = setup_logger(__name__)
# Log at different levels
logger.info("Scan started")
logger.warning("High latency detected")
logger.error("Connection timeout")
Design Overview
This project is structured as a pipeline rather than a monolithic loop. Each target host maintains its own scanning state and concurrency limits, preventing shared-state bugs and ensuring predictable behavior when scanning multiple hosts concurrently.
Scanning is performed asynchronously using non-blocking I/O. Blocking operations are isolated from the event loop to preserve responsiveness and correctness. Banner grabbing is implemented as a separate stage that executes only after a port is confirmed open, reducing unnecessary connections and improving overall efficiency.
Input → Host Queue → Scanner Pipeline → Port Check → Banner Grab → Output
↓
Per-Host State
(isolation, limits)
Architecture & Components
The port scanner is organized into modular components, each responsible for a specific aspect of the scanning pipeline:
core/
- scanner.py: Main orchestration engine that manages the concurrent scanning pipeline across multiple hosts. Handles semaphore-based concurrency control, error handling, and per-host state isolation.
- output.py: Formats and displays scan results in multiple formats (text, CSV, JSON) to console or file.
scanners/
- base.py: Abstract base class
Scandefining the scanner interface. Implements shared functionality for banner grabbing across HTTP, SSH, and generic services. - tcp.py:
TCPConnectimplementation—establishes full TCP connections to test port availability. Default, reliable scanning method. - syn.py:
SYNScanimplementation—uses raw SYN packets for lower-overhead scanning. Requires elevated privileges.
models/
- port.py:
Portdata class representing scan results with service metadata (port number, state, banner info). - arguments.py: Argument validation and normalization for command-line flags.
utils/
- network.py: Network helper functions for IP/CIDR/hostname parsing, DNS resolution, and reachability checks.
- validation.py: Input validation for ports, targets, and configuration parameters.
config.py & log.py
- config.py: Centralized configuration constants (timeouts, concurrency limits, log directories).
- log.py: Logging setup with file-based output and configurable log levels.
Component Interaction:
CLI Input → models/arguments → utils/validation → core/scanner → scanners/{tcp,syn} → core/output
↓ ↓
log.py ←──────────────────────────────────────────────────────────────────────→
Scanning Modes
TCP Connect Scan
- Establishes a full TCP connection to determine port availability
- Reliable and portable
- Works without elevated privileges
- Default scanning method
# Example: TCP connect scan
flags = {
"scan_type": "tcp",
"target": "example.com",
"ports": [80, 443]
}
scanner = SCANNER_CLASS[flags["scan_type"]](**flags)
results = await scanner.scan(**flags)
SYN Scan (Optional)
- Sends crafted SYN packets using
Scapyto infer port state - Lower overhead than full connections
- Intended for controlled or lab environments
- Preforms better with large port ranges and many hosts
# Example: SYN connect scan
flags = {
"scan_type": "syn",
"target": "example.com",
"ports": [80, 443]
}
scanner = SCANNER_CLASS[flags["scan_type"]](**flags)
results = await scanner.scan(**flags)
Concurrency Model
- Asynchronous task scheduling using asyncio
- Global concurrency limits to control total in-flight operations
- Per-host concurrency limits to isolate scan behavior
- Non-blocking network operations throughout the pipeline
This design allows the scanner to scale efficiently while maintaining correctness under load.
# Configure concurrency limits in conf.py
DEFAULT_CONCURRENCY_FOR_SCANS = 800
Use Cases
- Studying asynchronous programming and concurrency patterns in Python
- Understanding network scanning tradeoffs and implementation details
- Demonstrating systems-oriented software engineering skills
- Exploring extensible security and networking tooling
Contributing
Suggestions are welcome! Please open an issue or submit a pull request.
License
MIT License - see LICENSE file for details
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 socketscout-1.0.3.tar.gz.
File metadata
- Download URL: socketscout-1.0.3.tar.gz
- Upload date:
- Size: 39.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f4b6b9ce68490560ef4b4ec5fc8f946505a8f8e7bb9bf7aca991357d555213c
|
|
| MD5 |
e957d232a24b97a8df3b55b9198045df
|
|
| BLAKE2b-256 |
551dff03e4567f67d82efc1a0fa4c3f6e9cada9cbac7cac15413465b9f2550c9
|
File details
Details for the file socketscout-1.0.3-py3-none-any.whl.
File metadata
- Download URL: socketscout-1.0.3-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdc48990acd533859f5afa8016d1dcfa1bc533e5cc810efbdea5b17efecc1c57
|
|
| MD5 |
84990976748f95fcba8dc81792d14894
|
|
| BLAKE2b-256 |
4157e36e42ff40a7922fcc375b5d2cf8b25b7650ba977e5828ed6e85ad2129f4
|