Server Administration

  Home arrow Server Administration arrow SSH Case Studies: Gateway Hosts

SSH Case Studies: Gateway Hosts
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating:  stars stars stars stars stars / 0

    Table of Contents:
  • SSH Case Studies: Gateway Hosts
  • 11.4.2 Using SCP Through a Gateway



    SSH Case Studies: Gateway Hosts

    (Page 1 of 2 )

    In this tenth part of a nineteen-part article series on the secure shell, we'll study the issues related to using SSH in an environment that requires outgoing connections to go through a proxy server or gateway host, as you would commonly find in the corporate world. This article is excerpted from chapter 11 of the book SSH, The Secure Shell: The Definitive Guide, Second Edition, written by Daniel J. Barrett, Richard E. Silverman and Robert G. Byrnes (O'Reilly; ISBN-10: 0596008953).

    11.4 Connecting Through a Gateway Host

    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 chained SSH commands
    • Making scp connections to these hosts
    • Running SSH-within-SSH by port forwarding
    • Running SSH-within-SSH byProxyCommand

    These gateway techniques apply equally well when the situation is reversed: you’re on an external machine, and need to access various internal hosts through a single SSH gateway.

    11.4.1 Making Transparent SSH Connections

    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-11. We assume that all three machines have SSH installed.

    Figure 11-11. Proxy gateway

    To make a connection from client C to server S now requires two steps:

    1. Connect from C to gateway G:

      # Execute on clientC
      $ ssh G

    2. Connect from G to server S:

      # Execute on gateway G
      $ ssh S

    This works, and using agent forwarding and public-key authentication on both hosts, you can avoid a second authentication prompt on gateway G.

    Now, an obvious simplification would be this single command:

    $ ssh G ssh S

    If you do this, though, you’ll have a problem: first, you’ll see this warning:

    Pseudo-terminal will not be allocated because stdin is not a terminal.

    ...and next, your shell on S will behave very strangely! You won’t get a prompt, or any fancy line-editing—but if you persist and enter some commands, they will get executed. The problem is that ssh only creates a pseudo-terminal, needed for interactive terminal-based programs, if you explicitly request a remote shell session; to ssh, this means that you do not specify a remote program to run. By default, it assigns no terminal when running remote commands like ssh host uname -a. Most of the time this is a reasonable default, but sometimes you’ll run a remote command that actually needs a terminal—in this case, the shell! You can fix this with the –t switch for force a pseudo-terminal:

    $ ssh -t G ssh S

    But this introduces yet another messy aspect: to reach hosts through the gateway, you not only have to use double-ssh commands, but furthermore, specify –t in some cases but not others. Not a big burden for occasional use, perhaps, but cumbersome if large numbers of hosts or automation are involved.

    Fortunately, SSH configuration is flexible enough to afford a neat solution, which we now present using OpenSSH 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-12).

    Figure 11-12. Chained SSH connections through a proxy gateway

    Suppose your account on gateway G is gilligan, and on server S it is skipper. First, set up your SSH client configuration file so that 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: [8.2.3]

    # ~/.ssh/authorized_keys on gatewayG
    command="ssh -l skipper S" ...key.

    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 theHostconfiguration key-word for SSH clients, you can create a nickname S that instructs SSH to reach that host transparently via G. []

    You’ll soon notice a problem, though. Interactive logins work fine, but remote commands are ignored! And worse, the missing terminal problem rears its head again:

    $ ssh S echo Hello
    Pseudo-terminal will not be allocated because stdin is not a terminal.

    You’re left talking to a mute shell, and no “Hello” appears. The problem now is that we’ve done nothing to pass along any remote command to S; the forced command on G simply ignores it and always tries to start a remote-login SSH connection (hence provoking the missing terminal problem, as before). We can fix this using another OpenSSH feature:†

    command="ssh -l skipper S $SSH_ORIGINAL_COMMAND" ...key...

    If a remote command is used, sshd stores it in the environment variableSSH_ORIGINAL_COMMAND; we use that here to pass it along to the next ssh command. The variable is not set, however, if there is no remote command. Some shells consider this an error, so you might have to augment this in some way to accommodate the shell’s predilections. For example, some shells have this syntax:

    command="ssh -l skipper S ${SSH_ORIGINAL_COMMAND:-}" ...key...

    where ${foo:-bar} evaluates to “bar” if the variable foo is not set. And remember, the shell used here is the one belonging to the remote account; to be especially robust, it might be best to use a particular shell explicitly:

    command="/bin/bash -c 'ssh -l skipper S ${SSH_ORIGINAL_COMMAND:-}'" ...key...

    This technique also neatly solves the “missing terminal” problem at the same time!

    More Server Administration Articles
    More By O'Reilly Media

    blog comments powered by Disqus


    - SSH Case Studies: Gateway Hosts
    - SSH Case Studies: More on Pine and SSH
    - SSH Case Studies: Pine and IMAP
    - SSH Case Studies: More on the Passive Mode
    - SSH Case Studies: Network Address Translation
    - SSH Case Studies: The Passive Mode
    - SSH Case Studies: The FTP Protocol
    - SSH Case Studies: Batch Jobs, FTP and SSH
    - SSH Case Studies: Agents and Authentication
    - SSH Case Studies
    - Server Responses to Client Communication
    - Authentication in Client/Server Communication
    - Client/Server Communication
    - Understanding Awk in the UNIX Shell
    - Stream Editor in the UNIX Shell

    Developer Shed Affiliates


    © 2003-2019 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap