We all been in the situation where we need to understand if a port on a server can be reached, reachability is unsure, and no port scanner such as nmap is available, nor install is allowed.
ping
Please mind this is not about if the host in general can be reached. This generally can be done using the ping
command. Although it should be considered that ping generally uses a specific protocol (ICMP), which is different from the generally used TCP protocol for encrypted and unencrypted communication.
TCP port scanning
The port state of a TCP port on an host can be determined if the openssl
utility is available on the machine that needs to connect to the host. Nowadays, SSL/encryption almost always is a requirement, which makes it very likely the openssl package is installed, which contains the openssl
utility.
A TCP port on a host can have 3 principal states:
- Unreachable/firewalled If a host or hostname is specified that does not exist, then obviously it's impossible to connect to a port on that host, and there will be no communication back. The same happens when a host or hostname does exist, but is unreachable, or if the entire host (all ports) or the specific port is firewalled.
- Open If a host or hostname does allow communication with a specific port, and an executable is listening on that port, then communication can happen.
- Closed If a host or hostname does allow communication with a specific port, but no executable is listening on that port, then communication with that executable cannot happen. In such a case, the TCP/IP (network) stack will respond to the request by refusing the connection.
Now with these 3 states in mind, you can use the openssl
utility to obtain the exact state of a hostname and port combination. This is how that looks like:
Unreachable
➜ openssl s_client -connect 192.168.66.79:80
If a host is unreachable, it will not, and cannot respond. In that case, the utility will not produce any response for a long time, because it's waiting for the response. Eventually it will time out:
connect: Operation timed out
connect:errno=60
Open
➜ openssl s_client -connect 192.168.66.80:7000
CONNECTED(00000003)
...much more output related to SSL...
If a host is reachable, and has an executable listening on the port on the port specified, it will be able to connect, which is what the CONNECTED(00000003)
message means. This means the port is open, and can interact with the executable.
All the other output that follows is related to SSL, and might or might not be relevant. It is not for determining the port state.
Closed
➜ openssl s_client -connect 192.168.66.80:7001
connect: Connection refused
connect:errno=61
If a host is reachable, but has no executable listening on the port specified, the message will specify 'Connection refused'.
Top comments (2)
why not use nc -vz ?
I did find that nc / netcat is not always available by default, and even less so on more limit machines, whilst openssl generally is available nowadays. Also, the options to use are reasonably simple, and the output is reasonably easy to understand.