combine netcat with chat on bash for automatic udp responses - linux

I want to combine "chat" and "nc" on linux, so I will create a tiny udp server that responds on a specific request and sends back an answer.
In fact I want to redirect the stdout of "nc" to the stdin of "chat" and vice versa. My first attempt was:
nc -w 3000 -u -n -l -p 30000 >&1111 <2222 &
chat -V 'request' 'answer' >&2222 <1111
But it didn't work.

use socat instead of netcat. Something like this :
socat UDP-LISTEN:5555 EXEC:"chat -sv ping pong",pty
To test it, you can open another terminal, and use socat to bridge stdio and an UDP socket :
socat - UDP:localhost:5555
Type ping, and you will get pong !

Related

Output a linux command to a url/port or scocket instead of writing it to a file

I have a command which out outputs certain data which i store in a ext file using a '>>' command.Now Instead of doing that I want to have a socket or a port on any server which will catch the output of the command.Basically i want to output all my script data to a socket or url which ever is possible.
Any help in this direction is most welcomed.
You can use socat to listening on a port 12345 and echo any data sent to it like this:
socat -u TCP-LISTEN:12345,keepalive,reuseaddr,fork STDOUT
If you want to capture it to a file as well (file.log), you can use the same command with tee:
socat -u TCP-LISTEN:12345,keepalive,reuseaddr,fork STDOUT | tee file.log
You can run your program to output to bash's TCP virtual device:
./prog > /dev/tcp/localhost/12345
If you don't want to use bash magic then you can also use socat to send the data:
./prog | socat - TCP-CONNECT:localhost:12345
The above example assume you are running your program and "logger" on the same system but you can replace "localhost" with the hostname or address of the system you wish to send to (where the socat is listening).

Using netcat to pipe unix socket to tcp socket

I am trying to expose a unix socket as a tcp socket using this command:
nc -lkv 44444 | nc -Uv /var/run/docker.sock
When I try to access localhost:44444/containers/json from a browser, it doesn't load anything but keeps the connection open (the loading thingy keeps spinning), but the console (because of the -v flag) shows proper http response.
Any ideas on how to get this working?
PS: I know I can use socat, or just tell docker to also listen on a tcp socket, but I am using the project atomic vm image, and it won't let me modify anything except /home.
You are only redirecting incoming data, not outgoing data.
try with:
mkfifo myfifo
nc -lkv 44444 <myfifo | nc -Uv /var/run/docker.sock >myfifo
See http://en.wikipedia.org/wiki/Netcat#Proxying
Edit: in a script you would want to generate the name for the fifo at random, and remove it after opening it:
FIFONAME=`mktemp -u`
mkfifo $FIFONAME
nc -lkv 44444 < $FIFONAME | nc -Uv /var/run/docker.sock > $FIFONAME &
rm $FIFONAME
fg

unix netcat utility on linux, checking if connection was made

I am using netcat utility on linux to receive outputs from a program on a windows machine. My problem being that the program on the windows machine does not always give an output.
How can i check that either a connection has been made to netcat ?
What i am doing till now is "nc -l -v 9103 > output" then i check the size of output, the problem this poses is that netcat only write to a file after a certain buffer size has been reached or a new line char is encountered, so some cases evne though a connection has been made the file size is detected as zero.
How can i check if someone has made a connection with netcat.
I tried using
nc -l -v -e someprog.exe 9103 > output
but my netcat doesnt seem to support this
below are the options i have
$ nc -h
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port]
[-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version]
[-x proxy_address[:port]] [hostname] [port[s]]
Command Summary:
-4 Use IPv4
-6 Use IPv6
-D Enable the debug socket option
-d Detach from stdin
-h This help text
-i secs Delay interval for lines sent, ports scanned
-k Keep inbound sockets open for multiple connects
-l Listen mode, for inbound connects
-n Suppress name/port resolutions
-p port Specify local port for remote connects
-r Randomize remote ports
-s addr Local source address
-T ToS Set IP Type of Service
-C Send CRLF as line-ending
-t Answer TELNET negotiation
-U Use UNIX domain socket
-u UDP mode
-v Verbose
-w secs Timeout for connects and final net reads
-X proto Proxy protocol: "4", "5" (SOCKS) or "connect"
-x addr[:port] Specify proxy address and port
-z Zero-I/O mode [used for scanning]
Port numbers can be individual or ranges: lo-hi [inclusive]
verbose mode will write connectivity to stderr, and you can redirect stderr to a file, the verbose log has something like
connect to [xxx] from [xxxx]
try
nc -l -v -p 9103 -k 1> output 2>connect.log
and monitor connect.log for connectivity
if you don't use -k , netcat quits after 1st connection.
If you can upgrade your copy of netcat: the modern versions (1.10, for one) have an option to execute a program (or a shell command) upon connect. Otherwise, you can make the netcat think it runs in a terminal (to disable buffering of stdout), by using for example script (it just saves everything on stdin/stdout/stderr in the given file). Or use logging features of screen and tmux.

