1

I'm not an expert in shell script by any means. I got the structure idea from another post (Bash script telnet to test multiple addresses and ports) My need is to verify LAN connections between specific hosts and ports via telnet.

The reason for using telnet is the fact that both the LAN and machines are heavily secure and I don't have access to netcat, nmap or /dev/tcp. I'm also no where near comfortable with Python or Pearl to try that route... ( I know silly me, I'll get there though :P ).

The following code works, however for reasons beyond my understanding the while loop iterates only once and no more... :( .

Note: it is important for me to know if the connection failed due to timeout or was refused (port is closed at the endpoint).

Can anyone help me in 1) fixing it and 2) understanding why?

FYI: For anyone else that might have a similar need here's the fully operational updated code for the script. In this case connection refused is being handled as a success (testing firewall rules) which can be changed to failed depending on necessities.

    #!/bin/bash
    path=`pwd`;
    touch $path/test_telnet.out || exit;
    touch $path/success.log || exit;
    touch $path/failed.log || exit;
    echo "10.192.168.1 1200
    10.10.10.2 80
    10.220.2.8 6090
    10.220.2.9 6090" | ( while read host port; do
        telnet $host $port </dev/null > $path/test_telnet.out 2>&1 & sleep 1; kill $!;
        if grep Connected $path/test_telnet.out >/dev/null;
            then
                echo @ $(date +"%b %d %H:%M %Y") $host:$port [ OPEN ] | tee -a $path/success_log.txt;
            elif grep refused $path/telnet_test.txt >/dev/null; then
                echo @ $(date +"%b %d %H:%M %Y") $host:$port [ REFUSED ] | tee -a $path/success_log.txt;
            else
                echo @ $(date +"%b %d %H:%M %Y") $host:$port [ TIMEOUT ] | tee -a $path/failed_log.txt;
        fi;
    cp /dev/null $path/test_telnet.out;
    done
    ) 2>/dev/null #avoid bash messages
Community
  • 1
  • 1
TPatriot
  • 21
  • 1
  • 1
  • 5
  • 2
    If `telnet` operates at all like `ssh` then it is eating the contents of standard input before your loop can loop. Redirect stdin away for the telnet process and see if that helps. – Etan Reisner Apr 01 '15 at 13:55
  • @EtanReisner If I do 'telnet $host $port <> ...' the while iterates, however the '$host $port' inside the telnet does not change value. :( – TPatriot Apr 01 '15 at 15:43
  • I don't understand. The standard input redirection doesn't change the expansion of variables on the shell command line. `telnet` doesn't know there were variables. If redirecting standard input makes the loop continue then `read` will read the next line and set `host` and `port` appropriately so they will work on each time through the loop. Try a simpler case first to make sure you can get it working: `echo .... | while read host port; do echo "host: $host"; echo "port: $port"; done`. – Etan Reisner Apr 01 '15 at 15:45
  • @EtanReisner The variables being echoed inside the `if` change value but not the variables inside the `telnet`, so it keeps doing telnets to the same `host port` while the `echo` prints the `host port` that it's acually supposed to... weird I know... – TPatriot Apr 01 '15 at 16:02
  • There are no variables "in the telnet". You are running `telnet $host $port`. If `echo $host $port` works correctly then so will `telnet $host $post`. But I also just noticed that you appear to be killing the backgrounded sub-shell and not the `telnet` command itself. Is that intentional? – Etan Reisner Apr 01 '15 at 16:08
  • @EtanReisner Noob question here, isn't that `kill $!` going to kill the last ran process? which in this case should be the telnet. Also "in the telnet" might have been a bad way to put it, good thing you understood :) – TPatriot Apr 01 '15 at 16:19
  • `$!` is the last background-ed process. The only background-ed process you have is the sub-shell. So it will either be the sub-shell or nothing (depending on how that interacts exactly) I think. – Etan Reisner Apr 01 '15 at 16:22

2 Answers2

1

As Etan commented, telnet is eating the rest of your input. The fix is to redirect the input for telnet.

Change this:

telnet $host $port > ~/test_con/telnet_test.txt

to this:

telnet $host $port </dev/null > ~/test_con/telnet_test.txt
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    Thank you that along Etan's indication on the background process I edited the line with `telnet $host $port ~/test_con/telnet_test.txt & (sleep 2; kill $!)&` and it's ALIIIIIVE! :) Now to hide that Connected message that randomly appears in the bash :P – TPatriot Apr 01 '15 at 16:45
  • You probably want to redirect telnet's stderr to /dev/null – glenn jackman Apr 01 '15 at 16:49
0

I have added a shell script file and just run this. This script get servers and ports from below list.

for i in {10.21.xxx.yyy,10.21.xxx.yyy,10.23.xxx.yyy};
do
        for j in {5501,5502,5503,5504,7701,7702,7703,7704,5551,5552,5553,7771,7772,7773};
        do
                (echo > /dev/tcp/${i}/${j}) > /dev/null 2>&1 && echo "${i}:${j} :: it's getting connected" || echo "${i}:${j} :: it's not connecting"
        done
done
Anand Varkey Philips
  • 1,811
  • 26
  • 41