Creating Secure Tunnels With ssh
If you manage remote servers or if you have more than one computer you most likely have used the ssh command. A simple description of ssh is that it's a secure version of telnet, but that's like saying a Porsche is a just a better version of a Volkswagen bug.
Amoung other things, the ssh command allows you to setup secure tunnels to remote computers. One example of creating a tunnel that I use often is to use phpmyadmin to look at the database on a remote server without having to have phpmyadmin actually installed on the remote server.
To do this I simply install phpmyadmin on my local system then I use ssh to create a tunnel to the server that I want to interact with. This means I don't have to have phpmyadmin installed remotely and I don't have to maintain multiple phpmyadmin installations if I manage more than one server.
Now of course, mysql is network capable to begin with so it's also possible to just setup phpmyadmin on your local system to talk directly to mysql on the remote server. However, for security reasons you may not want to have mysql listening directly on a public interface: have it listen on localhost but not on the internet.
The essence of this type of tunnel is to start ssh and tell it to listen on a local TCP/IP port and to have it forward any traffic that it sees on that port to a particular port on the remote side. The normal mysql port is 3306, so what you can do is tell ssh to listen on port 3308 on your local computer and forward that to port 3306 on the remote side.
For example, if the remote server in question was myserver.example.com you could run the following command on your local system to create a tunnel as described above:
ssh -T -N -L 3308:localhost:3306 myserver.example.com
The meat of the command is the -L option, which tells ssh to listen on port 3308 locally and then on the remote side to forward all traffic on that port to localhost:3306. Note that the localhost here is not referring to the local system but rather where to forward things to on the remote side, in this case to localhost on the remote side.
The -T command disables allocation of a tty and the -N command disables the running of a command (eg your login shell) on the remote side. This means that this instance of ssh won't act like a terminal, it's just for port forwarding.
You can test the tunnel using the command line interface to mysql on your local system. You may need to specify the host name or address in the command:
$ mysql -P 3308 -u USERNAME -pPASSWORD DATABASE
# OR
$ mysql -h localhost -P 3308 -u USERNAME -pPASSWORD DATABASE
# OR
$ mysql -h 127.0.0.1 -P 3308 -u USERNAME -pPASSWORD DATABASE
If that works then your tunnel is set up. Now all you need to do is configure phpmyadmin, which I leave as an exercise since the point here is tunnels not phpmyadmin.
This type of tunneling capability only represents some of what you can do with ssh tunneling. For example, suppose myserver.example.com were actually a firewall that protected, amoung others, the system private.local. The system private.local is accessible from myserver.example.com but not from the internet directly. So, now you could run:
ssh -T -N -L 3308:private.local:3306 myserver.example.com
Here, ssh listens on port 3308 on the local system and it forwards that data to port 3306 on private.host, but it does that via the server myserver.example.com. In other words the local traffic on port 3308 gets transferred first to the remote system which then transfers it to port 3306 on private.host. Of course, if private.local's mysql server is only listening on its local interface this won't work, you'll need something more involved.
Another type of tunneling you can do is to reverse the tunnel: rather than using -L you can specify -R so that the listen side of the tunnel is on the remote side rather than on the local side. For example, suppose phpmyadmin was installed on myserver.example.com and you wanted to allow somebody using that phpmyadmin installation to connect to the mysql instance running on your local system. Just substitute -R for -L in the first ssh command above:
ssh -T -N -R 3308:localhost:3306 myserver.example.com
Here the remote ssh listens on port 3308 of myserver.example.com and then forwards traffic on that connection to port 3306 on your local system. Note that by default ssh is only listening on the localhost interface of the remote system so if the remote phpmyadmin install is secure your local system will also be secure. Remember that you still run this ssh command from your local system, you don't run it from the server (and unless your system is routable you probably couldn't successfully execute it on the remote system anyway).
To test the connection, on the remote system execute the command line mysql client using the same commands as we used above. This should connect to the database on your local computer. Again the configuration of phpmyadmin is left as an exercise.
Mitch Frazier is an Associate Editor for Linux Journal.
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Home, My Backup Data Center
- What's the tweeting protocol?
- New Products
- RSS Feeds
- Readers' Choice Awards
- Dart: a New Web Programming Experience
- Reply to comment | Linux Journal
12 hours 29 min ago - Reply to comment | Linux Journal
15 hours 1 min ago - Reply to comment | Linux Journal
16 hours 19 min ago - great post
16 hours 53 min ago - Google Docs
17 hours 16 min ago - Reply to comment | Linux Journal
22 hours 4 min ago - Reply to comment | Linux Journal
22 hours 51 min ago - Web Hosting IQ
1 day 25 min ago - Thanks for taking the time to
1 day 2 hours ago - Linux is good
1 day 3 hours ago
Enter to Win an Adafruit Prototyping Pi Plate Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Prototyping Pi Plate Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- Next winner announced on 5-21-13!
Free Webinar: Linux Backup and Recovery
Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.
In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.



