your site name
 
 What's New

HTML color codes and names
Linux / Unix tar command
Upgrading from MySQL 4 to 4.1

Information on batch files

How to create a boot disk

Visitor favorites
Information


 

 

Advanced SSH configuration and tunneling: We don’t need no stinking VPN software

 

Introduction

An ad-hoc forward of a specific port or two from the command line can be very handy, for example forwarding a work-only accessible wiki to your home machine, or from a local coffee shop so that you can read it. But there is a better way to architect a permanent solution. Many people don’t realize that it is completely possible to access at home every single resource that you have at work by simply creating SSH configuration files that have comprehensive tunneling instructions. Contrary to popular belief, this does not require VPN software. It requires only an open SSH port, which can be listening on port 22 or 4010. It doesn’t matter. While this is bad news for commercial vendors of VPN software, it is good news for you.

The world has changed, and now people work from home, from the road, and from the coffee shop. In addition, IT workers often use virtual machines running on their laptops to simulate production environments. By creating comprehensive SSH tunneling configurations, it is possible to make a remote machine, along with virtual machines, completely integrated into a production environment.

About SSH config files

Although reading a man page for something as big as SSH can be daunting, I would suggest doing a cursory skim through some of the options. It is always a good idea to do at least some skimming before engaging in heavy duty use of a command line tool in ways you have never used it before. There are two configuration files to be aware of for this article. The system-wide configuration file lives in /etc/ssh_config , and the user ssh file lives in ~/.ssh/config.

Since this is a more advanced article on SSH, it is important to know the distinction between the system-wide configuration file and the user configuration file. If you run a system cron job and would like SSH forwarding to be involved, it is important to note that the /etc/ssh_config file needs to be edited. If you need to enable forwarding for a user shell, which is most typical, then you should edit the user configuration file. The SSH config files also have a man page (man ssh_config), and it would be helpful to view that man page as well.

Creating A Basic SSH Config File

Getting basic requirements together

The basics of a creating a customized config file are easy. The general idea is to create a configuration that forwards local ports that bind to ports on a remote machine. While you are setting up your SSH configuration file, it would be a good to keep the iana.org list of ports handy. This will help you decide what port IMAP uses, for example.

A work network behind a firewall may consist of the following resources that are not accessible from outside of the local area network.

SMTP Server:  192.168.0.100			Port:  25	DNS Name:  smtp.pretendco.com
Corporate Wiki:  192.168.0.110			Port:  8080    DNS Name:  wiki.pretendco.com
IMAP Mail Server:  192.168.0.120		Port:  143	DNS Name:  imap.pretendco.com
Subversion Server:  192.168.0.140		Port:  22	DNS Name:  svn.pretendco.com
NFS Server:  192.168.0.150			Port:  2049	DNS Name:  nfs.pretendco.com
SMB/CIFS Server:  192.168.0.160		Port:  3020	DNS Name:  smb.pretendco.com
SSH Server:  192.168.0.170			Port: 22	DNS Name.  dev.pretendco.com
VNC Server/Dev Machine:  192.168.0.180 	Port:  5900	DNS Name:  vnc.pretendco.com

All that is needed to gain access to these resources from elsewhere is to have a publicly accessible SSH server with one open port inside of the LAN. Let’s suppose this server is called ssh.pretendco.com and that it has sshd (the SSH daemon) listening on port 5001. We can now build an SSH config file based on this information.

Understanding options

Now that we have a list of internal IP addresses, DNS names, and the ports with the services we would like to access, we can create a configuration file with a set of cascading configuration options. SSH has many helpful options that I would recommend perusing in the ssh_config man page. We are going to focus on the following options:

The most basic of configuration parameters. This gives you the ability to designate sections of the config file by hostname and pattern. For example:

Host *  (this means a section applies to every host)
Host ssh.pretendco.com (this means it only applies to ssh.pretendco.com)

Hostname:
You can nest multiple host configurations to create custom setups and alias hostnames so that they appear locally like they do at work. For example, a localhost:8080 tunnel could be turned into an alias like:

Host wiki.pretendco.com
	Hostname localhost
	Port 2200

