2

Is there any way to listen and execute a command ( for every connection ) while port forwarding with socat? A non-working example to make it more clear:

socat TCP-LISTEN:8080,reuseaddr, "exec:ls" fork tcp:localhost:80

hyogy
  • 23
  • 1
  • 5

1 Answers1

3

Like this?

socat tcp-listen:8080,reuseaddr,fork system:'ls; exec socat - tcp\:localhost\:80'
  • 1st parameter gets ,fork to have socat stay listening for more connections

  • system: is preferred over exec: to have a shell interpreter and easily run an additional command after the ls command,

  • which is a new socat command

    which will have stdin/stdout connected to the remote client's output/input and will forward it bidirectionally again to the next destination. Note that its : separator (and a few other special characters) must be escaped with a \ to not confuse the first socat command. If this line becomes more complex it become easier to simply exec a script like this:

    socat tcp-listen:8080,reuseaddr,fork exec:/path/to/myscript.sh
    

    with /path/to/myscript.sh:

    #!/bin/sh
    ls
    exec socat - tcp:localhost:80
    

    exec in the shell command is optional but avoids uselessly leaving around the shell.

socat also exports a few variables of its own that can be reused in the script, that you could check for example like this (with a connection made):

$ env - socat TCP-LISTEN:8080,reuseaddr,fork exec:printenv
SOCAT_PID=1057351
SOCAT_PPID=1057284
SOCAT_VERSION=1.7.4.1
SOCAT_SOCKADDR=127.0.0.1
SOCAT_SOCKPORT=8080
SOCAT_PEERADDR=127.0.0.1
SOCAT_PEERPORT=42970
A.B
  • 11,090
  • 2
  • 24
  • 45
  • This is amazing! Thanks!(: Just one more tip please: using that line, how would you decode strings in base64? I mean: the data passing through port 8080 are base64 encoded, but I want to decode it before the data reach port 80 ( the data coming back from port 80 must not be encoded ) – hyogy Jul 27 '21 at 07:33
  • 1
    As soon as you use a pipe somewhere (eg: `base64 -d | socat ... `), communication won't be completely bidirectional. Then this probably requires forking some commands in the script to get two half directions working . You should expose (probably in a different question) your full problem. Check https://xyproblem.info/ . You think you can solve it with Y = socat, but we don't know anything about X. Even if socat can solve it, I can't tell because I don't know your problem. – A.B Jul 27 '21 at 09:05
  • Thanks for your kind help!! I will come up with a new question and I will notify you if you want!(; – hyogy Jul 27 '21 at 09:53
  • 1
    actually for this specific case it's easy, except you get a problem with timing: no way to know when input ends so the communication has to end first and there probably won't be a reply sent back in time then. here's the line to put in myscript.sh : `exec base64 -d | socat - tcp:localhost:80`. `-` means STDIO, and while input comes from `base64 -d` output is sent back unaffected, as written in the comment. – A.B Jul 27 '21 at 10:11
  • I posted the relative question if you are interested in (: https://serverfault.com/questions/1070792/bidirectional-communication-unidirectional-decode – hyogy Jul 27 '21 at 12:30
  • You just rewrote an XY problem, while I already gave the answer in comments. My comment told it was working bidirectionally in the end. Sorry if that's not what I wrote in the former comment. – A.B Jul 27 '21 at 15:35
  • I got the perfect solution, check the question if you want!(: – hyogy Jul 27 '21 at 17:34