Examining Multiple Ports When Running NetCat (nc)

I am using -w 1 below to limit timeouts to 1 second. I also use -v for the reasons mentioned in comments. I used -n to refuse delays for reverse DNS lookups...

[mpenning@tsunami ~]$ for i in $(echo "172.16.1.1,172.16.1.5"|tr "," "\n"); do echo -e "22\n80\n443\n8080" | xargs -i nc -w 1 -zvn $i {}; done
(UNKNOWN) [172.16.1.1] 22 (ssh) open
(UNKNOWN) [172.16.1.1] 80 (www) : Connection timed out
(UNKNOWN) [172.16.1.1] 443 (https) open
(UNKNOWN) [172.16.1.1] 8080 (http-alt) : Connection timed out
(UNKNOWN) [172.16.1.5] 22 (ssh) open
(UNKNOWN) [172.16.1.5] 80 (www) open
(UNKNOWN) [172.16.1.5] 443 (https) open
(UNKNOWN) [172.16.1.5] 8080 (http-alt) : Connection refused
[mpenning@tsunami ~]$

If you like GNU Parallel as much as I do, try this:

parallel nc -vz host ::: 22 80 443 8080

Sample Output:

Connection to foo.example.com 22 port [tcp/ssh] succeeded!
nc: connect to foo.example.com port 80 (tcp) failed: Connection refused
nc: connect to foo.example.com port 443 (tcp) failed: Connection refused
nc: connect to foo.example.com port 8080 (tcp) failed: Connection refused

This method is also faster in some cases since it's testing connecting to ports in parallel, not serial. Specifically this would be where the remote host (or intervening firewall) discards your packets to stay stealth (as opposed to a successful connection or forceful reject).

Tip: in most Linux distros, you can install parallel from your package manager.

Update: With parallel, this generalizes super well to cover an often needed case of multiple hosts x multiple ports. The following example uses parallel to iterate over the cross product, so you don't need to write any nested loops.

parallel nc -vz ::: host1 host2 host3 ::: 22 80 443 8080

Output:

Connection to host1 22 port [tcp/ssh] succeeded!
Connection to host1 80 port [tcp/http] succeeded!
Connection to host1 443 port [tcp/https] succeeded!
nc: connect to host1 port 8080 (tcp) failed: Connection refused
Connection to host2 22 port [tcp/ssh] succeeded!
nc: connect to host2 port 80 (tcp) failed: Connection refused
nc: connect to host2 port 443 (tcp) failed: Connection refused
nc: connect to host2 port 8080 (tcp) failed: Connection refused
Connection to host3 22 port [tcp/ssh] succeeded!
nc: connect to host3 port 80 (tcp) failed: Connection refused
nc: connect to host3 port 8080 (tcp) failed: Connection refused
nc: connect to host3 port 443 (tcp) failed: Connection refused

Just as the previous example, parallel executes the connection tests in parallel. Note, the default parallelism is how many threads your system have, but can override easily with the -j switch to any value. You could easily get away with parallel -j 50 ... or even higher since testing sockets is not a CPU intensive task.