networking - Test connection to a port without actually connecting to it

07
2014-07
  • thelastblack

    I have a python socket server (single-threaded, accepts only one connection) running somewhere.

    I connect to that port and do my things.

    How can I detect whether port is open or closed without making any connection? I mean, I don't want to close the port to see if it is open or not :-)

    I already tried nc -zvv ip port but this closes the script (because it actually connects to the port).

  • Answers
  • grawity

    Use a port-scanning tool like nmap. When run with sufficient privileges (on Linux the cap_net_raw privilege is necessary, "root" on other Unix systems) the tool has several scan modes that do not involve completing the TCP handshake.

    The default scan mode when privileged is "TCP SYN scan" (the -sS option), which tries to start a TCP handshake but immediately resets it. This way, the program is not informed about a connection attempt because there was no connection.

    To scan specific ports, add the -p <ports> option.

    $ sudo nmap --reason -sS -p 22,53,79,80 localhost
    PORT    STATE  SERVICE REASON
    22/tcp  open   ssh     syn-ack
    79/tcp  open   finger  syn-ack
    143/tcp closed imap    reset
    443/tcp closed https   reset
    

  • Related Question

    linux - Manually closing a port from commandline
  • Questioner

    I want to close an open port which is in listening mode between my client and server application.

    Is there any manual command line option in Linux to close a port ??

    NOTE: I came to know that "only the application which owns the connected socket should close it, which will happen when the application terminates."

    I dont understand why it is only possible by the application which opens it ... But still eager to know if there is any another way to do it ??


  • Related Answers
  • Dankó Dávid

    You're kind of asking the wrong question here. It isn't really possible to simply "close a port" from outside the application that opened the socket listening on it. The only way to do this is to completely kill the process that owns the port. Then, in about a minute or two, the port will become available again for use. Here's what's going on (if you don't care, skip to the end where I show you how to kill the process owning a particular port):

    Ports are resources allocated by the OS to different processes. This is similar to asking the OS for a file pointer. However, unlike file pointers, only ONE process at a time may own a port. Through the BSD socket interface, processes can make a request to listen on a port, which the OS will then grant. The OS will also make sure no other process gets the same port. At any point, the process can release the port by closing the socket. The OS will then reclaim the port. Alternatively, if the process ends without releasing the port, the OS will eventually reclaim the port (though it won't happen immediately: it'll take a few minutes).

    Now, what you want to do (simply close the port from the command-line), isn't possible for two reasons. First, if it were possible, it would mean one process could simply steal away another process's resource (the port). This would be bad policy, unless restricted to privileged processes. The second reason is it is unclear what would happen to the process that owned the port if we let it continue running. The process's code is written assuming that it owns this resource. If we simply took it away, it would end up crashing on it's own, so OS's don't let you do this, even if you're a privileged process. Instead, you must simply kill them.

    Anyway, here's how to kill a process that owns a particular port:

    sudo netstat -ap | grep :<port_number>
    

    That will output the line corresponding to the process holding port . Then, look in the last column, you'll see /. Then execute this:

    kill  <pid>
    

    If that doesn't work (you can check by re-running the netstat command). Do this:

    kill -9 <pid>
    

    In general, it's better to avoid sending SIGKILL if you can. This is why I tell you to try kill before kill -9. Just using kill sends the gentler SIGTERM.

    Like I said, it will still take a few minutes for the port to re-open if you do this. I don't know a way to speed this up. If someone else does, I'd love to hear it.

  • Will

    Fuser can also be used

    fuser -k -n *protocol portno*
    

    Here protocol is tcp/udp and portno is the number you wish to close. E.g.

    fuser -k -n tcp 37
    

    More info at fuser man page

  • Community

    You could alternatively use iptables:

    iptables -I INPUT -p tcp --dport 80 -j DROP
    

    It basically accomplishes what you want. This will drop all TCP traffic to port 80.

  • Ben
    netstat -anp | grep 80
    

    It should tell you, if you're running apache, "httpd" (this is just an example, use the port your application is using instead of 80)

    pkill -9 httpd 
    

    or

    killall -9 httpd
    
  • Michael Shimmins

    You could write a script which modified the iptables and restarts them. One script for adding a rule dropping all packets on the port, another script for removing said rule.

    The other answers have shown you how to kill the process bound to the port - this may not be what you want. If you want the server to keep running, but to prevent connections from clients then you want to block the port, not stop the process.

  • slhck

    You could probably just find out what process opened the socket that the port is associated with, and kill that process.

    But, you would have to realize that unless that process has a handler that de-initializes all the stuff that it was using (open files, sockets, forks, stuff that can linger unless it's closed properly upon termination) then you would have created that drag on system performance. Plus, the socket will remain open until the kernel realizes that that the process has been killed. That usually just takes about a minute.

    I suppose the better question would be: What port (belonging to what process) do you want to stop?

    If you are trying to put an end to a backdoor or virus that you found, then you should at least learn what data is going back and forth before you terminate it. (wireshark is good for this) (And the process' executable name so you can delete it and prevent it from coming back on reboot) or, if it's something you installed (like HTTPD or FTPD or something) then you should already have access to the process itself.

    Usually it will have a control program (HTTPD stop|start or something). Or, if it's a system thing, you probably should not mess with it. Anyway, i thought that since everyone else is giving you the "how-to" angle, i should give you the caveats.

  • Rich Homolka

    One more issue: sometime the kernel owns ports themselves. I know NAT routing holds some ports open for NAT use. You can not kill a process for this, this is a kernel, and a reconfiguration and a reboot is required.