Smap: a port scanner that reads Shodan instead of touching your targets
a drop-in replacement for Nmap powered by shodan.io
At a glance
- What is it?
- It accepts Nmap syntax and produces Nmap output without sending a packet to the target, which is either exactly what you want or a decision that changes what your results mean.
- Who is it for?
- Smap makes sense for a specific and fairly common situation: you need to know which ports are open on a large set of hosts, and you are not authorized to or willing to send probe traffic to them. It gets there at a rate no active scanner can approach, because the work happened before you started.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 57 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The same arguments, a different source of truth
Smap is described as a drop-in replacement for Nmap, and the mechanism is simple to state: it is a passive port scanner built on shodan.io's free API. It does not probe the hosts you name. It asks Shodan what that index already knows about them and renders the answer in Nmap's shapes.
The argument compatibility is real but partial, and the README is specific about where the line falls. Options other than `-p`, `-h`, `-V`, `-o*`, `-iL`, `--concurrency` and `--append-output` are ignored in passive mode. That list is worth reading twice, because it means most of what makes Nmap Nmap, such as service detection scripts, timing templates and version probes, has no effect here.
So the drop-in claim holds at the level of invocation and output, not at the level of behaviour. A script that consumes Nmap's XML will keep working. A script that relied on Nmap's own probing to decide something will not be doing that any more, and nothing in the output format tells you so.
Installing it
Three install paths are documented. Pre-built binaries are linked from the releases page, and the Go install path is a single line, which is the easiest route if you already have a Go toolchain:
go install -v github.com/s0md3v/smap/cmd/smap@latestThere are two AUR packages, `smap-git` which builds from source and `smap-bin` which packages the pre-built binary, and a Homebrew formula.
brew update
brew install smapNote the case difference in the two GitHub paths. The repository is `s0md3v/Smap` with a capital S, while the Go install path and the module declaration in `go.mod` are lowercase `smap`. Go tooling is case sensitive about module paths, and the two forms coexist in the project's own documentation, which is a small trap if you are wiring this into a build script.
The `go.mod` file pins Go 1.25.0 and pulls in `publicsuffix-go` along with `golang.org/x/net` and `golang.org/x/text`. That dependency list is small for a tool that pretends to speak Nmap, which is consistent with a design that mostly formats other people's data.
Targets, ports and the four ways to name a host
Target specification follows Nmap closely. One or more hosts can be given as arguments, or a newline-separated file can be passed with `-iL`. Four formats are documented for the file, and they cover most of what you would put in a scan list.
smap 127.0.0.1 127.0.0.2
smap -iL targets.txtThe default port set is roughly four thousand ports, taken from the list Shodan publishes, and `-p` narrows the display to specific ports or ranges.
smap -p21-30,80,443 -iL targets.txtThat default is the one number to internalize. A four-thousand-port passive scan and a four-thousand-port active scan are not comparable operations: the first asks about ports someone else already probed, and the second sends traffic to each one. Neither is wrong, but they answer different questions, and the passive one inherits whatever Shodan chose to look at rather than a decision you made.
Concurrency defaults to three workers, deliberately low, and can be raised with `--concurrency`. The stated reason is to avoid hitting Shodan too hard, which is a shared-infrastructure constraint rather than a performance one.
Seven output formats and one that carries the extra data
Smap supports seven output formats selected with `-o*`, and a hyphen prints to the terminal.
smap example.com -oX output.xmlThe formats are Nmap's XML, greppable and default formats, an `oA` mode that emits all three at once, `oP` for bare IP and port pairs, `oS` for a Smap-specific format, and `oJ` for JSON. Six of the seven exist so that existing Nmap tooling keeps working.
The seventh is the one with information in it. The README states plainly that Nmap does not scan or display vulnerabilities and tags, so that data is absent from Nmap's formats, and that you should use `-oS` to see it. Vulnerability detection and service fingerprinting are listed as features, and for passive mode they only surface in the custom format. A team that parses `-oX` into a dashboard is silently dropping the two data points that make passive scanning different from an active one.
The --nmap path is the more interesting mode
The 1.0.0-beta release replaced an earlier `--active` flag with `--nmap`, and the change is worth understanding because it is where the project moved. Under `--nmap`, Smap collects the union of ports Shodan reports for the targets, substitutes that for the port range, and then hands the scan to a real Nmap, which handles the scanning and the output.
smap --nmap -Pn -sV --version-light 1.1.1.1Except for `--nmap` and `--concurrency`, the supplied arguments go to Nmap. If you also specify `-p`, the Shodan candidates are limited to that range first. Host-only operations such as `-sL` and `-sn` pass through without passive discovery at all. If Shodan reports no candidate ports, Nmap is not run.
This is a genuinely good design, because it addresses the failure mode of both tools separately. Shodan is unreliable about what is not open, so it is used only to narrow the space. Nmap is reliable about what is open but slow across a wide range, so it only probes what survived the filter.
The README is also candid about the residual risk: because Shodan's data can be stale or incomplete, using it as a port filter can miss open ports. In this mode Smap makes active connections, so the no-contact property of passive mode no longer applies.
What the README concedes
There is a Considerations section, and it is short and specific in a way that is easy to miss. Smap suits you if you want vulnerability detection, a very fast port scan, and no connections to the targets. It suits you if you are willing to accept no IPv6 support, results up to seven days old, and some rare unreliable software detection in passive mode.
Those four concessions line up with how the tool works rather than reading as hedging. Seven days is a property of a third-party index. No IPv6 is a property of that index too. Passive software detection is unreliable because it is inferred from banners observed by someone else's scan rather than probed.
The project also warns that previous versions in a workflow should be tested before updating, because 1.0.0-beta carries minor breaking changes, chiefly the `--active` to `--nmap` rename. GitHub reports 3,300 stars, 321 forks and a single open issue, and the last push was on 2026-08-15, the same day the beta tag was published. The one open issue is consistent with a project whose user base mostly uses the happy path.
Editorial conclusion
Smap makes sense for a specific and fairly common situation: you need to know which ports are open on a large set of hosts, and you are not authorized to or willing to send probe traffic to them. It gets there at a rate no active scanner can approach, because the work happened before you started. The trade is stated in the README itself: data can be up to seven days old, IPv6 is not supported, and passive software detection is unreliable on rare cases. Judge the tool on its own terms and the pairing with `--nmap` is the interesting part, since it takes Shodan's port candidates and then lets a real Nmap do the scanning. Start with `-p` on a single host to see how the output formats compare with what you are used to, and check whether your decisions depend on finding every open port before trusting a scan without `--nmap`.
Frequently asked questions
Does Smap send any traffic to the targets it scans?
Not in passive mode. Smap asks the Shodan API what it already knows about the hosts and formats the result, so no packets reach the targets. The exception is the --nmap flag, which passes the discovered ports to a real Nmap scan and does make active connections.
Is Smap really a drop-in replacement for Nmap?
At the level of invocation and output, largely. It takes the same arguments and supports Nmap's XML, greppable and default output formats. At the level of behaviour, no: in passive mode every option except -p, -h, -V, -o*, -iL, --concurrency and --append-output is ignored.
How old is the data Smap returns?
The README states results can be up to seven days old, because Smap reads from Shodan's existing index rather than scanning. It also notes that passive software detection is unreliable in rare cases and that IPv6 addresses cannot be scanned.
Where do I see vulnerability findings in Smap output?
Not in Nmap's formats. The README states that because Nmap does not scan or display vulnerabilities and tags, that data is missing from the nmap formats, and that the -oS custom Smap format is where it appears.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/s0md3v-smap)