Is it possible to send string into running process inside docker container? - linux

For example i have running docker container with cat (or other process using stdin) defined in CMD Dockerfile option.
I'm trying to send string test\n into running cat (or other process).
Is it possible to do this, or I need to find workaround?
Sum up:
I'm looking for something like
echo 'test' | docker run -i --rm alpine command
for running container.

You can pipe to stdin of the container's process if you start the container with -i. For example;
echo "foobar" | docker run -i --rm alpine cat
Keep in mind, that this is done when starting the container. Your question mentioned cat, which is not a long running process, so the container will actually exit after cat completes.

I solved it by simply pipeing stdin to docker attach, for example:
$ docker run -i busybox sh -c "while true; do cat /dev/stdin; sleep 1; done;"
test
and in another term
$ echo test | docker attach <containerId>

Yes as an example see
https://github.com/chilcano/docker-netcat
you need to open a port, extract from the previous link
$ docker run -d -t --name=netcat-jessie -p 8182:8182 -p 9192:9192/udp chilcano/netcat:jessie
and now, you have some examples of communication using those ports
send traces to open a TCP port
$ ping 8.8.4.4 | nc -v 192.168.99.100 8182
or send traces to an UDP port
$ ping 8.8.8.8 | nc -vu 192.168.99.100 9192
or send traces to an UDP port without netcat
$ ping 8.8.4.4 > /dev/udp/192.168.99.100/9192
and
$ tail -f /opt/wiremock/wiremock.log | nc -vu 192.168.99.100 9192
or send traces to a TCP port without netcat
$ tail -f /opt/wso2esb01a/repository/logs/wso2carbon.log > /dev/tcp/192.168.99.100/8182
or send traces to an UDP port without netcat
$ tail -f /opt/wso2am02a/repository/logs/wso2carbon.log > /dev/udp/192.168.99.100/9192

Related

Bash run task via ssh and get stdout, stderr live output to file in background

I am running a python 3 script via ssh, and I want to see the stdout and stderr in a file on the remote server.
Also, I would like to see the file updated live while the script is running and that the script will run in the background so the ssh connection will not wait for the script to finish.
While looking at other questions, I managed to answer most of my requests.
Here is what I come up with:
ssh user#machine_ip "(python3 my_script.py 2>&1 | tee output.log) &"
The problem is that the ssh is waiting for the script to finish.
So combining the answer from this question with some hackidy hack nonsense...
Really all you need to do is this:
(( python3 my_script.py 0<&- 2>&1 | tee -a ${OUTFILE} | nc -kl ${PORT} &) &)
Explanation:
Run your python script: python3 my_script.py
Detach stdin (so it can run independently): ... 0<&-
Redirect stderr to stdout so we can pipe them along together: ... 2>&1
Append output to some file but also keep the output going to stdout so we can pipe it someplace else: ... | tee -a ${OUTFILE} |
Pipe stdout to a netcat listening port so this machine can essentially "serve" the stdout from your python script: ... | nc -kl ${PORT}
Create a "double nested background subshell" this is explained in the link above but this will allow you to orphan "blah" so that it'll run even if your ssh connection ends (( ... blah ... &) &)
To view the stdout/stderr of my_script.py you now have several options. If you are still logged into that remote machine you can:
tail -f ${OUTFILE} # Same "OUTFILE" used in explanation component 4
nc localhost $PORT # Same "PORT" used in explanation component 5
If you are no longer logged in and you are now on a different machine (but on the same network) you can:
nc ${remote_machine} $PORT # Same "PORT" used in explanation component 5
Where ${remote_machine} is the hostname or IP address of the machine you ssh'ed into to run your command

Find pid of a process while its rinning on background

I have python sunning on my PC in a Linux machine .
ps -eaf | grep python
But now i dont know the process name say . Python is running on the port 7777. I only know the port no on which python with the bellow command .
netstat
Now i want to find out the pid no of python which is running on port 7777.
as i dont know the process name i only know port no 7777 . are there any command for the same problem .
You have to use following :
lsof -i :7777
I will show you pid without knowing the process name , but knowing the port no
sudo netstat -tunlp | grep :7777
You can use either netstat (deprecated) or ss, with the same options which are mnemonic:
-t = TCP
-u = UDP
-n = numeric output
-l = listening ports
-p = pid
Another commands that works, apart, from lsof, is fuser (the Linux one because the BSD's is different).
sudo fuser -n tcp -n 7777

How to enter bash of an ubuntu docker container?

I want to run an ubuntu container and enter bash:
[root#localhost backup]# docker run ubuntu bash
[root#localhost backup]#
The ubuntu container exits directly. How can I enter the bash?
Use -i and -t options.
Example:
$ docker run -i -t ubuntu /bin/bash
root#9055316d5ae4:/# echo "Hello Ubuntu"
Hello Ubuntu
root#9055316d5ae4:/# exit
See: Docker run Reference
$ docker run --help | egrep "(-i,|-t,)"
-i, --interactive=false Keep STDIN open even if not attached
-t, --tty=false Allocate a pseudo-TTY
Update: The reason this works and keeps the container running (running /bin/bash) is because the -i and -t options (specifically -i) keep STDIN open and so /bin/bash does not immediately terminate thus terminate the container. -- The reason you also need/want -t is because you presumably want to have an interactive terminal-like session so t creates a new pseudo-tty for you. -- Furthermore if you looked at the output of docker ps -a without using the -i/-t options you'd see that your container terminated normally with an exit code of 0.

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.

2 tcpdumps from a remote host

I need to collect tcpdump from different interfaces from a remote host.
Currently I do it in the following way:
ssh remotehost "tcpdump -i iface1 -w - " > iface1_dump.pcap &
ssh remotehost "tcpdump -i iface2 -w - " > iface2_dump.pcap
I wonder if there a way to realize it in single ssh connect (maybe some complex shell redirect is a cure) to minimize packets loss while second ssh command is on its way
2 conditions:
remote host has really limited disk space, so I can't tcpdump locally on that host
tcpdump -i any affects Ethernet headers, so I can't use it
You create a file "SEND_DATA" on the target machine, in which you put these 2 lines:
tcpdump -i iface1 -w - | nc <IP> <PORT1>
tcpdump -i iface2 -w - | nc <IP> <PORT2>
Every machine has netcat, so it works. You mark SEND_DATA executable
Next, you open a listening port on your PC, and run the script on remote machine:
> OUT1 nc -l -p PORT1
> OUT2 nc -l -p PORT1
ssh remotehost SEND_DATA
In this moment, the files OUT1 & OUT2 will start receiving data.
You also need to consult the manuals from 2 versions of nc, because I saw that the parameters differ sometimes.
The two ssh's is probably the nicest method, but you could also sed 's/^/one /' on the first one, in the background, and sed 's/&/two /' on the second, and then pull them apart on the local host with "egrep '^one ' | sed 's/one //'" for example.
You could also save the output in a pair of files, and scp them back when "done".
ssh remotehost "tcpdump -iiface1 -w- &
tcpdump -iiface2 -w- >&2 2>/dev/null" >iface1_dump.pcap 2>iface2_dump.pcap

Resources