Search code examples
sshexpectportforwardingnetcat

Using tcl/expect to prepare a tunnel


As part of a bigger plan (jumping through a bunch of hops and then create a port-tunnel to mongodb in a setup that PortForwarding is disabled) I attempted to create a tcl/expect script to verify if it is possible to relay a stream prepared by tcl/expect.

Here is my experiment:

# terminal 1 [listen to 2000]
nc -l 2000

# terminal 2 [listen to 200 then connect it to 2000 using expect]
socat tcp-l:200 system:'./nc-test.exp'

# terminal 3 [connect to 200]
nc localhost 200

and my tcl/expect simple script (nc-test.exp):

#!/usr/local/bin/expect

log_user 0
spawn nc localhost 2000
stty raw -echo
interact -o -nobuffer

Now the issue is everything I write in terminal 3 echos back to myself. Strangely this doesn't happen when I connect socat directly to nc localhost 2000 or when I directly execute tcl/expect script. Could you please help me figure

  • What is causing the unwanted echo?
  • Is my bigger plan feasible? (My main worry is keeping the stream raw)

Solution

  • The stty command in the expect script is acting on /dev/tty, which is probably the tty in terminal 2. However, spawn creates another pty to talk with the command it launches. That tty will inherit from the current tty, i.e. terminal 2, so will have echo on. It might be enough to simply move the stty raw -echo line to before the spawn, or more explicitly you can set the stty setting to be used by spawn by a command like

    set stty_init "raw -echo"
    

    before the spawn.