Quick way to scan for opened ports on local network according to a list

1

How can I quickly find out whether port 80 is open/listening on a server via a bash script?

Normally on all workstations the daemon is running, but sometimes it fails. I use the following command to check if an IP address has an open port. I would like to be able to do this for every line in a file without having to manually type it each time.

 nc -zw3 10.101.0.13 80 && echo "opened" || echo "closed"

The list file looks like this, where 3333 and 3334 are strings after $ip;

10.101.0.13; 3333
10.101.0.15; 3334
10.101.0.17; 4143
10.101.0.21; 1445
10.101.0.27; 2443
10.101.0.31; 2445
10.101.0.47; 3443
10.101.0.61; 3445

I have to separate open ports from closed ones, so I'll have a list of failed servers that will have to be fixed.

I tried something like this without success:

while IFS=";" read ip port ; do nc -zw3 "$ip" "$port" && echo "$ip:$port => opened" || echo "$ip:$port =>  closed" ; done < list.txt

while IFS=";" read ip port ; do nc -zw3 "${ip}" "${port}" && echo "${ip}:${port} => opened" || echo "${ip}:${port} =>  closed" ; done < list.txt

Mikhael Djekson

Posted 2014-01-29T08:03:20.090

Reputation: 148

The wait flag isn't available/won't work as you intend here for every version of [tag:nc], can you try running one of your nc -zw3 in shell with one open and one closed port and see if it really returns after 3 seconds? – None – 2014-01-29T09:41:10.617

yes, with opened one i get response within 10 miliseconds Connection to localhost 80 port [tcp/http] succeeded! and with bad one, within the same 10 miliseconds i get empty line. – Mikhael Djekson – 2014-01-29T15:52:14.343

What you describe works perfectly for me. Why do you say it's not working? – terdon – 2014-01-29T16:26:10.840

Answers

1

Here's the most basic and efficient Nmap command to do what you want (and nothing more):

#!/bin/sh
# Gather the IPs to scan for each port
perl -lanF\; -e'push @{$p{$F[1]}}, $F[0];END{$,=" ";while(($x,$y)=each%p){print $x,@$y}}' input.txt | while read port ips; do
  # Scan the appropriate port for each set of IPs
  nmap -Pn -n -oG - -p $port $ips |\
  # Put the open ones into open.txt and the closed/filtered into closed.txt
  awk 'OFS=":";$4~/^Ports:/{if(/open/){print $2,'$port' >> "open.txt"}else{print $2,'$port' >> "closed.txt"}}'
done

Unfortunately, Nmap does not have a built-in way to scan only some ports on some IPs and other ports on other IPs, otherwise this could be a lot simpler.

bonsaiviking

Posted 2014-01-29T08:03:20.090

Reputation: 1 563

1

Easiest thing is to install nmap from the repos, then do:

   awk -F ";" '{print $1}' data | xargs -L 1 nmap -p 80

where data is the file with the IP addresses to scan.

Edit:

If it is true,as @pabouk suggests below, that the number following the IP address is port to be scanned, then you can achieve the desired scan as follows:

   awk -F ";" '{print "nmap " $1 " -p" $2}' data | xargs -I % sh -c '%'

If you wish scan for both port 80, and the port read from the file, you can do it with this command:

   awk -F ";" '{print "nmap " $1 " -p80," $2}' data | xargs -I % sh -c '%'

If nmap is thought to produce too much output, the follwoing command will do:

   awk -F ";" '{print "nmap -oG - " $1 " -p80," $2}' data | xargs -I % sh -c '%' | grep Ports

MariusMatutiae

Posted 2014-01-29T08:03:20.090

Reputation: 41 321

You are ignoring the port numbers from the data file. – pabouk – 2014-02-01T18:42:12.540

I understand it that each line of the file contains this pair to scan: IP_address; port. Also nmap produces a lot of (in this case superfluous) output with every run. – pabouk – 2014-02-01T18:48:12.377

It still produces a lot of junk output. You could append: "| grep tcp | sort" (no quotes) to get rid of (most of) the junk and even sort the output according to port. – ecube – 2014-02-01T19:25:56.343

Yes, nmap -oG - ... | grep Ports: is what I tested just a moment ago. :) – pabouk – 2014-02-01T19:35:10.060

1

#!/bin/bash
N=0
cat $1 | while read line
do
    N=$((N+1))
    nc -zw3 $( echo $line | tr -d ';' ) && echo -e "OPEN\t$( echo $line | sed 's/; /:/g' )" || echo -e "CLOSED\t$( echo $line | sed 's/; /:/g' )" 
done

Usage: ./script.sh Scans the file specified and tests if each "$ip; $port" is open or closed.

If you want sorted output: ./script.sh | sort

No installation necessary.

As one line that you can paste into your terminal without having to make a shell script:

N=0; cat FILENAME | while read line; do; N=$((N+1)); nc -zw3 $( echo $line | tr -d ';' ) && echo -e "OPEN\t$( echo $line | sed 's/; /:/g' )" || echo -e "CLOSED\t$( echo $line | sed 's/; /:/g' )"; done

ecube

Posted 2014-01-29T08:03:20.090

Reputation: 558