6

I need a tool that tells me if a connection to a host is open or not - no data to send or receive. Just if the connect is successful.

Today I use telnet.

$ telnet myhost myport
Trying 192.168.1.99...
Connected to myhost.
Escape character is '^]'.
^[^]
telnet> quit
Connection closed.

But I need to have manual input there. ^] and then also the quit.

I need to check several hosts and that is too much for that.

Any tool out there that does the trick?

If not I need to write 15 lines in perl - whats is ok but I would prefer an existing tool.

3
  • 2
    "If not I need to write 15 lines in perl" - One is sufficient: perl -MIO::Socket::IP -e 'IO::Socket::IP->new(PeerAddr => $ARGV[0], Timeout => 5) or die $!' host:port . For several hosts just put a loop around it Commented 2 days ago
  • Use ping -c3 IP_addr, and parse the error stream.
    – waltinator
    Commented 2 days ago
  • 1
    Is this something you’re looking to run regularly on a schedule? If so, you may want to look into monit, which has built-in support for this type of thing as part of it’s support for monitoring remote hosts and would require zero scripting. Commented yesterday

5 Answers 5

7

An existing tool that does this is nmap, a port scanner:

$ nmap -sT -p 22 192.168.1.1-5
Starting Nmap 7.95 ( https://nmap.org ) at 2024-12-12 22:52 Eastern Standard Time
Nmap scan report for 192.168.1.1
Host is up (0.0039s latency).

PORT   STATE SERVICE
22/tcp open  ssh
MAC Address: 74:AC:B9:12:E1:93 (Ubiquiti)

Nmap done: 5 IP addresses (1 host up) scanned in 1.47 seconds

-sT indicates a TCP portscan - it will SYN, SYN/ACK, ACK and then RST the connection.

-p 22 indicates port 22 will be tested.

It can scan individual IPs, IP ranges (as shown above), IP CIDR blocks, or any combination of these three.

It also supports XML and grep-able output, like such:

$ nmap -sT -p 22 -oG - 192.168.1.1,3,5
# Nmap 7.95 scan initiated Thu Dec 12 22:59:14 2024 as: nmap -sT -p 22 -oG - 192.168.1.1,3,5
Host: 192.168.1.1 ()    Status: Up
Host: 192.168.1.1 ()    Ports: 22/open/tcp//ssh///
# Nmap done at Thu Dec 12 22:59:16 2024 -- 3 IP addresses (1 host up) scanned in 1.45 seconds
6

Bash has native redirection that can check for open ports

host=192.168.1.99
if (echo > "/dev/tcp/${host}/22") >/dev/null 2>&1; then
  echo 'port is open'
else
  echo 'port is closed'
fi

or you can use nc(1):

host=192.168.1.99
if timeout 3 nc -z "$host" 22 2>/dev/null; then
  echo 'port is open'
else
  echo 'port is closed'
fi

You can also use telnet programmatically by piping it to something like grep:

host=192.168.1.99
if telnet "$host" 22 2>&1 | grep -q "Connected"; then
  echo 'port is open'
else
  echo 'port is closed'
fi
4

With this scripts you can check if a host is response on a given port with:

bash's built-in /dev/tcp.

You can use ip address or domains(hostnames).

Script 1 Single Port

#!/bin/bash

HOST_NAME="127.1"
HOST_PORT="80"

if ( (exec 3<>/dev/tcp/${HOST_NAME}/${HOST_PORT}) 2> /dev/null); then
    echo -e "PORT: ${HOST_PORT} | ON"
else
    echo -e "PORT: ${HOST_PORT} | OFF"
fi

Script 2 Range of ports

#!/bin/bash

HOST_NAME="127.1"

for HOST_PORT in {1..1000}
do

if ( (exec 3<>/dev/tcp/${HOST_NAME}/${HOST_PORT}) 2> /dev/null); then
    echo -e "PORT: ${HOST_PORT} | ON"
else
    echo -e "PORT: ${HOST_PORT} | OFF"
fi
done

Script 3 Port 1-65535

#!/bin/bash

HOST_NAME="127.1"
declare -A PORT_ON

for HOST_PORT in {1..65535}
do
    if ( (exec 3<>/dev/tcp/${HOST_NAME}/${HOST_PORT}) 2> /dev/null); then
        PORT_ON[${HOST_PORT}]="ON"
    fi
done

for i in ${!PORT_ON[*]}
do
    echo -e "$i : ${PORT_ON[$i]}"
done

5
  • Note that Bash can be built with support for /dev/tcp disabled, usually for security reasons.
    – Mark
    Commented 22 hours ago
  • @Mark Yes, that's correct, but in most distros, that's not the case by default, but rather enabled ist the Standard.
    – Z0OM
    Commented 22 hours ago
  • @Mark do you mean alpine or minimal bash Like in busybox?
    – Z0OM
    Commented 22 hours ago
  • 1
    I mean Bash built using the --disable-net-redirections configuration parameter. I don't know which distros do this by default, but I do know that it's an option.
    – Mark
    Commented 16 hours ago
  • @Z0OM: Busybox's shell isn't bash at all, it's just ash which I think is mostly just POSIX sh, without any(?) bash extensions. Commented 15 hours ago
1

I believe the simplest way is with netcat's nc -vz <host>. For multiple hosts could be:

#!/bin/bash

hosts=("example.com" "anotherhost.com")
port=1234

for host in "${hosts[@]}"; do
  nc -vz "$host" "$port"
done

A more fancy way with one line:

echo -e "example.com\nanotherhost.com" | xargs -I {} nc -vz {} 80 # or any port

From manual:

-z      Only scan for listening daemons, without sending any data to them.
-v      Produce more verbose output.
0

Another good existing tool is fping

fping is a program like ping which uses the Internet Control Message Protocol echo request to determine if a target host is responding.

fping differs from ping in that you can specify any number of targets on the command-line, or specify a file containing the lists of targets to ping, or generate a range from a subnet on the command-line (the most common form that I generally use).

For example:

fping -a -r 0 -qs -g 192.168.1.99/24
  • -a : show targets that are alive
  • -r n : number of retries (default 3)
  • -q : quiet (don't show per-target/per-ping results). This limits output to live IP's only.
  • -s : print final stats, showing number of pings sent, number of live vs. dead IP's etc.
  • -g : generate target list (only if no -f specified). Specify the start and end IP in the target list, or supply a IP netmask "-g 192.168.1.0 192.168.1.25" or "-g 192.168.1.0/24"
  • "targets" : list of targets to check (if no -f specified)
  • --help for more options...

fping is installable from standard repositories for most distros.

apt-get install fping #Ubuntu: installed from the universe repo pool
zypper install fping #OpenSUSE
... etc.
1
  • 2
    With fping, you cannot scan ports as requested in the question, and if ICMP Echo Requests are blocked, as is standard on all servers and clients in our company, you also won’t receive any response.
    – Z0OM
    Commented yesterday

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .