Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Using Curl to Create a Telnet Connection

using-curl-to-create-a-telnet-connection.jpg

This can be really handy to confirm a service is running when you don't have telnet or that service's CLI tool installed.

Quick Jump:

It’s surprisingly easy, you can run curl -v telnet://$host:$port. The -v (verbose) flag is optional but without that you’ll miss out on seeing details about creating the connection.

Here’s an example:

$ curl -v telnet://example.com:80
*   Trying 93.184.215.14:80...
* Connected to example.com (93.184.215.14) port 80 (#0)

Now you can type this out and hit enter twice:

GET / HTTP/1.1
Host: example.com

You should get back a bunch of response headers and the HTML response.

If you plan to make an HTTP request this way it would make a lot more sense just to use curl such as curl https://example.com but using telnet can be really handy to test a TCP connection for a service in some cases.

Before we get into use cases for this, I know when writing automated tests I like to test failure cases. For example what’s the expected output when the host is unreachable or the host is reachable but the port isn’t available?

Here’s what happens when the host is unreachable:

$ curl -v telnet://this.will.not.exist.localhost.test:55555
* Could not resolve host: this.will.not.exist.localhost.test
* Closing connection 0
curl: (6) Could not resolve host: this.will.not.exist.localhost.test

Here’s what happens when the host is reachable but the port isn’t available:

$ curl -v telnet://localhost:55555
*   Trying 127.0.0.1:55555...
* connect to 127.0.0.1 port 55555 failed: Connection refused
*   Trying ::1:55555...
* connect to ::1 port 55555 failed: Connection refused
* Failed to connect to localhost port 55555 after 0 ms: Connection refused
* Closing connection 0
curl: (7) Failed to connect to localhost port 55555 after 0 ms: Connection refused```

Knowing these outputs could help you troubleshoot something if anything goes wrong.

By the way, if you have an advanced telnet use case you can pass in the --telnet-option flag to curl too.

# Why Would You Do This?

Maybe you’re in a containerized environment where telnet or your service’s CLI tool isn’t available but you do have access to curl. You may also be running that container as a non-root user and have security contexts in place to make the root file system read-only so you can’t install new tools.

For example, you have a Kubernetes cluster running and you want to quickly test running a service like Redis or Memcached in your cluster.

You may want to perform an end to end test to verify that the service comes up and you can interact with it from one of the pods which would demonstrate from a networking perspective everything is working.

Kubernetes does let you configure probes to test a TCP connection on a specific port which verifies something is running on that port:

spec:
  containers:
    - name: "redis"
      readinessProbe:
        tcpSocket:
          port: 6379

But when initially running something for the first time I also like to confirm it’s “really” working. This “really” working test is where using telnet comes into play.

As long as you have curl installed, and have your Kubernetes configs in place such as setting up a Deployment with a Service to expose redis as a valid hostname, you can run:

$ curl -v telnet://redis:6379
*   Trying 172.30.0.3:6379...
* Connected to redis (172.30.0.3) port 6379 (#0)

Then you can run any Redis command such as listing all of the keys:

KEYS *
*3
...

Yay, we just confirmed the service is accessible over the redis hostname and it’s really Redis that’s running because you interacted with the Redis server.

# Testing This with Docker Compose

The above use case mentions Kubernetes but nothing about this is specific to Kubernetes.

If you want to quickly try this out, I have a Flask starter app on https://github.com/nickjj/docker-flask-example which happens to run a web app container as a non-root user and the project uses Redis too.

You could:

  • Up that project
  • Run ./run shell to open a shell in the web container
  • Run curl -v telnet://redis:6379 and enter in KEYS * to see the result

The video below goes into more detail and shows how all of this works.

# Demo Video

Timestamps

  • 0:10 – Making a telnet connection through curl
  • 1:24 – Why would you ever do this?
  • 2:39 – Demoing how it works with Docker Compose
  • 4:55 – What happens when things go wrong?

When was the last time you used telnet? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments