Linux test remote port

Efficiently test if a port is open on Linux?

From a bash script how can I quickly find out whether a port 445 is open/listening on a server. I have tried a couple of options, but I want something quick:
1. lsof -i :445 (Takes seconds)
2. netstat -an |grep 445 |grep LISTEN (Takes seconds)
3. telnet (it doesn’t return)
4. nmap , netcat are not available on the server It will be nice to know of a way that doesn’t enumerate first and greps after that.

netstat -lnt (with -t and without -a ) will limit output to listening TCP connections only. It may speed-up a little bit. You can add -4 for IPv4 only if you don’t need IPv6.

I don’t know why lsof is slow for you, but normally it is the best of the solutions you listed. Your netstat solution is not very reliable (you can guess it whenever you use grep ; anyway it returns true if someone is listening on e.g. 4450). telnet and netcat actually attempt to create a connection, which may not always be what you want.

14 Answers 14

A surprise I found out recently is that Bash natively supports tcp connections as file descriptors. To use:

exec 6<>/dev/tcp/ip.addr.of.server/445 echo -e "GET / HTTP/1.0\n" >&6 cat  

I'm using 6 as the file descriptor because 0,1,2 are stdin, stdout, and stderr. 5 is sometimes used by Bash for child processes, so 3,4,6,7,8, and 9 should be safe.

As per the comment below, to test for listening on a local server in a script:

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!" exec 6>&- # close output connection exec 6 

To determine if someone is listening, attempt to connect by loopback. If it fails, then the port is closed or we aren't allowed access. Afterwards, close the connection.

Modify this for your use case, such as sending an email, exiting the script on failure, or starting the required service.

@AmanJain cat waits for EOF or Ctrl-C to quit. You'll need to adjust this for your protocol. BTW are you running this to a remote server?

@AmanJain I've updated it for a local system. You do just want to check if it's listening correct? There isn't any protocol checking, such as requesting a page via http?

if a port is taken, it returns nothing, is there any way to make it say "port is taken by " or smth

This is not a reliable method since not all OS (e.g. ubuntu 16 as I discovered today) are shipped with bash compiled for building the /dev/tcp/IP/PORT tree

I use it with 127.0.0.1 as "remote" address.

this returns "0" if the port is open and "1" if the port is closed

-z Specifies that nc should just scan for listening daemons, without sending any data to them. It is an error to use this option in conjunc- tion with the -l option.

That seems to be the easiest way, thanks. The sample script link is not working anymore though, yet it's quite self-explaining anyways.

Nice! This is much faster than the other answers on a server with many ports open. Returns in

The -z flag is not available in the nmap based ncat which most recent distros ship with: Fedora, Centos, etc. (nmap-ncat-6.01-9.fc18.x86_64)

@Sean unix commands typically return '0' to indicate success and non-zero for failure. So '0' indicates that it successfully connected and non-zero that it didn't connect for some reason. Note, however, that some versions of 'nc' don't support the '-z' argument so stackoverflow.com/a/25793128/6773916 is arguably a better solution.

You can use netstat this way for much faster results:

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/' 
netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/' 

This will output a list of processes listening on the port (445 in this example) or it will output nothing if the port is free.

Actually it is correct syntax but probably you're using Linux and I am on Mac. For Linux use this: netstat -lnt | awk '$6 == "LISTEN" && $4 ~ ".445"'

In order to check for port 80 I needed to use awk '$6 == "LISTEN" && $4 ~ "80$"' . Instead of checking for the dot before the port number with \.80 , I used 80$ . Otherwise, this also matched IP addresses containing .80 and ports starting with 80 such as 8000 .

@PatrickOscity: Good point, but to make this robust to you need to combine both approaches: awk '$6 == "LISTEN" && $4 ~ "\.80$"'

You can use netcat for this.

connects to the server and directly closes the connection again. If netcat is not able to connect, it returns a non-zero exit code. The exit code is stored in the variable $?. As an example,

will return 0 if and only if netcat could successfully connect to the port.

This answer needs more upvotes. nc works perfectly for this case. the /dev/tcp trick is clever, but seems difficult to implement a script with signal interrupts.

nc has the -z flag for this purpose, which doesn't require taking input from /dev/null . There's already an answer using the -z flag above.

@AbeVoelker Not all versions of nc support the -z flag. I am on CentOS 7 and found Tony's solution to be what I needed.

Based on Spencer Rathbun's answer, using bash:

Good, it will suppress "Connection Refused" message. Auto-exits if the service accept the connection without wait forever.

Best solution for services that send no data after a new connection. About 20 times faster than calling netcat. Can be shortened to : &>/dev/null

I'd add a timeout to get a closed result faster: timeout 5s bash -c ': &>/dev/null ' && echo open || echo closed

@user1338062 This happens on an Ubuntu Bionic on Azure against external IP (not localhost or 127.0.0.1 ).

they're listed in /proc/net/tcp.

it's the second column, after the ":", in hex:

> cat /proc/net/tcp sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 10863 1 ffff88020c785400 99 0 0 10 -1 1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1 2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000 1000 0 10562454 2 ffff88010040f7c0 22 3 30 5 3 3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000 1000 0 10701021 2 ffff880100474080 41 3 22 10 -1 4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000 1000 0 10700849 2 ffff880104335440 57 3 18 10 -1 5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000 1000 0 10698952 2 ffff88010040e440 46 3 0 10 -1 6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000 1000 0 9562907 2 ffff880104334740 22 3 30 5 4 7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000 1000 0 10696677 2 ffff880106cc77c0 45 3 0 10 -1 

