SSH is like the Swiss army knife of the unix and linux world. It is a tool that helps solve a variety of issues when it comes to passing traffic over port 22.
This post is going to be a collection of guides showing some of the various solutions that can be accomplished with SSH. This guide assumes you are running Linux on both your office and home workstations.
SSH proxies for web traffic
Suppose you are at a hotel on a public WIFI, and don’t have access to a VPN. How can you still surf the web securely? Assuming you have a server setup at home, or some other secure location, you can simply proxy all your traffic through your home server using an encrypted SSH tunnel.
On your local workstation, run the following:
[user@workstation ~]# ssh -D 7070 [email protected]
Now with the proxy setup, you can route your traffic through a SOCKS 5 proxy in your browsers configuration, or using a plugin such as FoxyProxy. Just be sure that under the SOCKS host, you use:
Host: 127.0.0.1
Port: 7070
Type: SOCKS v5
SSH proxies for SSH traffic
Using the same scenario, we’re still at the hotel using public WIFI, and don’t have access to a VPN. How can we pass our SSH traffic through a secure proxy server?
On your local workstation, run the following:
[user@workstation ~]# ssh -D 7070 [email protected]
Now configure your .ssh/config to pass all SSH traffic through the SOCKS proxy:
[user@workstation ~]# vim .ssh/config
...
# Filter through socks5 proxy
Host *
ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:7070 %h %p
IdentityFile ~/.ssh/id_dsa
ForwardAgent yes
GSSAPIAuthentication no
VerifyHostKeyDNS no
HashKnownHosts no
TCPKeepAlive yes
ServerAliveInterval 300
...
How to X forward applications located on remote servers
Lets suppose you want to access a specific application from your office computer not installed on your home workstation maybe, or want to be able to pick up where you left off on something. For this example, we’ll be accessing Firefox from the office computer, on the home computer.
This would be done on your home computer by:
[user@workstation ~]# ssh -X user@remoteserver firefox
What if you needed to access a internal Windows server from your home computer, but it was only accessible from your office computer? Assuming you can SSH to your office computer, you can run:
[user@workstation ~]# ssh -X user@remoteserver rdesktop -a 24 -u user -f 192.168.1.100
How to create a reverse SSH tunnel
Reverse SSH tunnels are useful when the firewall on the server you need to connect to is blocking inbound SSH connections, but allows for outbound SSH connections. So this is where we simply have the remote server behind the firewall establish the SSH tunnel.
Please understand the security implications of doing this! If you have the ability to use a VPN to access the remote server, use that instead!
On the remote server behind the firewall, create a SSH tunnel to your workstation by:
[root@remoteserver ~]# ssh -R 7022:localhost:22 user@yourworkstation
Now from your workstation, connect to the remote server by:
[user@workstation ~]# ssh -p 7022 localhost
If you want to keep this tunnel up so you don’t have to keep re-establishing the connection when/if it drops, you can script it on the remote server by placing the following script into a cronjob that runs every 5 minutes or something. You will need to have SSH keys in place prior to doing this:
[root@remoteserver ~]# vim /root/ssh-check-tunnel.sh
#!/bin/bash
# Create tunnel if its not established
COMMAND='ssh -N -R 7022:localhost:22 user@yourworkstation'
# Check to see if tunnel is currently up
CHECK_TUNNEL=`ps -eo args | grep "$COMMAND" | grep -v grep`
# If the tunnel is down, create it
if [ -z "$CHECK_TUNNEL" ] ; then
$COMMAND
fi
Then make it executable
[root@remoteserver ~]# chmod 755 /root/ssh-check-tunnel.sh
Finally, drop it into cron:
[root@remoteserver ~]# crontab -e
*/5 * * * * /root/ssh-check-tunnel.sh
How to access servers behind a NAT transparently
Here we will be creating an SSH VPN. However if a regular VPN is available, use that instead. Also understand the security implications of running this before you follow this guide!
To make this a bit easier to understand, here are our devices and IP’s:
workstation: Ubuntu based workstation
remoterouter: FreeBSD router running NAT
remoteserver: Server behind router with a private IP
Assuming you have a workstation running Ubuntu, and you want to be able to access servers that are behind a FreeBSD router running NAT, how can you go about accessing the private IP’s of those remote servers from your workstation simply by running:
[user@workstation ~]# ssh [email protected]
To do this, you need to create a tunnel from your workstation to the FreeBSD router that is providing the private IP’s to the remote servers.
On your workstation, create a SSH key pair without a passphrase (Just take the defaults), and copy that over to the FreeBSD router running NAT:
[root@workstation ~]# ssh-keygen -t dsa
[root@workstation ~]# scp /root/.ssh/id_dsa.pub root@freebsdrouter:/root/.ssh/authorized_keys
Then on your workstation, allow SSHD to create a tunnel:
[root@workstation ~]# vim /etc/ssh/sshd_config
...
PermitTunnel yes
...
Then restart SSH:
[root@workstation ~]# service ssh restart
Now comes the hard part, configure the tunnel interface on your Ubuntu workstation. This guide is assuming 10.1.0.100 and .200 are not in use already on your network. Please be sure to replace ‘remoterouter’ with the IP of your remote server:
[root@workstation ~]# vim /etc/network/interfaces
...
iface tun0 inet static
pre-up ssh -f -w 0:0 root@remoterouter 'ifconfig tun0 10.1.0.200 10.1.0.100'
pre-up sleep 5
address 10.1.0.100
pointopoint 10.1.0.200
netmask 255.255.255.0
up route add -net 10.10.10.0 netmask 255.255.255.0 gw 10.0.0.100 tun0
...
Note, if the remote router is running CentOS 5, you may need to run:
[root@remoterouter ~]# modprobe -av tun
[root@remoterouter ~]# echo modprobe tun >> /etc/rc.modules
[root@remoterouter ~]# chmod -x /etc/rc.modules
On your workstation, bring up the tunnel:
[root@workstation ~]# ifup tun0
Finally, wave a dead chicken over the alter and try to ping one of the servers behind the NAT:
[root@workstation ~]# ping 10.1.0.50
If that works, great! You just created an SSH VPN! You will be able to access any of your servers that are behind this NAT.
If the tunnel gets disconnected, you will need to run the following to re-establish the tunnel:
[root@workstation ~]# ifdown tun0
[root@workstation ~]# ifup tun0