Bash has network support

I was writing an script last night, and I found a problem.

I have a mysql server with some database and some stuff that I have to query sometimes. So, to make make life easier, I simply tunnel the tcp connection using ssh.

$ ssh -L 12345:localhost:3306 -N -f myserver.com

This starts listening on the port 12345 of my machine, and forwards everything to the port 3306 at myserver.com. It works pretty well, and it is quite secure and easy to setup.

But the thing is that, if you run it twice, it will ‘fail’, but the ssh is still running. So, if you have a cron file, you will end up with lots of ssh sessions in background.

Wat?

I tried to figure out how I can check if the port is already used on my machine, to dont launch ssh in that case.

And I found that, surprisingly, bash has built-in functions for network support!! everything goes through /dev/tcp/<addr>/<port> , it is a “hidden file” where you can read and write.

$ exec 3<>/dev/tcp/www.google.com/80
$ echo "GET /" >&3
$ cat <&3

This will connect to google (a popular website that sysadmins use to check availability) , and get some page. It created a file descriptor, number 3, where you can send or read data.

You can, for example, write a simple port scanner:

$port = 1; while [$port -lt 1024];do echo > /dev/tcp/<TARG_IP>/$port;
 [$? == 0] && echo $port "is open" >> /tmp/ports.txt; port = 'expr 
$port + 1'; done;

Ok, now my script seems very easy:

#!/bin/bash

LOCALPORT=3333
FD=6exec ${FD}<>/dev/tcp/127.0.0.1/${LOCALPORT} 2>/dev/null && exit
ssh -L 12345:localhost:3306 -N -f myserver.com

Leave a comment