so i guess one of those :50 in the third column must be stackoverflow :o)

look in man 5 proc for more details. and picking that apart with sed etc is left as an exercise for the gentle reader.

Источник

How to Check Remote Ports are Reachable Using ‘nc’ Command

A port is a logical entity which acts as a endpoint of communication associated with an application or process on an Linux operating system. It is useful to know which ports are open and running services on a target machine before using them.

We can easily list open ports in Linux on a local machine using the netstat or several other Linux commands such NMAP.

In this guide, we will show you how to determine if ports on a remote host are reachable/open using simple netcat (in short nc) command.

netcat (or nc in short) is a powerful and easy-to-use utility that can be employed for just about anything in Linux in relation to TCP, UDP, or UNIX-domain sockets.

# yum install nc [On CentOS/RHEL] # dnf install nc [On Fedora 22+] $ sudo apt-get install netcat [On Debian/Ubuntu]

We can use it to: open TCP connections, listen on arbitrary TCP and UDP ports, send UDP packets, do port scanning under both IPv4 and IPv6 and beyond.

Using netcat, you can check if a single or multiple or a range of open ports as follows. The command below will help us see if the port 22 is open on the host 192.168.56.10:

In the command above, the flag:

  1. -z – sets nc to simply scan for listening daemons, without actually sending any data to them.
  2. -v – enables verbose mode.

The next command will check if ports 80, 22 and 21 are open on the remote host 192.168.5.10 (we can use the hostname as well):
nc -zv 192.168.56.10 80 22 21

It is also possible to specify a range of ports to be scanned:’

For more examples and usage of netcat command, read through our articles as follows.

That’s all. In this article, we explained how to check if ports on a remote host are reachable/open using simple netcat commands. Make use of the comment section below to write back to us concerning about this tip.

Источник

Test if remote TCP port is open from a shell script

I'm looking for a quick and simple method for properly testing if a given TCP port is open on a remote server, from inside a Shell script. I've managed to do it with the telnet command, and it works fine when the port is opened, but it doesn't seem to timeout when it's not and just hangs there. Here's a sample:

l_TELNET=`echo "quit" | telnet $SERVER $PORT | grep "Escape character is"` if [ "$?" -ne 0 ]; then echo "Connection to $SERVER on port $PORT failed" exit 1 else echo "Connection to $SERVER on port $PORT succeeded" exit 0 fi 

I either need a better way, or a way to force telnet to timeout if it doesn't connect in under 8 seconds for example, and return something I can catch in Shell (return code, or string in stdout). I know of the Perl method, which uses the IO::Socket::INET module and wrote a successful script that tests a port, but would rather like to avoid using Perl if possible. Note: This is what my server is running (where I need to run this from) SunOS 5.10 Generic_139556-08 i86pc i386 i86pc

The answer lied with Expect. We wrote a simple script that sends a telnet on the port we needed, with a timeout of 8 seconds. There's plenty of examples to pick from too. We based ours off this post: unix.com/shell-programming-scripting/…

check_tcp from github.com/monitoring-plugins/monitoring-plugins can do this, including entering strings and checking for an expected answer.

18 Answers 18

As pointed by B. Rhodes, nc ( netcat ) will do the job. A more compact way to use it:

That way nc will only check if the port is open, exiting with 0 on success, 1 on failure.

For a quick interactive check (with a 5 seconds timeout):

FWIW, I have completely overhauled my answer with an example, separately applicable to both RHEL 6 and RHEL 7.

on Mac at least, you may need to add -G# to set a connection timeout separate from/in addition to the -w# timeout, which basically functions as a read timeout.

@jolestar You can manually upgrade Ncat on Centos 7 to get the -z option. You may want to consider: unix.stackexchange.com/questions/393762/…

It's easy enough to do with the -z and -w TIMEOUT options to nc , but not all systems have nc installed. If you have a recent enough version of bash, this will work:

# Connection successful: $ timeout 1 bash -c 'cat < /dev/null >/dev/tcp/google.com/80' $ echo $? 0 # Connection failure prior to the timeout $ timeout 1 bash -c 'cat < /dev/null >/dev/tcp/sfsfdfdff.com/80' bash: sfsfdfdff.com: Name or service not known bash: /dev/tcp/sfsfdfdff.com/80: Invalid argument $ echo $? 1 # Connection not established by the timeout $ timeout 1 bash -c 'cat < /dev/null >/dev/tcp/google.com/81' $ echo $? 124 

What's happening here is that timeout will run the subcommand and kill it if it doesn't exit within the specified timeout (1 second in the above example). In this case bash is the subcommand and uses its special /dev/tcp handling to try and open a connection to the server and port specified. If bash can open the connection within the timeout, cat will just close it immediately (since it's reading from /dev/null ) and exit with a status code of 0 which will propagate through bash and then timeout . If bash gets a connection failure prior to the specified timeout, then bash will exit with an exit code of 1 which timeout will also return. And if bash isn't able to establish a connection and the specified timeout expires, then timeout will kill bash and exit with a status of 124.

Use a different syntax for Git Bash:

Otherwise, Git Bash will return an error where none is expected:

$ timeout 1 bash -c 'cat < /dev/null >/dev/tcp/google.com/80' $ echo $? 124 

Источник

Читайте также:  Linux gui поиск файлов
Оцените статью
Adblock
detector