« Archives in August, 2005

Redirecting TCP Ports with SSH

SSH impresses me each time I play with it. It is so powerful, that most of the time (90%) of the time, you aren’t using it to its greatest potential.

Here is a neat trick for creating a SSH tunnel to forward TCP based packets (this doesn’t work for UDP packets) between two servers on the internet.

You run this on the server who’s port you want to forward.

ssh -C -N -f -L localport:thelocalhostip:remoteport remoteuser@remotehost1

Here is what that will do: This will open a tunnel between localhostip:localport to remotehost1:remoteport.

What can you do with it? Well lets take a real world example. Lets say we want to forward all SMTP traffic from one server in the datacenter to another server on the other side of the world. You can do:

ssh -C -N -f -L 25:192.168.1.69:25 root@1.2.3.4

You will be prompted for a password if you don’t have authorized keys setup between the current server and the remote server (a subject for another post).

What you should be able to do is telnet to 192.168.1.69 25 and see the greeting from the SMTP server running on port 25 on 1.2.3.4.

I only used SMTP as an example, I know that there are several MTA based options that can do the same thing. However this is a good option to help make sure mail keeps flowing from an old server to a new server, if you didn’t set your TTL to a low setting when migrating servers (not that I would ever forget to do anything like that 😉 ).

You can also string more than one port on the command by adding additional -L localport:localip:remoteport.

As an added benefit this also encrypts the information between the two servers… So an added layer of security to things. Also the -C option enables compression on the tunnel for additional savings in bandwidth… See I told you SSH was cool.

More Shell Scripting Fun

Here is another thing I encountered just now… when you use cat to read the contents of a file into a bash variable, it tends to lose its formatting with out a really good way to preserve that formatting. To preserve the formatting from a catted file inside a bash variable use the following:

VAR=$(/bin/cat -E /path/to/file/filename.txt)

The -E option for cat will place $ for each end of line, then use this to convert them to something we can use:

NEWVAR=$(echo $VAR | sed ‘s/$ /\\n/g’)

This will replace the $ and the [space] that follows it with \n, then we use echo’s -e option to convert the \n’s to line feeds.

echo -e $NEWVAR > /path/to/file/newfilename.txt)

There is another option for cat (-A) that outputs newlines as $ and tabs as ^I, however I am unable to pattern match the ^I because I can’t figure out the key combo to make a match to it. (CTRL+V then CTRL+I and CTRL+V then TAB do not produce a ^I).

Bash Oneliner of the Day

From time to time in my day, I need to do a bunch of edits quickly and easily, so I make up these quick little one line bash scripts to do this for me. From time to time I will post them here so that other might be able to bask in the glory that is a handy dandy “oneliner”.

So… Lets kick this blog of the proper way, with a “oneliner” bash script that will parse all the files in the current directory and rename them with a new name.

for i in `find ./ -name “*template*” -type f`; do mv $i `echo -n $i | sed ‘s/template/quickform/’`; done

Pretty simple huh? What does it do I hear you ask? Well lets break it down (remember that “ or backticks causes everything inside the back ticks to be executed).

for i in `find ./ -name “*template*” -type f`; goes out and searches the current directory for any file (-type f) who’s name contains template and then passes each returned result and places its value in the variable i.

do mv $i `echo -n $i | sed ‘s/template/quickform’`; do is executed each time the value of $i changes from the previous for statement. What this does is executes mv $i and then we echo out the current value of $i to sed via a pipe (used to pass information from one application to another) to sed’s search and replace command (s/needle/replacement) to change the word template in the variable $i with quickform.

done just tells bash that the script is over and to start on the next loop if there is one.

That is all for now… stay tuned for cool things you can do with SSH.