Fast CLI port scanner written in Rust. Scans TCP ports on hosts, hostnames, or across entire subnets. Async, concurrent, cross-platform.
- Multiple targets: scan several hosts, subnets, and hostnames in one command
- Target file: load hosts from a file (
-i hosts.txt) - DNS resolution for hostnames
- Flexible ports: single (
80), list (22,80,443), range (1-1024), mixed, or top-N - Service detection: identifies well-known services by port number
- Banner grabbing: reads service version banners from open ports
- HTTP probe: active banner grabbing for web servers
- Host discovery: TCP ping check before scanning (
--ping) - Exclude hosts: skip specific IPs or subnets (
--exclude) - Scan profiles:
--profile fast,full,stealth - Retry: retry timed-out connections (
--retry) - Rate limiting: cap connections per second (
--rate) - Colored terminal output
- Multiple output formats: text, JSON, CSV
- Auto-detect format:
-o scan.jsonsaves JSON,-o scan.csvsaves CSV - Multiple outputs:
-o scan.txt -o scan.json -o scan.csvin one command - Diff mode: compare scans to detect changes (
--diff) - Quiet mode: machine-friendly output for pipelines (
-q) - Progress bar: visual scan progress with ETA
- Cross-platform: Linux and Windows binaries from a single Docker build
Download the latest archive for your platform from Releases:
- Linux:
rscan-vX.Y.Z-linux-amd64.tar.gz - Windows:
rscan-vX.Y.Z-windows-amd64.zip
# Linux
VERSION=v0.7.2 # check latest at https://github.com/idesyatov/rscan/releases
curl -L https://github.com/idesyatov/rscan/releases/download/${VERSION}/rscan-${VERSION}-linux-amd64.tar.gz -o rscan.tar.gz
tar xzf rscan.tar.gz
sudo mv rscan-${VERSION}-linux-amd64/rscan /usr/local/bin/
# Windows (PowerShell)
$VERSION = "v0.7.2" # check latest at https://github.com/idesyatov/rscan/releases
Invoke-WebRequest -Uri "https://github.com/idesyatov/rscan/releases/download/$VERSION/rscan-$VERSION-windows-amd64.zip" -OutFile rscan.zip
Expand-Archive rscan.zip -DestinationPath .
# Binary is in rscan-$VERSION-windows-amd64\rscan.exeRequires Docker — no Rust toolchain needed.
docker build -t rscan-builder .
# Linux / macOS
docker run --rm -v ./dist:/dist rscan-builder
# Windows (PowerShell)
docker run --rm -v "${PWD}/dist:/dist" rscan-builderRebuild from scratch:
docker build --no-cache -t rscan-builder .Binaries appear in ./dist/:
dist/
linux/rscan # ELF x86_64
windows/rscan.exe # PE x86_64
rscan <TARGET>... [OPTIONS]
rscan -i targets.txt [OPTIONS]Target:
| Option | Description |
|---|---|
<TARGET>... |
IP, CIDR, or hostname (multiple allowed) |
-i, --target-file <FILE> |
Read targets from file |
--exclude <HOSTS> |
Exclude IPs/CIDRs (comma-separated) |
Ports:
| Option | Default | Description |
|---|---|---|
-p, --ports <PORTS> |
1-1024 |
Ports: 80, 22,80,443, 1-1024 |
--top <N> |
— | Scan top N most common ports |
Scan:
| Option | Default | Description |
|---|---|---|
-t, --timeout <MS> |
1000 |
Connection timeout in milliseconds |
-j, --threads <NUM> |
100 |
Max concurrent connections |
-b, --banner |
— | Grab service banners |
--ping |
— | Discover alive hosts first |
--retry <N> |
0 |
Retry timed-out ports N times |
--rate <N> |
— | Max connections per second |
Profile:
| Option | Description |
|---|---|
--profile fast |
Top 100 ports, 200ms timeout, 200 threads |
--profile full |
All 65535 ports, 2s timeout |
--profile stealth |
Top 20, 3s timeout, 10 threads, 10 conn/s |
Output:
| Option | Description |
|---|---|
--json |
Output JSON to stdout |
-q, --quiet |
Output only ip:port (for scripting) |
--diff <FILE> |
Compare with previous scan (JSON) |
-o, --output <FILE> |
Save to file (format by extension: .txt, .json, .csv) |
-v, --verbose |
Show progress and details |
# hosts.txt — one target per line
# Comments start with #, blank lines are ignored
192.168.1.1
192.168.1.0/24
10.0.0.1
google.com
example.com
Scan from a target file:
rscan -i hosts.txt -p 80,443Combine file and CLI targets:
rscan 10.0.0.1 -i hosts.txt --top 20 -bScan multiple targets:
rscan 192.168.1.1 10.0.0.1 google.com -p 80,443Fast scan with banner grabbing:
rscan 192.168.1.0/24 --profile fast -bFull scan of all ports:
rscan 10.0.0.1 --profile fullStealth scan:
rscan 10.0.0.0/24 --profile stealthScan subnet with ping discovery, excluding gateway:
rscan 192.168.1.0/24 -p 22,80,443 --ping --exclude 192.168.1.1Rate-limited scan with retries:
rscan 10.0.0.0/24 --top 20 --rate 500 --retry 2Export to all formats in one command:
rscan google.com --top 50 -b -o scan.txt -o scan.json -o scan.csvQuiet mode for scripting:
rscan 10.0.0.0/24 -p 80 -q | xargs -I{} curl -s http://{}Diff mode — detect changes:
# Save baseline
rscan 192.168.1.0/24 --top 20 -o baseline.json
# Later — compare
rscan 192.168.1.0/24 --top 20 --diff baseline.jsonJSON output:
rscan google.com --top 10 --json -b[
{
"host": "142.250.185.14",
"port": 80,
"state": "open",
"service": "http",
"banner": "HTTP/1.1 200 OK"
},
{
"host": "142.250.185.14",
"port": 443,
"state": "open",
"service": "https"
}
]| Profile | Ports | Timeout | Threads | Rate |
|---|---|---|---|---|
| default | 1-1024 | 1000ms | 100 | — |
| fast | top 100 | 200ms | 200 | — |
| full | 1-65535 | 2000ms | 100 | — |
| stealth | top 20 | 3000ms | 10 | 10/s |
Profiles set defaults — explicit flags still override them.
- Collects targets from CLI arguments and/or target file (
-i) - Resolves hostnames via DNS, expands CIDRs
- Applies host exclusions (
--exclude) - Optionally discovers alive hosts via TCP ping (
--ping) - Selects ports: explicit, range, or top-N by frequency
- Scans each IP × port with async TCP connect, retries, and rate limiting
- Optionally reads service banners from open ports
- Identifies services by port number
- Outputs colored results to terminal and/or saves to files
- Rust — compiled, zero-cost abstractions
- tokio — async runtime for concurrent scanning
- clap — CLI argument parsing
- colored — terminal colors
- serde — JSON serialization
- Docker — reproducible cross-compilation via mingw-w64