Checking if port is open linux

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 if a certain port is open and unused?

Could you please help and tell how can i find out if port 80 is open and unused so that I can start installation.

For what it's worth, /etc/services is completely static. Grepping it can tell you if a port is officially designated by IANA or some such, but does not tell whether or not it's in local use.

9 Answers 9

sudo netstat -anp | grep ':80 ' 

That should give you pid & name of the process that holds port 80

This can be achieved using the nc command as follows:

It will return TRUE if the port is already in use, or FALSE is it (i.e, available not listening currently).

I don't recommend lsof or netstat method as it first try to scan all running PIDs to get all bounded ports:

# time lsof -i:8888 real 0m1.194s user 0m0.137s sys 0m1.056s``` # time nc -z 127.0.0.1 8888 real 0m0.014s user 0m0.011s sys 0m0.004s 

Here 8888 is an unused port. The nc command is ~85 times faster in the above example.

Eg 1:

$ nc -z 127.0.0.1 80 && echo "IN USE" || echo "FREE" IN USE $ nc -z 127.0.0.1 81 && echo "IN USE" || echo "FREE" FREE 

Eg 2:

If you are trying with a remote IP, it is better to add a timeout to auto-exit if it is not accepting connection for the specified time.

Its Google's IP which is not used, so it will timeout after trying for 2 seconds.

This also works greatly when running inside the Docker image that uses host network. Inside the image, lsof incorrectly reports the port is not in use when it actually is.

The traditional version of nc does not include the -z option. See the differences between traditional and openbsd.

netstat -tln | tail -n +3 | awk '< print $4 >' 

This one displays bind addresses of TCP listening endpoints. All other endpoints are free; Also if on Unix and you are not root, then you can't bind to a 'privileged' port number (port number lower than 1024).

Explained in more details:

  • netstat -tln - all listening tcp ports
  • tail -n +3 - cut off the header of netstat command
  • awk '< print $4 >' - print the fourth column that consists of [ip]:[port]

For the general case you still need to care to cut out all irrelevant interfaces; a listening address 0.0.0.0 is listening on all network cards, if there is an IP address then that's the specific IP of the network card/network interface.

Источник

Check if port is open or closed on a Linux server?

It's not quite clear what you're asking. What do you mean by "open"? Do you mean some server is listening on that port? Or do you mean it's allowed by the system firewall? Or what?

nc -w5 -z -v , you should get something like Connection to 127.0.0.1 9000 port [tcp/*] succeeded! , otherwise port is closed.

A topic that contains an answer also for kernel level services and programs serverfault.com/questions/1078483/…

8 Answers 8

You can check if a process listens on a TCP or UDP port with netstat -tuplen .

To check whether some ports are accessible from the outside (this is probably what you want) you can use a port scanner like Nmap from another system. Running Nmap on the same host you want to check is quite useless for your purpose.

GNU netstat knows the parameters -t , -u , -p , -l , -e , and -n . Thanks to the options parser it can be expressed as -tuplen . linux.die.net/man/8/netstat

Also, the telnet command usually does only supports TCP, so you're out of luck if the service you want to check runs on another protocol.

According to article: computingforgeeks.com/netstat-vs-ss-usage-guide-linux netstat is deprecated, and ss is it's replacement, so you can do ss -an , ss -tuplen or for tcp listening sockets ss -ntlp .

Quickest way to test if a TCP port is open (including any hardware firewalls you may have), is to type, from a remote computer (e.g. your desktop):

Which will try to open a connection to port 80 on that server. If you get a time out or deny, the port is not open 🙂

OK, in summary, you have a server that you can log into. You want to see if something is listening on some port. As root, run:

this will show a listing of processes listening on TCP and UDP ports. You can scan (or grep) it for the process you're interest in,and/or the port numbers you expect to see.

If the process you expect isn't there, you should start up that process and check netstat again. If the process is there, but it's listening on a interface and port that you did not expect, then there's a configuration issue (e.g., it could be listening, but only on the loopback interface, so you would see 127.0.0.1:3306 and no other lines for port 3306, in the case of the default configuration for MySQL).

If the process is up, and it's listening on the port you expect, you can try running a "telnet" to that port from your Macbook in your office/home, e.g.,

 telnet xxxxxxxxxxxx.co.uk 443 

That will test if (assuming standard ports) that there's a web server configured for SSL. Note that this test using telnet is only going to work if the process is listening on a TCP port. If it's a UDP port, you may as well try with whatever client you were going to use to connect to it. (I see that you used port 224. This is masqdialer, and I have no idea what that is).

If the service is there, but you can't get to it externally, then there's a firewall blocking you. In that case, run:

This will show all the firewall rules as defined on your system. You can post that, but, generally, if you're not allowing everything on the INPUT chain, you probably will need to explicitly allow traffic on the port in question:

 iptables -I INPUT -p tcp --dport 224 -j ACCEPT 

or something along those lines. Do not run your firewall commands blindly based on what some stranger has told you on the Internet. Consider what you're doing.

If your firewall on the box is allowing the traffic you want, then your hosting company may be running a firewall (e.g., they're only allowing SSH (22/tcp), HTTP (80/tcp) and HTTPS (443/tcp) and denying all other incoming traffic). In this case, you will need to open a helpdesk ticket with them to resolve this issue, though I suppose there might be something in your cPanel that may allow it.

Источник

Читайте также:  Настройка переключения языка linux mint
Оцените статью
Adblock
detector