A /16 is 65,536 addresses. Scanning even the top 1000 ports on each from one host is tens of millions of probes, and if any single source pushes that volume it gets slow, throttled, or noticed. Port scanning is the kind of broad, parallel work a fleet is built for. This post covers running pulse, the Crossfyre network engine, across nodes: how to split the range, pick a technique, detect services, pace the scan, and resume a big sweep if it breaks.
Scan only ranges you own or are explicitly authorized to assess. Port scanning is unambiguously active traffic. Confirm the IP ranges are in scope (paid engagement or a program that lists them) before you point pulse at anything.
A baseline pulse scan
pulse takes one or more targets as hosts or CIDR ranges, a port set, and a technique. Port sets can be named shorthands (top-100, top-1000) or explicit ranges and lists. The live TUI streams open ports as they are found.
# Connect scan of the top 1000 ports across a /24 you own,
# with service detection on whatever comes back open.
pulse scan \
--target 10.0.0.0/24 \
--ports top-1000 \
--technique connect \
--tasks 200 \
--timeout 1500 \
--delay 0 \
--service-detection--tasks is concurrent probes, --timeout is how long each waits for an answer (milliseconds), and --delay is an optional pause each slot takes before its next probe. Together they set how hard a single run pushes. On Crossfyre you rarely touch them by hand: the platform paces the fleet for you, which is the point of the sections that follow.
SYN versus connect
pulse offers two techniques, and the choice is a real trade-off, not a default to ignore.
- SYN (half-open). Sends a SYN, reads the SYN/ACK, never completes the handshake. Faster and lighter because connections are never fully established, and it leaves a smaller footprint in application logs. It needs raw-socket privileges, so the node runs it as root.
- Connect (full handshake). Completes a normal TCP connection. No special privileges required, and more reliable through some middleboxes and proxy paths, but slower and more visible because each port is a real, logged connection.
Reach for SYN on large sweeps where speed and a lighter footprint matter and the node has privileges. Use connect when you cannot run privileged, or when egress goes through a proxy chain that only carries full connections.
Split the CIDR across the fleet
The single-source bottleneck goes away when the scan does not run from a single source. Launch a port-scan workflow on Crossfyre and the control plane splits the range into discrete operations and publishes them onto a durable, acknowledged work queue. Each node pulls operations and runs the pulse daemon against its slice, so a /16 is scanned by the whole fleet at once.
- Time drops with node count. A range split across ten nodes finishes in roughly a tenth of the wall-clock time of one node, without any node scanning ten times harder.
- Load spreads across egress. The scan is divided across many nodes instead of pouring out of one box, so a big sweep draws far fewer blocks than the same scan from a single source.
- Egress is yours to place. Each node can route through layered proxy chains and VPN-isolated tunnels, so probes leave from where you choose and never from the host network.
The same spread-not-speed idea from content discovery at scale applies here: Crossfyre gets a big scan done by dividing it across the fleet, not by pushing any one box harder. You add nodes; the platform handles the pacing.
Service detection: from open port to useful finding
An open port is a lead; the service behind it is the finding. With --service-detection, pulse probes open ports to identify the service and version, so the result is "8080: an outdated app server" rather than "8080: open." That context is what lets you triage and is what your report needs.
Service detection adds probes per open port, so it costs more time and noise. A common pattern is two passes: a fast SYN sweep to find what is open across the range, then targeted service detection on the open ports only. Results from both land in the Findings explorer, filterable by host and severity and exportable to CSV, JSON, or Markdown.
Pacing a big sweep, without babysitting it
Push a large range too hard from too few sources and the scan gets throttled or flagged; go too gently and it crawls. Finding that balance by hand, run after run, is tedious and easy to get wrong. This is the part Crossfyre does for you: it splits the range across your nodes and paces the sweep as it runs, so a big scan finishes fast and with far fewer blocks, and you never have to hand-tune it.
The open-source pulse engine still exposes --tasks, --delay, and --timeout if you want to hand-tune a single run. --timeout is the one worth matching to the network in front of you: too short and slow hosts read as closed, too long and the scan waits on dead addresses. Across a fleet, though, the platform takes care of the pacing so you do not have to.
Resume a crashed sweep
Million-probe sweeps get interrupted: a node is reclaimed, a segment goes dark, you pause to retune. pulse persists scan state, so rerunning the same command continues from where it stopped instead of rescanning the whole range. Pass --fresh-start only when you want to discard saved state and begin clean.
Across the fleet it is automatic. Operations sit on the durable queue until a node completes them, so a node that dies mid-sweep has its slice redelivered to a healthy node, and nothing already scanned is repeated. Reserve-then-reconcile billing means you pay for the probes that actually ran, not for the attempt that crashed. See how scans survive a crashed node for the full picture, and meet the engines if you are new to mach, voyage, and pulse.
Enrol a few nodes and fan a port scan across an authorized range that one box could never finish in time.
Start free