How to listen for multiple tcp connection using nc - linux

How to create a TCP connection using nc which listens to multiple hosts?
nc -l -p 12345

Simultaneous connections are not possible with netcat. You should use something like ucspi-tcp's tcpserver tool or leverage xinetd since you're on Linux.
See: https://superuser.com/questions/232747/netcat-as-a-multithread-server
Consecutive connections could be handled through a shell script that restarts netcat after it finishes.

ncat can do it.
E.g. ncat --broker --listen -p 12345 will distribute all incoming messages to all other clients (think of it as a hub).

I recommend socat as nc alternative.
For OP's problem, socat - TCP-LISTEN:12345,fork,reuseaddr can do the job.

-k
Forces nc to stay listening for another connection after its current connection is completed. It is an error to use this option without the -l option.

using nc it is not possible to open parallel connections to same port, however you can trick nc to open multiple connections to same port.
To understand this, lets say you start listening on 4444 port using $ nc -l -p 4444 -v. Now, if you check output of $ netstat -anp | grep 4444 you will get its state as LISTEN and in here its pid is 3410.
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 3410/nc
Now, after it gets connected to client, lets say you run $ nc localhost 4444 -v, its state will get changed into ESTABLISHED. Now, try running $ netstat -anp | grep 4444 you will get its state as ESTABLISHED, see for same pid 3410, and a client process with pid 3435
tcp 0 0 127.0.0.1:46678 127.0.0.1:4444 ESTABLISHED 3435/nc
tcp 0 0 127.0.0.1:4444 127.0.0.1:46678 ESTABLISHED 3410/nc
Please note that there is no available listening port, so you can't have another client process. However if you run again $ nc -l -p 4444 -v you can have a listening port and can have multiple client process.
see netstat -anp | grep 4444 output after you start listening to same port.
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 3476/nc
tcp 0 0 127.0.0.1:46678 127.0.0.1:4444 ESTABLISHED 3435/nc
tcp 0 0 127.0.0.1:4444 127.0.0.1:46678 ESTABLISHED 3410/nc
see netstat -anp | grep 4444 output after you attach new client to same port.
tcp 0 0 127.0.0.1:4444 127.0.0.1:46694 ESTABLISHED 3476/nc
tcp 0 0 127.0.0.1:46678 127.0.0.1:4444 ESTABLISHED 3435/nc
tcp 0 0 127.0.0.1:4444 127.0.0.1:46678 ESTABLISHED 3410/nc
tcp 0 0 127.0.0.1:46694 127.0.0.1:4444 ESTABLISHED 3483/nc
You can say connections behavior is like:
SERVER_PROCESS_1 <---> CLIENT_PROCESS_1
SERVER_PROCESS_2 <---> CLIENT_PROCESS_2
so, you can write some script to simulate this behavior, or use this bash script to modify.
#!/usr/bin/bash
lport="4444"
i=0;
while [ true ]; do
echo "opening socket $(( i++ ))";
if [[ "$(ss sport = :$lport -l -H | wc -l)" -eq 0 ]]; then
nc -l -vv -p $lport &
#do something else to process or attach different command to each diff server process
fi;
if [[ "$(ss sport = :$lport -l -H | wc -l)" -ne 0 ]]; then
watch -n 0.1 -g "ss sport = :$lport -l -H" > /dev/null;
fi;
if [[ i -eq 10 ]]; then
break;
fi;
done;
in here every time client consume a connection this script will start new listen socket.
This behavior is however can be changed in ncat (here, using -k)as you can analyze the with below example:
server is started using $ ncat -l -p 4444 -v -4 -k and 3 clients are started using $ ncat -4 localhost 4444. Now output for $ netstat -anp | grep 4444 is:
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 3596/ncat
tcp 0 0 127.0.0.1:4444 127.0.0.1:46726 ESTABLISHED 3596/ncat
tcp 0 0 127.0.0.1:46726 127.0.0.1:4444 ESTABLISHED 3602/ncat
tcp 0 0 127.0.0.1:46722 127.0.0.1:4444 ESTABLISHED 3597/ncat
tcp 0 0 127.0.0.1:4444 127.0.0.1:46724 ESTABLISHED 3596/ncat
tcp 0 0 127.0.0.1:4444 127.0.0.1:46722 ESTABLISHED 3596/ncat
tcp 0 0 127.0.0.1:46724 127.0.0.1:4444 ESTABLISHED 3601/ncat
Every time new client connect, server fork its process to attach to client, so each server process is using same pid. So output of server in this way is shared to every attached clients, however each client can send individual message to server.
You can say connections behavior is like:
SERVER_PROCESS_1 <---> CLIENT_PROCESS_1
SERVER_PROCESS_1 <---> CLIENT_PROCESS_2
SERVER_PROCESS_1 <---> CLIENT_PROCESS_3
without -k, ncat will behave same as nc.
Benefits or loses can be defined on how they are to be needed.
For this example, i used nc or nc.traditional (v1.10-41.1+b1), and ncat (7.80).