Comments
Tunnel ok, but MySQL won't connect over tunnel
1) I start the tunnel: ssh -L 3307:localhost:3306 remote
(where 'remote' is the remote host)
2) I can test with: telnet localhost 3307. The remote MySQL's version appears
3) I try to connect: mysql -P 3307 -h localhost user@remote mybase
and get connected to the local database (version is local MySQL's, the data is local, and no network activity.
The local MySQL is running on 3306. AllowTcpForwarding and GatewayPorts are enabled in sshd_config.
Suggestions?
(Also tried with a tunnel 81:localhost:80, which gives me access to the remote website on my local port 81 - works fine. So I guess the problem lies with MySQL?)
127.0.0.1
Try this:
or this
Check these two bug reports: bug report 1 and bug report 2.
If I'm understanding what they're saying there: "-h localhost" essentially means "Use a Unix Domain Socket" (and ignore the -P option) and "-h 127.0.0.1" means use TCP/IP. Specifying "--protocol=tcp" forces the use of TCP/IP.
This explains why the use of "localhost" has always given me problems. And I agree with one of the commentors that says this behavior is "INSANE".
Mitch Frazier is an Associate Editor for Linux Journal.
[solved] Thanks!
This explains why the use of "localhost" has always given me problems. And I agree with one of the commentors that says this behavior is "INSANE".
That is putting it mildly . I could have expected localhost not to work because of lookup problems, but not this!
Thanks - it solved my problem!
John
got error :(
thanks for good article
but I have problem with this solution:( mysql server is running,but when I want to connect to mysql server by this way,I get this error:
"ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)"
thanks for any help or guidance
Not Using TCP/IP
That means that mysql is trying to connect to the server using a "UNIX Domain Socket" rather than a TCP/IP socket. Did you specify the -h and -P options?
Mitch Frazier is an Associate Editor for Linux Journal.
Thanks
Thanks for the info.. Nice article.
Ok, but...
Hi,
there is also cool option to detach the terminal - its -f. When used, ssh goes background after tunnel creation.
There is also possibility to create tunnels "on the fly", when you're already connected to remote host. man ssh (under ESCAPE CHARACTERS) says:
" ~C Open command line. Currently this allows the addition of port forwardings using the -L, -R and -D options (see above). It
also allows the cancellation of existing remote port-forwardings using -KR[bind_address:]port. !command allows the user to
execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h
option."
Reverse SSH tunnel
Also, don't forget reverse SSH tunnel. This is similar, except that the tunnel established work in "reverse".
So, if you establish a tunnel from A to B, you'll then be able to connect from B to A. This is great when you want to connect to something behind a firewall.
ssh tunnels
Hi Mitch-
You forgot to mention the most powerful and best tunnel of them all... -D !
Let's say that where you work has a fascist web web filter policy and blocks sites like this one Let's say they also allow ssh outbound. (or you configured your sshd to listen to a non-standard port that is not filtered, like 53 or 33123.
you can run a standalone SOCKS 5 proxy by sshing to that remote host with the -D and all your traffic will come out from the remote machine.
simply do a ssh -D 12345 my.linux.at.ho.me
then set your app to use a socks 5 proxy at localhost:12345
works like a charm!
you can also ease the -D, -L -R typing pain by writing your own .ssh/config.
circumventing Websense can be fun!
-L is ancient history
It's still useful in plenty of cases, so it is worth exploring. But no mention of -L is complete w/o giving -w at least a sidebar. The -w option is what permitted SSH to make the leap from mere tunnels to a real VPN capability.