Here we gonna discuss several tools to test the TCP Connection, their pros and cons.
Many of you might thing OK telnet, curl and nc, what you wanna discuss.
Well you are not always granted rights to install and some tools migth not be installed.
In other cases you want to be able to run in loop which with telnet would be problematic.
All the knowledge described below are used in my test_tcp script you can find here: test_tcp
So let's see:
telnet
Starting with telnet. This is most used and example bellow clearly shows the usage.
However, telnet is not installed in most modern linux systems.
root@judo:/media/nas# telnet 10.0.0.101 21 Trying 10.0.0.101... telnet: Unable to connect to remote host: No route to host root@judo:/media/nas# telnet 10.0.0.33 23 Trying 10.0.0.33... telnet: Unable to connect to remote host: Connection refused root@judo:/media/nas# telnet 10.0.0.33 22 Trying 10.0.0.33... Connected to 10.0.0.33. Escape character is '^]'. SSH-2.0-OpenSSH_8.0 ^C
Howevet even it's not trivial it can be used in scripts.
g33k@judo:~$ echo -n '\035\nquit' | timeout 5 telnet 10.0.0.33 22 Trying 10.0.0.33... Connected to 10.0.0.33. Escape character is '^]'. SSH-2.0-OpenSSH_8.0 Connection closed by foreign host. g33k@judo:~$ echo -n '\035\nquit' | timeout 5 telnet 10.0.0.33 23 Trying 10.0.0.33... telnet: Unable to connect to remote host: Connection refused
curl
cURL is designed as command line network swiss knife. Support lots of protocols and let you download upload files via or work with APIs.
It also supports telnet protocol se we can use it to test connectivity.
It's also installed in most modern linux systems so the only problem is again that it's problematic to use it non-interactivelly in script (mainly to figure success).
root@judo:/media/nas# curl telnet://10.0.0.101:21 curl: (7) Failed to connect to 10.0.0.101 port 21: No route to host root@judo:/media/nas# curl telnet://10.0.0.33:23 curl: (7) Failed to connect to 10.0.0.33 port 23: Connection refused root@judo:/media/nas# curl telnet://10.0.0.33:22 SSH-2.0-OpenSSH_8.0 ^C
nc(netcat)
Netcat is also known as hackers network swiss knife. But it's not installed by default in most systems and because of it usage as part of the reverse shalls and backdoors is not allowed to be installed by security teams. So even if you can install it might disapear from system sooner or later.
However it's perfect for use in scripts, It's easy non interactive an give you nice error message.
root@judo:/media/nas# nc -z -v -n 10.0.0.33 23 (UNKNOWN) [10.0.0.33] 23 (telnet) : Connection refused root@judo:/media/nas# nc -z -v -n 10.0.0.101 23 (UNKNOWN) [10.0.0.101] 23 (telnet) : No route to host root@judo:/media/nas# nc -z -v -n 10.0.0.101 22 (UNKNOWN) [10.0.0.101] 22 (ssh) open
bash
Newer versions of bash have this in-build feature which you can be used to test TCP connectivity, it's also cool because it's non interactive and perfect for scripts.
So what is the problem, well bash is consider non POSIX and hence some poorist remove it from the system, such example might be some debian distros, or debian based embedded systems and appliances.
timeout $TIMEOUT_SECONDS bash -c "cat < /dev/null > /dev/tcp/${TEST_HOST}/${PORT}" &> /dev/null echo $?
root@judo:/media/nas# timeout 5 bash -c "cat < /dev/null > /dev/tcp/10.0.0.33/23" &> /dev/null root@judo:/media/nas# echo $? 1 root@judo:/media/nas# timeout 5 bash -c "cat < /dev/null > /dev/tcp/10.0.0.33/22" &> /dev/null root@judo:/media/nas# echo $? 0
openssl
What? Yes we can use openssl client to check connectivity. Because if you are checking ssl well first you need to connect.
And even though there is no SSL at destination port, well it tells you CONNECTED or give error as you can see in examples below.
Also you find it installed in most of the systems.
So with bit of redirections and grep you have noninteractive TCP tester which can be used in scripts.
root@judo:/media/nas# openssl s_client -verify_return_error -connect 10.0.0.101:9997 &> >(grep -E "connect:errno|CONNECTED") CONNECTED(00000003) root@judo:/media/nas# openssl s_client -verify_return_error -connect 10.0.0.101:21 &> >(grep -E "connect:errno|CONNECTED") connect:errno=113 root@judo:/media/nas# openssl s_client -verify_return_error -connect 10.0.0.33:23 &> >(grep -E "connect:errno|CONNECTED") connect:errno=111
Examples:
root@judo:/media/nas# openssl s_client -verify_return_error -connect 10.0.0.101:9997 CONNECTED(00000003) write:errno=0 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 283 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---
root@judo:/media/nas# openssl s_client -verify_return_error -connect 10.0.0.33:23 140043327092032:error:0200206F:system library:connect:Connection refused:../crypto/bio/b_sock2.c:110: 140043327092032:error:2008A067:BIO routines:BIO_connect:connect error:../crypto/bio/b_sock2.c:111: connect:errno=111
root@judo:/media/nas# openssl s_client -verify_return_error -connect 10.0.0.101:21 140261272417600:error:02002071:system library:connect:No route to host:../crypto/bio/b_sock2.c:110: 140261272417600:error:2008A067:BIO routines:BIO_connect:connect error:../crypto/bio/b_sock2.c:111: connect:errno=113
wget
Oh so if I can use openssl to test tcp connectivity then I can use basically any program which is using tcp protocol and havecan run without need of user intervention, right?
Yes sure, wget will tell you it can connect but have not index.html when you test connectivity, but you know TCP connectivity to port 22 is fine.
root@judo:/media/nas# wget -t 1 http://10.0.0.33:22 --2022-07-09 10:48:42-- http://10.0.0.33:22/ Connecting to 10.0.0.33:22... connected. HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9 Length: unspecified Saving to: ‘index.html.2’ index.html.2 [ <=> ] 57 --.-KB/s in 0s 2022-07-09 10:48:42 (2.13 MB/s) - Read error at byte 57 (Connection reset by peer).Giving up. root@judo:/media/nas# wget -t 1 http://10.0.0.33:23 --2022-07-09 10:49:16-- http://10.0.0.33:23/ Connecting to 10.0.0.33:23... failed: Connection refused. root@judo:/media/nas# wget -t 1 http://10.0.0.101:21 --2022-07-09 10:49:22-- http://10.0.0.101:21/ Connecting to 10.0.0.101:21... failed: No route to host. root@judo:/media/nas#