This is handy because it allows you to completely simulate working inside of a local area network. And if you have scripts or configuration files that are hard coded to work with names inside of your LAN, then you will very much enjoy using this configuration.

ServerAliveInterval: This option can be configured to send a message every N seconds to a remote server so that a connection will not die. By default it is set to 0 seconds.

Host and Hostname are really the only options you will need for most configurations, but knowing about other options like ServerAliveInterval and ServerAliveCountMax can be helpful too. Now that we have the basic requirements and understand how to use the options, let’s write a configuration file that will create our VPN to work.

Writing ~/.ssh/config

Here is a configuration file based on the things we just talked about. You should be able to use this as a template by plugging in the names and ports of the devices you would like to connect to.

If you have a config file in ~/.ssh/config, make a backup and move the original file. You can do something like this:

cd ~/.ssh/
mv config backup_config_file

Now you can cut and paste this into a new file you call config.

###SSH Port Forwarding Configuration###

####Global Configuration Options###

#Host * will apply to all hosts
Host *
    ServerAliveCountMax 4       #Note default is 3
    ServerAliveInterval 15      #Note default is 0

####Port Forwarding Directives###

#Network Reference, Cheat Sheet:
#Refer to http://www.iana.org/assignments/port-numbers for full list of port numbers
#SMTP Server:  192.168.0.100         Port:  25   DNS Name:  smtp.pretendco.com
#Corporate Wiki:  192.168.0.110          Port:  8080    DNS Name:  wiki.pretendco.com
#IMAP Mail Server:  192.168.0.120        Port:  143  DNS Name:  imap.pretendco.com
#Subversion Server:  192.168.0.140       Port:  22   DNS Name:  svn.pretendco.com
#NFS Server:  192.168.0.150          Port:  2049 DNS Name:  nfs.pretendco.com
#SMB/CIFS Server:  192.168.0.160     Port:  3020 DNS Name:  smb.pretendco.com
#SSH Server:  192.168.0.170          Port: 22    DNS Name.  dev.pretendco.com
#VNC Server/Dev Machine:  192.168.0.180  Port:  5900 DNS Name:  vnc.pretendco.com

#(Note we just made up the name workTunnel.)
#The workTunnel alias holds both the nested ssh server configuration,
#and the actual port forwarding directives.
#Note you can forward to either an IP Address or a hostname.

Host workTunnel
    #Work SSH Server To Initiate Tunneling From
    Host ssh.pretendco.com
    Port 5001

    # SMTP Server
    LocalForward localhost:2525 smtp.pretendco.com:25 

    # Corporate Wiki
    # Note I am forwarding to an IP address just to show that you can.
    LocalForward localhost:8080 192.168.0.110:8080

    # IMAP Mail Server
    LocalForward locahost:1430  imap.pretendco.com:143

    # Subversion Server
    LocalForward locahost:2222  svn.pretendco.com:22

    # NFS Server
    LocalForward locahost:2049  nfs.pretendco.com:2049

    # SMB/CIFS Server
    LocalForward locahost:3020  smb.pretendco.com:3020

    # SSH Server
    LocalForward locahost:2220  dev.pretendco.com:22

    # VNC Server
    LocalForward locahost:5900  dev.pretendco.com:5900

###Hostname alias directives###
#These allow you to mimic hostnames as they appear at work.
#We just take the localhost names from the above section and add alias names.
#Note that you don't need to use a FQDN; you can use a short name ,such as smtp instead of smtp.pretendco.com.

Host smtp.pretendco.com
    HostName localhost
    Port 2525

Host wiki.pretendco.com
    HostName localhost
    Port 8080

Host imap.pretendco.com
    HostName localhost
    Port 1430

Host svn.pretendco.com
    HostName localhost
    Port 2222

Host nfs.pretendco.com
    HostName localhost
    Port 2049

Host smb.pretendco.com
    HostName localhost
    Port 3020

Host dev.pretendco.com
    HostName localhost
    Port 2220

Host vnc.pretendco.com
    HostName localhost
    Port 5900

#End Config File

Using the SSH Tunnel

