One of SSH's major benefits is transparency. A terminal session secured by SSH behaves
like an ordinary, insecure one (e.g., created by telnet or rsh) once it has been established.
Behind the scenes, however, SSH keeps the session secure via strong authentication,
encryption, and integrity checking.
In some situations, however, transparency is hard to achieve. A network firewall might be in the way, interfering with certain network traffic you need. Corporate security policies might prohibit you from storing SSH keys on certain machines. Or you might need to use insecure network applications in an otherwise secure environment.
In this chapter, we'll discuss an important feature of SSH, called forwarding or tunneling, that addresses several concerns about transparency:
Securing other TCP/IP applications
SSH can transparently encrypt another application's data stream. This is called port
forwarding.
Securing X window applications
Using SSH, you can invoke X programs on a remote machine and have them appear, securely, on your local display. (This feature of X is insecure ordinarily.) This is called X forwarding, a special case of port forwarding for which SSH has extra support.
SSH forwarding isn't completely transparent, since it occurs at the application level, not the network level. Applications must be configured to participate in forwarding, and a few protocols are problematic to forward (FTP data channels are a notable example). But in most common situations, once a secure tunnel is set up, the participating applications appear to the user to operate normally. For complete application-level transparency, you need a network-level technique, such as IPSEC [Section 1.6.4] or a proprietary VPN
(Virtual Private Network) technology available from various vendors, in host software or dedicated routers. While VPNs provide a more complete solution, they require significantly more work and expense to set up compared to SSH forwarding.
So, when we say "transparent" in this chapter, we mean "transparent to the application, once a little configuration has been done."
In some situations, however, transparency is hard to achieve. A network firewall might be in the way, interfering with certain network traffic you need. Corporate security policies might prohibit you from storing SSH keys on certain machines. Or you might need to use insecure network applications in an otherwise secure environment.
In this chapter, we'll discuss an important feature of SSH, called forwarding or tunneling, that addresses several concerns about transparency:
Securing other TCP/IP applications
SSH can transparently encrypt another application's data stream. This is called port
forwarding.
Securing X window applications
Using SSH, you can invoke X programs on a remote machine and have them appear, securely, on your local display. (This feature of X is insecure ordinarily.) This is called X forwarding, a special case of port forwarding for which SSH has extra support.
SSH forwarding isn't completely transparent, since it occurs at the application level, not the network level. Applications must be configured to participate in forwarding, and a few protocols are problematic to forward (FTP data channels are a notable example). But in most common situations, once a secure tunnel is set up, the participating applications appear to the user to operate normally. For complete application-level transparency, you need a network-level technique, such as IPSEC [Section 1.6.4] or a proprietary VPN
(Virtual Private Network) technology available from various vendors, in host software or dedicated routers. While VPNs provide a more complete solution, they require significantly more work and expense to set up compared to SSH forwarding.
So, when we say "transparent" in this chapter, we mean "transparent to the application, once a little configuration has been done."
In this chapter, we discuss using SSH forwarding techniques to
allow otherwise prohibited traffic across firewalls. This can be a
perfectly legitimate and adequately safe practice if done properly:
the firewall prevents unauthorized traffic, while SSH forwarding
allows authorized users to bypass the restriction. However, don't
forget you are bypassing a security restriction that is in place for
a reason. Be sure to follow the guidelines we give for safe SSH
forwarding. Also, take care that you aren't violating a company
policy by using forwarding. Just because you can do something
doesn't automatically mean that it's a good idea. If in doubt,
consult with your system administrators.
Book: SSH, The Secure Shell: The Definitive Guide
Section: Chapter 9. Port Forwarding and X Forwarding
9.1 What Is Forwarding?
Forwarding is a type of interaction with another network application, as shown in Figure 9- 1. SSH intercepts a service request from some other program on one side of an SSH
connection, sends it across the encrypted connection, and delivers it to the intended recipient on the other side. This process is mostly transparent to both sides of the connection: each believes it is talking directly to its partner and has no knowledge that forwarding is taking place. Even more powerfully, SSH forwarding can achieve certain types of communication that are impossible without it.
Figure 9.1. SSH forwarding
Forwarding isn't a new concept. The basic operation of a terminal connection over a network (say, using telnet) is also a kind of forwarding. In a telnet connection, you sit on one end, your remote shell is on the other, and both sides operate as if directly connected by a serial cable. Nevertheless, sitting in the middle is a cooperating telnet client and server, forwarding bytes back and forth. SSH forwarding is much the same, except SSH plays fancy tricks with the data to add security.
We have also seen another type of SSH forwarding, agent forwarding. [Section 6.3.5] This
let us create SSH connections from one computer, through a second computer, and onto a third using public-key authentication, but without installing our private key on the second machine. To accomplish this, an SSH server pretended to be an SSH agent, while transparently forwarding data to and from a remote agent. This paradigm holds true for TCP port forwarding and X forwarding, as the SSH server transparently masquerades as another network application.
9.1 What Is Forwarding?
Forwarding is a type of interaction with another network application, as shown in Figure 9- 1. SSH intercepts a service request from some other program on one side of an SSH
connection, sends it across the encrypted connection, and delivers it to the intended recipient on the other side. This process is mostly transparent to both sides of the connection: each believes it is talking directly to its partner and has no knowledge that forwarding is taking place. Even more powerfully, SSH forwarding can achieve certain types of communication that are impossible without it.
Figure 9.1. SSH forwarding
Forwarding isn't a new concept. The basic operation of a terminal connection over a network (say, using telnet) is also a kind of forwarding. In a telnet connection, you sit on one end, your remote shell is on the other, and both sides operate as if directly connected by a serial cable. Nevertheless, sitting in the middle is a cooperating telnet client and server, forwarding bytes back and forth. SSH forwarding is much the same, except SSH plays fancy tricks with the data to add security.
We have also seen another type of SSH forwarding, agent forwarding. [Section 6.3.5] This
let us create SSH connections from one computer, through a second computer, and onto a third using public-key authentication, but without installing our private key on the second machine. To accomplish this, an SSH server pretended to be an SSH agent, while transparently forwarding data to and from a remote agent. This paradigm holds true for TCP port forwarding and X forwarding, as the SSH server transparently masquerades as another network application.
Book: SSH, The Secure Shell: The Definitive Guide
Section: Chapter 9. Port Forwarding and X Forwarding
9.2 Port Forwarding
SSH uses TCP/IP as its transport mechanism, usually TCP port 22 on the server machine, as it encrypts and decrypts the traffic passing over the connection. We will now discuss a cool feature that encrypts and decrypts TCP/IP traffic belonging to other applications, on other TCP ports, using SSH. This process, called port forwarding, is largely transparent and quite powerful. Telnet, SMTP, NNTP, IMAP, and other insecure protocols running over TCP can be made secure by forwarding the connections through SSH. Port forwarding is sometimes called tunneling because the SSH connection provides a secure "tunnel" through which another TCP/IP connection may pass.
Suppose you have a home machine H that runs an IMAP-capable email reader, and you want to connect to an IMAP server on machine S to read and send mail. Normally, this connection is insecure, with your mail account password transmitted as plaintext between your mail program and the server. With SSH port forwarding, you can transparently reroute the IMAP connection (found on server S's TCP port 143) to pass through SSH, securely encrypting the data over
[1]
9.2 Port Forwarding
SSH uses TCP/IP as its transport mechanism, usually TCP port 22 on the server machine, as it encrypts and decrypts the traffic passing over the connection. We will now discuss a cool feature that encrypts and decrypts TCP/IP traffic belonging to other applications, on other TCP ports, using SSH. This process, called port forwarding, is largely transparent and quite powerful. Telnet, SMTP, NNTP, IMAP, and other insecure protocols running over TCP can be made secure by forwarding the connections through SSH. Port forwarding is sometimes called tunneling because the SSH connection provides a secure "tunnel" through which another TCP/IP connection may pass.
Suppose you have a home machine H that runs an IMAP-capable email reader, and you want to connect to an IMAP server on machine S to read and send mail. Normally, this connection is insecure, with your mail account password transmitted as plaintext between your mail program and the server. With SSH port forwarding, you can transparently reroute the IMAP connection (found on server S's TCP port 143) to pass through SSH, securely encrypting the data over
[1]
the connection.
protection.
The IMAP server machine must be running an SSH server for port forwarding to provide real
In short, with minimal configuration changes to your programs, SSH port forwarding protects arbitrary TCP/IP
connections by redirecting them through an SSH session. Port forwarding can even pass a connection safely through a
firewall if you configure things properly. Once you start securing your communications with port forwarding, you'll
wonder how you ever got along without it. Here are examples of what you can do:
-
● Access various kinds of TCP servers (e.g., SMTP, IMAP, POP, LDAP, etc.) across a firewall that prevents direct
access.
-
● Provide protection for your sessions with these same TCP servers, preventing disclosure or alteration of
passwords and other content that would otherwise be sent in the clear as part of the session.
-
● Tunnel the control connection of an FTP session, to encrypt your username, password, and commands. (It isn't
usually possible to protect the data channels that carry the file contents, though. [Section 11.2])
-
● Use your ISP's SMTP servers for sending mail, even if you're connected outside the ISP's network and the ISP
forbids mail relaying from your current location. [Section 11.3.2]
9.2.1 Local Forwarding
In our earlier example, we had an IMAP server running on machine S, and an email reader on home machine H, and we wanted to secure the IMAP connection using SSH. Let's delve into that example in more detail.
SSH port forwarding is a general proxying mechanism for TCP only. (See Sidebar "TCP
Connections" for an overview of TCP concepts.) Forwarding can't work with protocols not
[2]
[2]
built on TCP, such as the UDP-based DNS, DHCP, NFS, and NetBIOS,
based protocols, such as AppleTalk or Novell's SPX/IPX.
or with non-IP-
TCP Connections
To understand port forwarding, it's important to know some details about TCP, the Transmission Control
Protocol. TCP is a fundamental building block of the Internet. Built on top of IP, it is the transport
mechanism for many application-level Internet protocols such as FTP, Telnet, HTTP, SMTP, POP, IMAP,
and SSH itself.
TCP comes with strong guarantees. A TCP connection is a virtual, full-duplex circuit between two communicating parties, acting like a two-way pipe. Either side may write any number of bytes at any time to the pipe, and the bytes are guaranteed to arrive unaltered and in order at the other side. The mechanisms that implement these guarantees, though, are designed to counter transmission problems in the network, such as routing around failed links, or retransmitting data corrupted by noise or lost due to temporary network congestion. They aren't effective against deliberate attempts to steal a connection or alter data in transit. SSH provides this protection that TCP alone lacks.
If an application doesn't need these guarantees about data integrity and order, or doesn't want the overhead associated with them, another protocol called User Datagram Protocol (UDP) often suffices. It is packet- oriented, and has no guarantees of delivery or packet ordering. Some protocols that run over UDP are NFS, DNS, DHCP, NetBIOS, TFTP, Kerberos, SYSLOG, and NTP.
When a program establishes a TCP connection to a service, it needs two pieces of information: the IP address of the destination machine and a way to identify the desired service. TCP (and UDP) use a positive integer, called a port number, to identify a service. For example, SSH uses port 22, telnet uses port 23, and IMAP uses port 143. Port numbers allow multiple services at the same IP address.
The combination of an IP address and a port number is called a socket. For example, if you run telnet to connect to port 23 on the machine at IP address 128.220.91.4, the socket is denoted "(128.220.91.4,23)." Simply put, when you make a TCP connection, its destination is a socket. The source (client program) also has a socket on its end of the connection, and the connection as a whole is completely defined by the pair of source and destination sockets.
In order for a connection attempt to a socket to succeed, something must be "listening" on that socket. That is, a program running on the destination machine must ask TCP to accept connection requests on that port and to pass the connections on to the program. If you've ever attempted a TCP connection and received the response "connection refused," it means that the remote machine is up and running, but nothing is listening on the target socket.
How does a client program know the target port number of a listening server? Port numbers for many protocols are standardized, assigned by the Internet Assigned Numbers Authority or IANA. (IANA's complete list of port numbers is found at http://www.isi.edu/in-notes/iana/assignments/port-numbers.) For instance, the TCP port number assigned to the NNTP (Usenet news) protocol is 119. Therefore, news servers listen on port 119, and newsreaders (clients) connect to them via port 119. More specifically, if a newsreader is configured to talk to a news server at IP address 10.1.2.3, it requests a TCP connection to the socket (10.1.2.3,119).
Port numbers aren't always hardcoded into programs. Many operating systems let applications refer to protocols by name, instead of number, by defining a table of TCP names and port numbers. Programs can then look up port numbers by the protocol name. Under Unix, the table is often contained in the file /etc/ services or the NIS services map, and queries are performed using the library routines getservbyname () , getservbyport() , and related procedures. Other environments allow servers to register their listening ports dynamically via a naming service, such as the AppleTalk Name Binding Protocol or DNS's WKS and SRV records.
So far, we've discussed the port number used by a TCP server when a TCP client program wants to connect. We call this the target port number. The client also uses a port number, called the source port
TCP comes with strong guarantees. A TCP connection is a virtual, full-duplex circuit between two communicating parties, acting like a two-way pipe. Either side may write any number of bytes at any time to the pipe, and the bytes are guaranteed to arrive unaltered and in order at the other side. The mechanisms that implement these guarantees, though, are designed to counter transmission problems in the network, such as routing around failed links, or retransmitting data corrupted by noise or lost due to temporary network congestion. They aren't effective against deliberate attempts to steal a connection or alter data in transit. SSH provides this protection that TCP alone lacks.
If an application doesn't need these guarantees about data integrity and order, or doesn't want the overhead associated with them, another protocol called User Datagram Protocol (UDP) often suffices. It is packet- oriented, and has no guarantees of delivery or packet ordering. Some protocols that run over UDP are NFS, DNS, DHCP, NetBIOS, TFTP, Kerberos, SYSLOG, and NTP.
When a program establishes a TCP connection to a service, it needs two pieces of information: the IP address of the destination machine and a way to identify the desired service. TCP (and UDP) use a positive integer, called a port number, to identify a service. For example, SSH uses port 22, telnet uses port 23, and IMAP uses port 143. Port numbers allow multiple services at the same IP address.
The combination of an IP address and a port number is called a socket. For example, if you run telnet to connect to port 23 on the machine at IP address 128.220.91.4, the socket is denoted "(128.220.91.4,23)." Simply put, when you make a TCP connection, its destination is a socket. The source (client program) also has a socket on its end of the connection, and the connection as a whole is completely defined by the pair of source and destination sockets.
In order for a connection attempt to a socket to succeed, something must be "listening" on that socket. That is, a program running on the destination machine must ask TCP to accept connection requests on that port and to pass the connections on to the program. If you've ever attempted a TCP connection and received the response "connection refused," it means that the remote machine is up and running, but nothing is listening on the target socket.
How does a client program know the target port number of a listening server? Port numbers for many protocols are standardized, assigned by the Internet Assigned Numbers Authority or IANA. (IANA's complete list of port numbers is found at http://www.isi.edu/in-notes/iana/assignments/port-numbers.) For instance, the TCP port number assigned to the NNTP (Usenet news) protocol is 119. Therefore, news servers listen on port 119, and newsreaders (clients) connect to them via port 119. More specifically, if a newsreader is configured to talk to a news server at IP address 10.1.2.3, it requests a TCP connection to the socket (10.1.2.3,119).
Port numbers aren't always hardcoded into programs. Many operating systems let applications refer to protocols by name, instead of number, by defining a table of TCP names and port numbers. Programs can then look up port numbers by the protocol name. Under Unix, the table is often contained in the file /etc/ services or the NIS services map, and queries are performed using the library routines getservbyname () , getservbyport() , and related procedures. Other environments allow servers to register their listening ports dynamically via a naming service, such as the AppleTalk Name Binding Protocol or DNS's WKS and SRV records.
So far, we've discussed the port number used by a TCP server when a TCP client program wants to connect. We call this the target port number. The client also uses a port number, called the source port
number, so the server can transmit to the client. If you combine the client's IP address and its source port
number, you get the client's socket.
Unlike target port numbers, source port numbers aren't standard. In most cases, in fact, neither the client nor the server cares which source port number is used by the client. Often a client will let TCP select an unused port number for the source. (The Berkeley r-commands, however, do care about source ports. [Section 3.4.2.3]) If you examine the existing TCP connections on a machine with a command such as netstat -a or lsof -i tcp , you will see connections to the well-known port numbers for common services (e. g., 23 for Telnet, 22 for SSH), with large, apparently random source port numbers on the other end. Those source ports were chosen from the range of unassigned ports by TCP on the machines initiating those connections.
Once established, a TCP connection is completely determined by the combination of its source and target sockets. Therefore, multiple TCP clients may connect to the same target socket. If the connections originate from different hosts, the IP address portions of their source sockets will differ, distinguishing the connections. If they come from two different programs running on the same host, TCP on that host ensures they have different source port numbers.
IMAP uses TCP port 143; this means that an IMAP server will be listening for connections on port 143 on the server machine. To tunnel the IMAP connection through SSH, you need to pick a local port on home machine H (between 1024 and 65535) and forward it to the remote socket (S,143). Suppose you randomly pick local port 2001. The
[3]
The -L option specifies local forwarding, in which the TCP client is on the local machine with the SSH client. The option is followed by three values separated by colons: a local port to listen on (2001), the remote machine name or IP address (S), and the remote, target port number (143).
The previous command logs you into S, as it will if you just type ssh S. However, this SSH session has also forwarded TCP port 2001 on H to port 143 on S; the forwarding remains in effect until you log out of the session. To make use of the tunnel, the final step is to tell your email reader to use the forwarded port. Normally your email program connects to port 143 on the server machine, that is, the socket (S,143). Instead, it's configured to connect to port 2001 on home machine H itself, i.e., socket (localhost,2001). So the path of the connection is now as follows:
Unlike target port numbers, source port numbers aren't standard. In most cases, in fact, neither the client nor the server cares which source port number is used by the client. Often a client will let TCP select an unused port number for the source. (The Berkeley r-commands, however, do care about source ports. [Section 3.4.2.3]) If you examine the existing TCP connections on a machine with a command such as netstat -a or lsof -i tcp , you will see connections to the well-known port numbers for common services (e. g., 23 for Telnet, 22 for SSH), with large, apparently random source port numbers on the other end. Those source ports were chosen from the range of unassigned ports by TCP on the machines initiating those connections.
Once established, a TCP connection is completely determined by the combination of its source and target sockets. Therefore, multiple TCP clients may connect to the same target socket. If the connections originate from different hosts, the IP address portions of their source sockets will differ, distinguishing the connections. If they come from two different programs running on the same host, TCP on that host ensures they have different source port numbers.
IMAP uses TCP port 143; this means that an IMAP server will be listening for connections on port 143 on the server machine. To tunnel the IMAP connection through SSH, you need to pick a local port on home machine H (between 1024 and 65535) and forward it to the remote socket (S,143). Suppose you randomly pick local port 2001. The
[3]
The -L option specifies local forwarding, in which the TCP client is on the local machine with the SSH client. The option is followed by three values separated by colons: a local port to listen on (2001), the remote machine name or IP address (S), and the remote, target port number (143).
The previous command logs you into S, as it will if you just type ssh S. However, this SSH session has also forwarded TCP port 2001 on H to port 143 on S; the forwarding remains in effect until you log out of the session. To make use of the tunnel, the final step is to tell your email reader to use the forwarded port. Normally your email program connects to port 143 on the server machine, that is, the socket (S,143). Instead, it's configured to connect to port 2001 on home machine H itself, i.e., socket (localhost,2001). So the path of the connection is now as follows:
-
The email reader on home machine H sends data to local port 2001.
-
The local SSH client on H reads port 2001, encrypts the data, and sends it through the SSH connection to the
SSH server on S.
-
The SSH server on S decrypts the data and sends it to the IMAP server listening on port 143 on S.
-
Data is sent back from the IMAP server to home machine H by the same process in reverse.
# SSH1, OpenSSH
LocalForward 2001 localhost:143
# SSH2 only
LocalForward "2001:localhost:143"
following command then creates the tunnel:
$ ssh -L2001:localhost:143 S
Note the small syntactic differences. In SSH1 and OpenSSH, there are two arguments: the local port number, and the
remote socket expressed as host:port. In SSH2, the expression is just as on the command line, except that it must be
enclosed in double quotes. If you forget the quotes, ssh2 doesn't complain, but it doesn't forward the port, either.
Our example with home machine H and IMAP server S can be set up like this:
In SSH1 and OpenSSH, by default, only the host running the SSH client can connect to locally forwarded ports. This is because ssh listens only on the machine's loopback interface for connections to the forwarded port; that is, it binds the socket (localhost,2001), a.k.a. (127.0.0.1,2001), and not (H,2001). So, in the preceding example, only machine H can use the forwarding; attempts by other machines to connect to (H,2001) get "connection refused." However, ssh for SSH1 and OpenSSH has a command-line option, -g, that disables this restriction, permitting any host to connect to locally forwarded ports:
9.2.1.2 Remote forwarding
A remotely forwarded port is just like a local one, but the directions are reversed. This time the TCP client is remote, its server is local, and a forwarded connection is initiated from the remote machine.
Continuing with our example, suppose instead that you are logged into server machine S to begin with, where the IMAP server is running. You can now create a secure tunnel for remote clients to reach the IMAP server on port 143. Once again, you select a random port number to forward (say, 2001 again) and create the tunnel:
Once this command has run, a secure tunnel has been constructed from the port 2001 on the remote machine H, to port 143 on the server machine S. Now any program on H can use the secure tunnel by connecting to (localhost,2001). As before, the command also runs an SSH terminal session on remote machine H, just as ssh H does.
As with local forwarding, you may establish a remote forwarding using a keyword in your client configuration file. The RemoteForward keyword is analogous to LocalForward, with the same syntactic differences between SSH1 and
Our example with home machine H and IMAP server S can be set up like this:
# SSH1, OpenSSH
Host local-forwarding-example
HostName S
LocalForward 2001 localhost:143
# Run on home machine H
$ ssh local-forwarding-example
9.2.1.1 Local forwarding and GatewayPorts
In SSH1 and OpenSSH, by default, only the host running the SSH client can connect to locally forwarded ports. This is because ssh listens only on the machine's loopback interface for connections to the forwarded port; that is, it binds the socket (localhost,2001), a.k.a. (127.0.0.1,2001), and not (H,2001). So, in the preceding example, only machine H can use the forwarding; attempts by other machines to connect to (H,2001) get "connection refused." However, ssh for SSH1 and OpenSSH has a command-line option, -g, that disables this restriction, permitting any host to connect to locally forwarded ports:
# SSH1, OpenSSH
$ ssh1 -g -L<localport>:<remotehost>:<remoteport> hostname
The client configuration keyword GatewayPorts also controls this feature; the default value is no, and giving
GatewayPorts=yes does the same thing as -g:
# SSH1, OpenSSH
GatewayPorts yes
There's a reason why GatewayPorts and -g are disabled by default: they represent a security risk. [Section 9.2.4.2]
9.2.1.2 Remote forwarding
A remotely forwarded port is just like a local one, but the directions are reversed. This time the TCP client is remote, its server is local, and a forwarded connection is initiated from the remote machine.
Continuing with our example, suppose instead that you are logged into server machine S to begin with, where the IMAP server is running. You can now create a secure tunnel for remote clients to reach the IMAP server on port 143. Once again, you select a random port number to forward (say, 2001 again) and create the tunnel:
$ ssh -R2001:localhost:143 H
The -R option specifies remote forwarding. It is followed by three values, separated by colons as before but interpreted
slightly differently. The remote port to be forwarded (2001) is now first, followed by the machine name or IP address
(localhost) and port number (143). SSH can now forward connections from (localhost,143) to (H,2001).
Once this command has run, a secure tunnel has been constructed from the port 2001 on the remote machine H, to port 143 on the server machine S. Now any program on H can use the secure tunnel by connecting to (localhost,2001). As before, the command also runs an SSH terminal session on remote machine H, just as ssh H does.
As with local forwarding, you may establish a remote forwarding using a keyword in your client configuration file. The RemoteForward keyword is analogous to LocalForward, with the same syntactic differences between SSH1 and
SSH2:
# SSH1, OpenSSH
RemoteForward 2001 S:143
# SSH2 only
RemoteForward "2001:S:143"
For example, here's the preceding forwarding defined in an SSH2-format configuration file:
# SSH2 only
remote-forwarding-example:
Host H
RemoteForward "2001:S:143"
$ ssh2 remote-forwarding-example
9.2.2 Trouble with Multiple Connections
If you use LocalForward or RemoteForward in your configuration file, you might run into a subtle problem. Suppose you have set up a section in your configuration file to forward local port 2001 to an IMAP server:
# SSH1 syntax used for illustration
Host server.example.com
LocalForward 2001 server.example.com:143
This configuration works fine if you connect once:
$ ssh server.example.com
But if you try to open a second ssh connection to server.example.com at the same time-perhaps to run a different
program in another window of your workstation-the attempt will fail:
$ ssh server.example.com
Local: bind: Address already in use
Why does this happen? Because your configuration file section tries to forward port 2001 again but finds that port is
already in use ("bound" for listening) by the first instance of ssh. You need some way to make the connection but omit
the port forwarding.
SSH1 (but not OpenSSH) provides a solution, the client configuration keyword ClearAllForwardings. From the name, you might think it terminates existing forwardings, but it doesn't. Rather, it nullifies any forwardings specified in the current ssh command. In the previous example, you can connect without forwardings to server.example.com with:
You might think that the GatewayPorts feature discussed in the last section applies
equally well to remote port forwardings. This would make sense as a feature, but as it
happens, it isn't done. There would have to be a way for the client to communicate this
parameter to the server for a given forwarding, and that feature hasn't been included in the
SSH protocol. In SSH1 and SSH2, remotely forwarded ports always listen on all network
interfaces and accept connections from anywhere. [Section 9.4] The OpenSSH server does
accept the GatewayPorts configuration option, and it applies globally to all remote
forwardings established by that server.
# SSH1 only
$ ssh1 -o ClearAllForwardings=yes server.example.com
The original tunnel, set up by the first invocation, continues to exist, but ClearAllForwardings prevents the
second invocation from attempting to recreate the tunnel. To illustrate the point further, here's a rather silly command:
$ ssh1 -L2001:localhost:143 -o ClearAllForwardings=yes mymachine
The -L option specifies a forwarding, but ClearAllForwardings cancels it. This silly command is identical in
function to:
$ ssh1 mymachine
ClearAllForwardings may also be placed in your client configuration file, of course. It seems more useful on the
command line, however, where it can be used on the fly without editing a file.
9.2.3 Comparing Local and Remote PortForwarding
The differences between local and remote forwarding can be subtle. It can get a bit confusing to know which kind of forwarding to use in a given situation. The quick rule is look for the TCP client application.
The rest of this section is devoted to dissecting the forwarding process in detail and understanding where this rule comes from.
9.2.3.1 Common elements
Local and remote forwarding can be confusing because of overloaded terminology. In a given port forwarding situation, there are two clients and two servers lying around. We have the SSH client and server programs (e.g., ssh and sshd ), plus the TCP application's client and server programs whose connection you want to protect by port forwarding.
An SSH session has a direction of establishment. That is, you run an SSH client on one machine, and it initiates a session with an SSH server on another. Likewise, a forwarded connection has a direction of establishment: you run an application client on one machine, and it initiates a session with a service on another. These two directions may or may not match. This is the difference between local and remote forwarding. Let's introduce some terminology and provide some diagrams to make sense of this.
No comments:
Post a Comment