Search code examples
bashshellunixtelnetfirewall

Bash script telnet to test multiple addresses and ports


I am required to test at least 130 ip addresses and ports. I am hoping to write a bash script such that it reads the ip address and ports from an input file.

I have the following

while read line
do
telnet $line >> $2
done < $1

This is a crappy code as it cannot determine whether its connected or failed, and I have to rely on its auto escape character to disconnect from a connection.

How can I improvise this such that it updates $2 with the status quickly? I am working on Redhat and do not have netcat or expect installed..


Solution

  • As other stackoverflower's said, I would recommend using nmap or netcat if avilable. However, if you cannot use those software, you can use bash's builtin /dev/tcp/<host>/<port> instead.

    http://www.gnu.org/software/bash/manual/bashref.html#Redirections

    I could'nt figure out which version of bash you are using, but /dev/tcp/... seems to implemented since some old bash.

    #!/bin/bash
    echo "scanme.nmap.org 21
    scanme.nmap.org 22
    scanme.nmap.org 23
    scanme.nmap.org 79
    scanme.nmap.org 80
    scanme.nmap.org 81" | \
    while read host port; do
      r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
      if [ "$r" = "0" ]; then
        echo $host $port is open
      else
        echo $host $port is closed
      fi
    done
    

    This produces

    scanme.nmap.org 21 is closed
    scanme.nmap.org 22 is open
    scanme.nmap.org 23 is closed
    scanme.nmap.org 79 is closed
    scanme.nmap.org 80 is open
    scanme.nmap.org 81 is closed
    

    UPDATED: The following can do timeout. Although it may seem little tricky, idea is just to kill the child process after some timeout.

    Bash script that kills a child process after a given timeout

    #!/bin/bash
    echo "scanme.nmap.org 80
    scanme.nmap.org 81
    192.168.0.100 1" | (
      TCP_TIMEOUT=3
      while read host port; do
        (CURPID=$BASHPID;
        (sleep $TCP_TIMEOUT;kill $CURPID) &
        exec 3<> /dev/tcp/$host/$port
        ) 2>/dev/null
        case $? in
        0)
          echo $host $port is open;;
        1)
          echo $host $port is closed;;
        143) # killed by SIGTERM
           echo $host $port timeouted;;
         esac
      done
      ) 2>/dev/null # avoid bash message "Terminated ..."
    

    this produces

    scanme.nmap.org 80 is open
    scanme.nmap.org 81 is closed
    192.168.0.100 1 timeouted
    

    since 192.168.100 does not exist in my local network.