This is an incomplete answer, because I haven't got it working. Arguably more of a question, in fact. Maybe someone else can finish it off.
First of all, it seems there are different versions of netcat. I'm on Ubuntu, so I've probably got the version that came with Ubuntu. When I nc -h, it says this:
OpenBSD netcat (Debian patchlevel 1.187-1ubuntu0.1)
When I run man nc, it says this:
-F Pass the first connected socket using sendmsg(2) to stdout and exit. This
is useful in conjunction with -X to have nc perform connection setup with
a proxy but then leave the rest of the connection to another program (e.g.
ssh(1) using the ssh_config(5) ProxyUseFdpass option).
It seems to me that this means that, instead of doing the usual thing with stdin and stdout, it just prints something to stdout. That something could then be used by another process to do the actual connection to the client.
Unfortunately, -F has no effect that I can see. So maybe I'm doing it wrong. Or maybe there's some secret pipe somewhere that I have to listen to, or a supplementary argument they forgot to document. Or maybe I happen to have a broken build of netcat, and it works for everyone else who's on Ubuntu.
In combination with the -k option (or, failing that, a while-true loop), this would allow many different clients to have separate connections. Suppose you have an executable called handle_connection, which takes as arguments an in file descriptor from a client and an out file descriptor to the client, and spawns a subprocess which communicates with the client. Then the server script might look like this:
nc -lkF $host $port | while read in out ; do
handle_connection $in $out ;
done

ncat can do it, but the correct command with ncat is:
ncat --keep-open --listen -p 12345
This will accept multiple connections at the same time.
You can then send the data with multiple clients. e.g. open in two or more terminals, and try typing there:
nc localhost 12345

Related

What actually reuseaddr option does in socat?

I'm reading the doc about socat here and here.
The example socat -u TCP4-LISTEN:3334,reuseaddr,fork OPEN:/tmp/test.log,creat,append works well with and without option reuseaddr.
What does the reuseaddr do?
Why above example works well with and without the reuseaddr?
In which cases the reuseaddr is really needed?
reuseaddr allows to bind to address which is in TIME_WAIT state, e.g. after server is killed while client is connected.
Without reuseaddr, server side:
$ socat -u TCP-LISTEN:3334,fork -
Client:
$ socat -u TCP-CONNECT:localhost:3334 -
Back to server:
^C
$ netstat -nta | grep 3334
tcp 0 0 127.0.0.1:3334 127.0.0.1:37578 TIME_WAIT
$
$ socat -u TCP-LISTEN:3334,fork -
2023/01/14 16:44:19 socat[84239] E bind(5, {AF=2 0.0.0.0:3334}, 16): Address already in use
With reuseaddr (before run wait until TIME_WAIT state passed away, or use different port number):
$ socat -u TCP-LISTEN:3334,fork,reuseaddr -
Client:
$ socat -u TCP-CONNECT:localhost:3334 -
Back to server:
^C
$ netstat -nta | grep 3334
tcp 0 0 127.0.0.1:3334 127.0.0.1:35168 TIME_WAIT
$ socat -u TCP-LISTEN:3334,fork,reuseaddr -
^^^ No error.
Note reuseaddr should be applied to both initial and subsequent sockets.
Here's the important part: http://www.dest-unreach.org/socat/doc/socat.html#EXAMPLE_OPTION_REUSEADDR
due to reuseaddr, it allows immediate restart after master process's termination, even if some child sockets are not completely shut down
So the difference should only be visible if some child sockets are not completely shut down.
I've tried your example and could see (with lsof) the reuseaddr option on the socket activated
socat -u TCP4-LISTEN:3334,reuseaddr,fork OPEN:/tmp/test.log,creat,append
...
lsof -nP -i -sTCP:LISTEN -T f | grep 3334
socat 46095 userabc 5u IPv4 0x59cfcb9c717622ef 0t0 TCP *:3334 (SO=ACCEPTCONN,PQLEN=0,QLEN=0,QLIM=5,RCVBUF=1048576,REUSEADDR,SNDBUF=1048576 TF=MSS=512,UNKNOWN=0xa0)
socat -u TCP4-LISTEN:3334,fork OPEN:/tmp/test.log,creat,append
...
lsof -nP -i -sTCP:LISTEN -T f | grep 3334
socat 46375 userabc 5u IPv4 0x59cfcb9c6f806e0f 0t0 TCP *:3334 (SO=ACCEPTCONN,PQLEN=0,QLEN=0,QLIM=5,RCVBUF=1048576,SNDBUF=1048576 TF=MSS=512,UNKNOWN=0xa0)

finding a process ID and listing the command name and any network connections