Simple Socket Server in Bash?

Is there a way to quickly bind to a TCP port/ip address and simply print out all information to STDOUT? I have a simple debugging solution which writes things to 127.0.0.1:4444 and I'd like to be able to simply bind up a port from bash and print everything that comes across. Is there an easy way to do this?
$ nc -k -l 4444 > filename.out
see nc(1)
Just because you asked how to do it in bash, though netcat answer is very valid:
$ exec 3<>/dev/tcp/127.0.0.1/4444
$ cat <&3
That is working as you expecting:
nc -k -l 4444 |bash
and then you
echo "ls" >/dev/tcp/127.0.0.1/4444
then you see the listing performed by bash.
[A Brief Security Warning]
Of course if you leave a thing like this running on your computer, you have a wide open gateway for all kinds of attacks because commands can be sent from any user account on any host in your network. This implements no security (authentication, identification) whatsoever and sends all transmitted commands unencrypted over the network, so it can very easily be abused.
Adding an answer using ncat that #Freedom_Ben alluded to:
ncat -k -l 127.0.0.1 4444
and explanation of options from man ncat:
-k, --keep-open Accept multiple connections in listen mode
-l, --listen Bind and listen for incoming connections

Redirecting TCP-traffic to a UNIX domain socket under Linux

Assume a legacy Linux application listening on a UNIX domain socket /tmp/foo.
In addition to communicating with this legacy application over the UNIX domain socket mechanism I want to be able to connect to it via a TCP-connection on port say 1234.
What is the easiest way to bind to TCP port 1234 and then redirect all incoming connections to the UNIX domain socket /tmp/foo?
Turns out socat can be used to achieve this:
socat TCP-LISTEN:1234,reuseaddr,fork UNIX-CLIENT:/tmp/foo
And with a bit of added security:
socat TCP-LISTEN:1234,bind=127.0.0.1,reuseaddr,fork,su=nobody,range=127.0.0.0/8 UNIX-CLIENT:/tmp/foo
These examples have been tested and work as expected.
Easiest? Probably Netcat (aka nc):
nc -l 1234 | nc -U /tmp/foo
The first command listens on port 1234 for incoming connections, and pipes the resulting data to the second command. The second connects to the Unix domain socket /tmp/foo, and writes its input to that socket. Note that this will only accept a single connection, and exit as soon as that connection is dropped. If you want to keep listening for more connections, use the -k option:
nc -lk 1234 | nc -U /tmp/foo
You can test that this is working by setting up a listener for that socket in one terminal:
nc -lUk /tmp/foo
And writing to it in another:
nc localhost 1234
socat, as recommended by knorv, is more capable, but more complicated to use.
You should be able to bind to TCP 1234, get a socket fd for /tmp/foo and use the select call to 'listen' for data on both 1234, and /tmp/foo. Any data written to 1234, you rewrite to /tmp/foo and vice-versa.
You now act as a proxy and transfer data back and forth.
And here is a web-page which might help: http://osr507doc.sco.com/en/netguide/dusockC.io_multiplexing.html
In additons to #knorv's answer: with xinetd it can work like a daemon
# cat /etc/xined.d/mysrv
service mysrv
{
disable = no
type = UNLISTED
socket_type = stream
protocol = tcp
wait = no
server = /usr/bin/socat
server_args = STDIN UNIX-CLIENT:/tmp/mysocket.sock
bind = 127.0.0.1
port = 1234
}
Not tried it : but it looks like 'lighttpd' can do this for you:
http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore

Resources