An exchange I had a few months ago went something like this:
Me: Weird, my requests aren’t getting through, but I can ping the server just fine.
Coworker: I can’t telnet to the port… the firewall is probably blocking your traffic.
Me (to myself): 🤨 wtf does telnet do?
telnet came up again as I was reading Compute Networking: A Top Down Approach. It demonstarted using
telnet to interact with a mail server using SMTP. I decided it was time to dig in to telnet, and the rest of this post will describe what I found.
I’ve included a bunch of links in the Resources section at the bottom, but I’ll summarize what I found.
telnet opens a TCP connection on a specific port and then drops you into a shell where every key you press is sent over the TCP connection to the remote host1. It came before SSH and was the way to connect to remote machines and execute commands. It’s not secure by default so is mostly not used, but it comes in handy to check if a port is accepting TCP connections on a host.
Telnet interface example: NASA JPL Horizons
Aside from checking if a port is accessible, and networking textbooks, the only other time I could remember thinking about
telnet was when I wanted to calculate the phase of the moon and wanted to know its ephemerides2. It turns out NASA provides this as a service called Horizons that has a telnet interface!
If you click this link: telnet://horizons.jpl.nasa.gov:6775 you can play around with it (it opens a terminal window for me with some warning prompts). It can send you email and tell you about positions of all kinds of objects.
Alternatively, as I was poking around about scripting
telnet connections, I came up with the following
expect script (another tool I have just learned about). This script will print out some moon facts:
#!/usr/bin/env expect spawn telnet horizons.jpl.nasa.gov 6775 expect "Horizons> " # The Moon send "301\n" # Exit out expect " Select" send "\n" expect "Horizons> " send "quit"
Some other fun telnet sites are:
telnet towel.blinkenlights.nl– Star Wars: A New Hope in ASCII
telnet mapscii.me- An ASCII map of the world, fully zoomable
HTTP via Telnet
Telnet also allows manually typing out text based protocols that use TCP like HTTP! I couldn’t remember the exact HTTP syntax, so I ran the following
curl command to print out an HTTP request:
$ curl -v google.com/ * TCP_NODELAY set * Connected to google.com (22.214.171.124) port 80 (#0) > GET / HTTP/1.1 > Host: google.com > User-Agent: curl/7.55.1 > Accept: */* > ...
I could recreate this with telnet by typing just the first two lines3:
$telnet google.com 80 Trying 126.96.36.199... Connected to google.com. Escape character is '^]'. GET / HTTP/1.1 Host: google.com HTTP/1.1 301 Moved Permanently Location: http://www.google.com/ Content-Type: text/html; charset=UTF-8 Date: Mon, 11 Jun 2018 00:18:29 GMT Expires: Wed, 11 Jul 2018 00:18:29 GMT Cache-Control: public, max-age=2592000 Server: gws Content-Length: 219 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>301 Moved</TITLE></HEAD><BODY> <H1>301 Moved</H1> The document has moved <A HREF="http://www.google.com/">here</A>. </BODY></HTML>
Ping vs. Telnet
Now the question is, why did
telnet uncover that the firewall was blocking traffic but
ping didn’t? On
ping’s man page, it says:
ping uses the ICMP protocol’s mandatory ECHO_REQUEST datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway
ping operates at the ICMP level, it doesn’t have ports. If a firewall is only filtering based on ports accessed, it wouldn’t drop the ICMP packet, but it would not allow the
telnet connection to succeed.
- man page
- source code
- Where does most firewall enforcement happen? Is it slotted somewhere in between IP and TCP/UDP? Or does this firewall just happen to not block ICMP Echo from ping?
- How was SSH developed and adopted? Were most remote connections like the Horizons interface or was there a something more similar to how we use SSH today?
I checked this out by doing
telnet google.com 80while running
sudo tcpdump "port 80"and seeing every key I press get emitted as a line in
Typing just the first line followed the redirect and gave the actual contents of google.com, HTML, JS and all. This is the same output if I had
curlfollow redirects with