Scan is a small web service for recording and displaying Masscan results.
As of v0.8.1 Scan uses Go modules. Go 1.13 or newer is required to build.
Precompiled binaries for Linux on x86-64 are available on the GitHub releases page.
Both build and runtime require the SQLite libraries installed.
For a Debian system:
sudo apt-get install sqlite3
Or macOS:
brew install sqlite
To generate the scan binary run:
make
This will generate the bindata.go containing static assets and build the binary.
Scan stores results in a SQLite database. The database is automatically created and maintained at startup.
The -data.dir flag (defaults to current directory) tells Scan where to store the database file.
Scan can automatically obtain a TLS certificate for HTTPS using Let's Encrypt.
When the -tls flag is set and a client connects to the HTTPS port, Scan will attempt to automatically obtain a certificate for the hostname being connected to. A DNS hostname must be set up for this to work as Let's Encrypt uses Domain Validation - it needs to connect to the hostname on the HTTP port.
Optionally, you can restrict certificates to a single hostname using the -tls.hostname flag.
By default the data will not be displayed unless a user has been authenticated and authorized.
Authentication is with Google OAuth2. You should create credentials for the application at https://console.cloud.google.com/apis/credentials.
- Click the down arrow next to Create credentials
- Select Web application
- Enter a name for the application (e.g. Scan)
- Add the
/authURI to Authorized redirect URIs (e.g. https://scan.example.com/auth) - Download the JSON file containing the credentials
Scan will look for the credentials file called client_secret.json in the data directory (-data.dir flag) by default. The data directory defaults to the current directory. The credentials file path can be changed with the -credentials flag. If a relative path is specified it's assumed the file is in the data directory.
Users can be managed at the /admin URI.
If you want to authorise users by a G Suite group you must enable the
Admin SDK on the project
and add the group address to the groups table:
INSERT INTO groups (group_name) VALUES ('scan-users@example.com');
If you want to disable authentication use the -no-auth flag.
Results are sent to /results using the POST method. The data is expected to be
a JSON array of Masscan results.
Note that Masscan generates incorrect JSON data. It looks like:
{ "ip": "192.168.0.1", "ports": [ {"port": 80, "proto": "tcp", "status": "open"} ] },
{ "ip": "192.168.0.1", "ports": [ {"port": 443, "proto": "tcp", "status": "open"} ] },
{finished: 1}That is, it is missing the surrounding [ ] and the last line is not valid JSON.
This must be fixed before POSTing the data.
[
{ "ip": "192.168.0.1", "ports": [ {"port": 80, "proto": "tcp", "status": "open"} ] },
{ "ip": "192.168.0.1", "ports": [ {"port": 443, "proto": "tcp", "status": "open"} ] }
]You can fix it by using sed:
sed -e '/,$/h;g;$s/,$//' -e '1i [' -e '$a ]'
And then send it to the server:
curl -H "Content-Type: application/json" -d @data.json https://scan.example.com/results
When automating this you should ensure you don't send empty data to the server.
If the output file is empty you should send an empty JSON array ([]).
Jobs allow you to request nodes to perform specific scans, possibly in addition to the scans they usually do.
Once job data has been submitted, the job list will show a count of how many ports were found.
Nodes fetch the job list from /jobs. This is a JSON document of the form:
[
{
"id": 1,
"cidr": "192.0.2.0/24",
"ports": "1-1024",
"proto": "tcp"
}
]Job data is submitted similar to normal results, but using the PUT method
and appending the job ID to the URI, e.g.
curl -H "Content-Type: application/json" -X PUT -d @data.json https://scan.example.com/results/1
To aid with network debugging after finding open ports, you can submit a
traceroute for the IP. This should be POSTed to /traceroute as multipart
form data, e.g.
curl -F dest=192.0.2.1 -F traceroute=@traceroute.txt https://scan.example.com/traceroute
Prometheus metrics are available to allow you to monitor and alert on Scan results. By default it listens on localhost:3000.
Listening on a separate port from the main web server is deliberate - if you have authentication enabled the metrics data could leak information. If you configure metrics to listen on a public interface you should use IP ACLs to control access.
TLS can be enabled on the metrics server (-metrics.tls) if TLS is also enabled for the main server.