Once you customize the ~/.ssh/config file from the template shown above, you will need to open an SSH connection to the master alias, which holds the nested port forwarding for everyone. To do this, I would highly recommend connecting in SSH verbose mode first. SSH is extremely quiet by default, and it will be a good idea to use a -v option as shown below:

ssh -v workTunnel

If you configured things correctly, you should see output that looks like this:

....................
debug1: Local connections to localhost:2200 forwarded to remote address svn.pretendco.com:22
debug1: Local forwarding listening on ::1 port 2200.
debug1: channel 0: new [port listener]
debug1: Local forwarding listening on 127.0.0.1 port 2200.
debug1: channel 1: new [port listener]
debug1: Local connections to localhost:2222 forwarded to remote address dev.pretendco.com:22
debug1: Local forwarding listening on ::1 port 2222.
debug1: channel 2: new [port listener]
debug1: Local forwarding listening on 127.0.0.1 port 2222.
......................

Tip:
Something very important to note, is that if you setup a HostName alias properly, then you can perform an ssh directory to that resource, just as you would inside of work. For example, if you need to access your inside the firewall you can type:

svn list svn+ssh://svn.pretendco.com/project

If you need to access a machine with a protocol other than ssh, say your internal wiki running on port 8080, then you can quite simply add an alias to your /etc/hosts file as show below:

# that require network functionality will fail.
127.0.0.1   localhost.localdomain   localhost wiki
::1 localhost6.localdomain6 localhost6

You can always get to the forwarded wiki port by using:

http://localhost:8080

But, with the change to the /etc/hosts file you can also access it this way:

http://wiki:8080

If you are really motivated you can also do port forwarding to a “privilaged port”, port 80, if you have a server running on port 80 inside of the firewire, and you would then get to the http resource like you would at work, be slightly changing the ssh configuration file. Please note you will also need to do tunneling with “sudo” privilages.

    # Internal Web Server running on port 80
    LocalForward locahost:80  web.pretendco.com:80

This then allows you to browse to http://web.

Conclusion

Now that you have a sophisticated SSH configuration set up, you can connect to resources in exactly the same way you connect at work because of the host alias directives we applied. If you have an internal wiki server at work and you applied your custom information to the template I have supplied, then you can just type in wiki:8080 (substituting your actual wiki server), and it will work. I hope you find this as cool as I do!

Please note that things are not exactly perfect though. When you get back to work, if you try to SSH into your development box, you will have a problem, as your configuration file is set up to think you are at home. There is a simple solution, though. (Remember this only applies SSH connections to machines you have listed in your config file.)

You can do quite a few things, and I will leave it to you to decide which to use:

1. You could customize your Bash or Z-Shell startup script to detect whether you are at home or at work, and then source configuration files based on what IP address your local machine is assigned.
2. You could create an alternate SSH file named remoteConfig and leave your regular config file blank. When you are at home or on the road, you can use ssh -F ~/.ssh/remoteConfig
3. An even easier way would be to make an alias out of option 2.

You can then create an alias in your bashrc file or your .zshenv file, that looks something like this:

alias stunnel='ssh -v -F ~/.ssh/remoteConfig workTunnel'

Now when you are at work, you use SSH like you normally do, but when you are on the road or at home you type in:

stunnel

With one command, you have access to your complete LAN in exactly the manner you use it at work, and you don’t need to muck around with writing conditional statements and sourcing bash config files to do it.

Summary

In this article we took ad hoc SSH tunneling and turned it into a full-blown VPN. I hope this took some of the mystery out of working from home via SSH tunneling and gave you an idea of how you can customize SSH tunneling to do just about anything.

I mentioned virtual machines in the beginning of the article, but then only hinted at how they could be included in this setup. As an exercise to the reader, I will leave integrating virtual machines to you. As a hint, look at how we aliased the stunnel command, and that should give you all the head start you need.

The information provided in this article is for your information only. The origin of this information may be internal or external to Red Hat. While Red Hat attempts to verify the validity of this information before it is posted, Red Hat makes no express or implied claims to its validity. Please review and comply with any relevant IT policies at your company.

Home - vps - webhosting - Dictionary