3

Referencing this question: automating telnet session using bash scripts

I am trying to capture the time it takes for a remote host to timeout. Let's say it's 10 seconds. By hand, I can launch time telnet host port input some commands and then do nothing and after 10 seconds time's output will hold my needed time.

While, in a script, the issue is that using this solution:

{ echo "command"; } | time telnet host port

when the pipes end, it sends an EOF and telnet closes immediately. I can solve this by adding a sleep n as my last piped command, but then everything hangs for that timeout (which can be more than the actual server timeout).

Just to explain what I'm trying to do let's borrow Google's help. I want my time output to be 5 minutes, which is what Google seems to use as timeout. Instead:

{ echo "GET / HTTP/1.1"; echo "Host: www.google.com"; echo "Connection: keep-Alive"; echo ""; echo ""; } | time telnet www.google.com 80 2>&1

Gives 0 - wrong (EOF is sent immediately)

{ echo "GET / HTTP/1.1"; echo "Host: www.google.com"; echo "Connection: keep-Alive"; echo ""; echo ""; sleep 10; } | time telnet www.google.com 80 2>&1

Gives 10 - wrong

{ echo "GET / HTTP/1.1"; echo "Host: www.google.com"; echo "Connection: keep-Alive"; echo ""; echo ""; sleep 1; } | time telnet www.google.com 80 2>&1

Gives 1 - wrong

{ echo "GET / HTTP/1.1"; echo "Host: www.google.com"; echo "Connection: keep-Alive"; echo ""; echo ""; sleep 900; } | time telnet www.google.com 80 2>&1

Gives 900 - wrong (here I would expect the telnet to stop given the remote host sends a kill, but instead the sleep wins)

So, how can I solve this? Thanks!

JoeSlav
  • 4,479
  • 4
  • 31
  • 50

2 Answers2

2

telnet is meant for interactive use. I recommend to use netcat:

time netcat -q-1 www.google.com 80 <<EOF
GET / HTTP/1.1
Connection: keep-alive
Host: www.google.com


EOF

Alternatively you may use /dev/tcp if your script runs in bash:

#!/bin/bash
host="www.google.com"
port=80    
time {
    exec 3<>"/dev/tcp/${host}/${port}"
    cat <<EOF - >&3
GET / HTTP/1.1 
Host: ${host}
Connection: keep-alive


EOF
    cat <&3
}
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Thanks for the pointer! Does that command actually gives you 5 minutes as the result of time ? to me it breaks immediately. By the way, its "GET / HTTP/1.1" – JoeSlav Feb 02 '18 at 08:52
  • Why should it be 5 minutes? – hek2mgl Feb 02 '18 at 09:14
  • Because with our Google example, that is what Google is doing. If you send those commands Google will reply and then wait for 5 minutes and then close the connection. The "5 minute" is what I'm trying to measure. If you try to telnet you can see this behavior: https://pastebin.com/uzad7QRm. Perhaps it's some netcat option.. – JoeSlav Feb 02 '18 at 09:31
  • Thanks a lot. This approach will make it impossible to test HTTPS with openssl but it's definitely nicer than using expect! – JoeSlav Feb 02 '18 at 14:18
2

Although I don't overly like it, this seems to work:

( time { echo "set timeout 400"; echo "spawn telnet www.google.com 80"; 
         echo 'send "GET / HTTP/1.1\r"'; echo "send \"Host: www.google.com\r\""; 
         echo 'send "Connection: keep-alive\r"'; echo 'send "\r"'; 
         echo "expect { eof exit timeout exit }"; } | expect ) 2>&1

The above outputs both the HTTP headers/body and the time results, so both can be manipulated.

By the way, the above works for HTTP. For HTTPS you have to use openssl, but the same system works.

JoeSlav
  • 4,479
  • 4
  • 31
  • 50