All along we've assumed that your outgoing connectivity is unlimited: that you can establish any outgoing TCP connection you desire. Even our discussions of firewalls have assumed that they restrict only incoming traffic. In more secure (or simply more regimented) environments, this might not be the case: in fact, you might not have direct IP connectivity at all to the outside world.
In the corporate world, companies commonly require all outgoing connections to pass through a proxy server or gateway host : a machine connected to both the company network and the outside. Although connected to both networks, a gateway host doesn't act as a router, and the networks remain separated. Rather, it allows limited, application-level access between the two networks.
In this case study, we discuss issues of SSH in this environment:
Connecting transparently to external hosts using
Running SSH-within-SSH by port forwarding
Suppose your company has a gateway host, G, which is your only gateway to the Internet. You are logged into a client host C and want to reach a server host S outside the company network, as shown in Figure 11-14. We assume that all three machines have SSH installed.
To make a connection from client C to server S now requires two steps:
Connect from C to gateway G:
# Execute on client C $ ssh G
Connect from G to server S:
# Execute on gateway G $ ssh S
This works, of course, but it requires an extra manual step on the gateway, a machine you don't care about. Using agent forwarding and public-key authentication, you can avoid entering a passphrase on gateway G, but even so, the additional hop ideally should be transparent.
Worse, you can't transparently execute remote commands on server S from client C. Instead of the usual:
# Execute on client C $ ssh S /bin/ls
you must run a remote
ssh on gateway G that in turn contacts server S:
# Execute on client C $ ssh G "ssh S /bin/ls"
This isn't only annoying but also can complicate automation. Imagine rewriting all your SSH-based scripts to accommodate this environment.
Fortunately, SSH configuration is flexible enough to afford a neat solution, which we now present using SSH1 features and syntax. We use public-key authentication to take advantage of the options of the authorized_keys file, and
ssh-agent with agent forwarding so that authentication passes on transparently to the second SSH connection (see Figure 11-15).
Suppose your account on gateway G is gilligan, and on server S it is skipper. First, set up your SSH client configuration file so the name S is a nickname for accessing your account on gateway G:
# ~/.ssh/config on client C host S hostname G user gilligan
Next, on gateway G, associate a forced command with your chosen key to invoke an SSH connection to server S: See Forced Commands
# ~/.ssh/authorized_keys on gateway G command="ssh -l skipper S" ...key..
Note that if you want to use this setup for an interactive connection, you need to use the
Now, when you invoke the command
ssh S on client C, it connects to gateway G, runs the forced command automatically, and establishes a second SSH session to server S. And thanks to agent forwarding, authentication from G to S happens automatically, assuming you've loaded the appropriate key. This can be the same key you used to access gilligan@G or a different one.
This trick not only provides a transparent connection from client C to server S, it also sidesteps the fact that the name S might not have any meaning on client C. Often in this kind of network situation, your internal network naming scheme is cut off from the outside world (e.g., split DNS with internal roots). After all, what's the point of allowing you to name hosts you can't reach? Thanks to the
Host configuration keyword for SSH clients, you can create a nickname S that instructs SSH to reach that host transparently via G.
Daniel J. Barrett has been immersed in Internet technology since 1985. Currently, he is working as a software engineer. He is the author of O'Reilly's Linux Pocket Guide, and the coauthor of two more O'Reilly books: Linux Security Cookbook, and SSH, The Secure Shell: The Definitive Guide.
Richard E. Silverman first touched a computer as a college junior in 1986, when he logged into a DEC-20, typed "MM" to send some mail, and was promptly lost to the world.
View catalog information for SSH, The Secure Shell: The Definitive Guide
Return to ONLamp.com.
Copyright © 2009 O'Reilly Media, Inc.