i've been trying to create a script that will take a process ID number (PID) and then identify the process ID with its name and also list any network connections that its connected to.
I understand I should use netstat to do this. here is my code so far however it doesn't seem to do anything, can you explain where im going wrong and what i need to do?
echo 'Please enter a Process ID: '
read pidN
echo 'You entered process ID: ' $pidN
pID= pgrep -fl "^(/.*)?${pidN}\s"
echo $pID
If you use the command below (ex: ssh)
netstat -nalp | grep -i ssh
Follow the result:
[root#localhost ~]# netstat -nalp | grep 1055
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1055/sshd
tcp6 0 0 :::22 :::* LISTEN 1055/sshd
unix 3 [ ] STREAM CONNECTED 20308 1055/sshd

Close established TCP connection on Linux

I am not able to find an answer to a simple thing I will try to achive:
once a tcp connection is established to my linux server, let's say ssh / tcp 22 or x11 / tcp 6000 display -> how do I close this connection without killing the process (sshd / x11 display server).
I saw also some suggestoin to use iptables, but it does not work for me, the connection is still visible in netstat -an.
would be good if someone can point me to the right direction.
what I tried so far
tcpkill: kills the process, not good for me
iptables: does not close the established connection, but prevent further connections.
Thanks in adavnce
DJ
Ok, I found at least one solution (killcx) which is working. Maybe we will be able to find an easier solution.
Also, i saw the comment from "zb" - thanks - which might also work, but I was not able to find a working syntax, since this tool seems to be really useful but complex.
So here is an example how to work with the 1. solution which is working for me:
netstat -anp | grep 22
output: tcp 0 0 192.168.0.82:22 192.168.0.77:33597 VERBUNDEN 25258/0
iptables -A INPUT -j DROP -s 192.168.0.77 (to prevent reconnect)
perl killcx.pl 192.168.0.77:33597 (to kill the tcp connection)
killcx can be found here: http://killcx.sourceforge.net/
it "steals" the connection from the foreign host (192.168.0.77) and close it. So that solution is working fine, but to complex to setup quickly if you are under stress. Here are the required packages:
apt-get install libnetpacket-perl libnet-pcap-perl libnet-rawip-perl
wget http://killcx.sourceforge.net/killcx.txt -O killcx.pl
however, would be good to have an easier solution.
tcpkill wont work, since it will only kill any new connection, it doesnt kill existing ESTABLISHED connections
heres how you remove an Established TCP connection
find the PID of the process and the IP of the client connecting,
lets say you are on serverA and someone is connecting from serverB
root#A> netstat -tulpan | grep ssh | grep serverB
should see something like,
tcp 0 0 <serverA IP>:<port> <serverB>:<port> ESTABLISHED 221955/sshd
use lsof utility to get the File Descriptor of this connection using the parent PID
root#A> lsof -np 221995 | grep serverB IP
should see something like this
sshd 221955 <user> 17u IPv4 2857516568 0t0 TCP <serverA IP>:<port>-><serverB IP>:<port> (ESTABLISHED)
get the File Descriptor number (4th column) = 17u
use GDB to shut down this connection, w/out killing sshd
root#A> gdb -p 211955 --batch -ex 'call shutdown(17u, 2)'
should see something similar,
0x00007f0b138c0b40 in __read_nocancel () from /usr/lib64/libc.so.6
$1 = 0
[Inferior 1 (process 211955) detached]
that TCP connection should now be closed

How to show which port is the database socket running by Linux command?

I have three MySQL database sockets running on a Linux machine. By the cmd "sudo netstat -npl|grep mysql", I can find the ports and db sockets. But I need to match them one to one by using pid.
Is there any cmd I can use to show the port number of a db socket directly in Linux?
The output looks like this:
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 3886/mysqld
The PID of the mysqld process is the number before /mysqld, i.e. 3886.
There's several different ways to do it, but for your purposes, I suggest simply looking at the output of the command you're already running.
$ sudo netstat -npl|grep mysql
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1124/mysqld
unix 2 [ ACC ] STREAM LISTENING 8713 1124/mysqld /var/run/mysqld/mysqld.sock
This is telling me that process 1124 is listening on 3306 and /var/run/mysqld/mysqld.sock

linux how to find out which program connect to remote port

See the output below:
tcp 0 0 192.168.2.222:35774 192.168.3.200:9090 TIME_WAIT
On Linux I want to find out which program connects to 192.168.3.200:9090, how can I achieve this?
I think
# lsof -Pnl +M -i4 // Listens on all IPV4 Ports
or
# netstat -ntp
are the commands you are searching for.
Then try to use fgrep to find the line. (in your case: fgrep '192.168.3.200:9090')
--> netstat -ntp | fgrep '192.168.3.200:9090'
you can do netstat -anp.
You'll need to sudo or be root to see the process information.
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 665/sshd
netstat -avnp | egrep '^tcp' | fgrep '192.168.3.200:9090'

Resources