Creating SSH tunnels using PuTTY. What is SSH tunneling and why is it needed?

This article will describe how to build SSH tunnels using PuTTY.

1. Local port forwarding

Consider the following situation. We're inside corporate network, our computer has the address 192.168.0.2, access to the outside world is completely closed (that is, no NAT, proxy, etc.). We do not have the ability to influence the access restriction policy, but we do have SSH access to one of the servers with a routable IP address that is accessible from the Internet. For example, let the internal address of this server be 192.168.0.3. The network structure is shown in the figure:

Let's assume that we really need to connect, for example, via SSH to some remote server with IP address 212.212.212.212 somewhere far away on the Internet. To do this, launch PuTTY, create an SSH connection to server 192.168.0.3 (hereinafter referred to as SSH session 1), go to the Tunnels item:

and indicate that local port 2222 of our computer should be matched to port 22 on the server with IP address 212.212.212.212. Next, click the “Open” button and log in to server 192.168.0.3. Then we create another connection (hereinafter referred to as SSH session 2), but on localhost, port 2222 and click the “Open” button:

As a result, SSH session 2 will be tunneled (that is, it will be installed inside the previously established SSH session 1). For the remote server 212.212.212.212, everything will look as if 111.111.111.111 is connecting to it:

2. Remote port forwarding

In this case, the connection inside the SSH tunnel is established in the other direction - from the remote server to our local computer. It can be useful if you need to open access to local services on your computer. Let's consider the same network as in point 1, but for simplicity let's assume that we now have NAT:

Here we already have the opportunity to connect via SSH directly to 212.212.212.212 thanks to the presence of NAT. But 212.212.212.212, of course, will not be able to connect to 192.168.0.2 without special tricks, because 192.168.0.2 is not directly connected to the Internet. Let's assume that a user sitting under X on 212.212.212.212 needs to get to our computer 192.168.0.2 via remote desktop. To do this, in an SSH connection session from 192.168.0.2 to 212.212.212.212, you need to change the settings in the Tunnels section as follows:

#lsof -i -nP | grep 3333 sshd 18598 avz 11u IPv4 592868957 TCP 127.0.0.1:3333 (LISTEN)

That is, sshd waits for connections on TCP port 3333, which will then be redirected via the SSH tunnel to 192.168.0.2 port 3389. And the user sitting at 212.212.212.212 will be able to see our desktop using rdesktop:

3. Socks-proxy

In this case, we can use a server with an SSH daemon as an intermediate (proxy). Network diagram as in case #1 (without NAT and regular proxies):

To force PuTTY to act as a socks proxy, you need to change the SSH session parameters from 192.168.0.2 to 192.168.0.3 as follows:

C:\>netstat -ano | find "1080" TCP 127.0.0.1:1080 0.0.0.0:0 LISTENING 2392 C:\>tasklist | find /i "2392" putty.exe 2392 Console 0 5420 KB

That is, putty running with PID 2392 starts listening on port 1080, waiting for connections. Next, we take any application that can work with a SOCKS proxy, for example Firefox, and tell it to use our proxy:

Now all requests from the browser will go through server 192.168.0.3. The logs of the websites that we will visit in this way will display the external IP address of our server - 111.111.111.111.

P.S. From the Putty 0.58 help file:

Question A.10.3: What does “PuTTY” mean?

It"s the name of a popular SSH and Telnet client. Any other meaning is in the eye of the beholder. It"s been rumoured that “PuTTY” is the antonym of “getty”, or that it's the stuff that makes your Windows useful... :)

Please enable JavaScript

© 2009–2019, site - When using site materials, it is advisable to indicate the source. Thank you!

Mar 28, 2012 By Jayson Broughton
in HOW-TOs SysAdmin

“If you see a light at the end of a tunnel, it is the light of an approaching train,” Robert Lowell. Another good quote. This article is about building tunnels with using SSH, or as I call this topic, "VPN tunnels for the poor." Despite the basic beliefs of system administrators, SSH tunnels can actually be quite useful thing both for techies and home use. I say "despite the beliefs of sysadmins" because reverse tunnels or web traffic wrapped in SSH can get through firewalls and content filters. The article, however, is not about how you can subvert corporate security policies, but about how SSH tunneling can make our lives a little less complicated.

Why SSH tunnels instead of VPN? Ok, I use this and that at home. If you've been following me on jaysonbroughton.com, you know that I have OpenVPN three-factor authentication (username, certificate, and one-time password) in the works. But if I want to check one of the servers under my control via Android, or look into a computer on which I do not have administrative rights (and the portable OpenVPN client needs them), or even want to fix some errors using vnc access over SSH tunnel, then SSH is my choice of way to secure traffic.

We'll discuss the basics: how to build a tunnel, what each command syntax means, examples of reverse tunnels, and situations in which you should use one or another approach. I also briefly went over the structure of the configuration file.

So oh system requirements. I'm using Debian in a virtual environment, so your results may vary from mine. Therefore, I provide information about the tools: the OpenSSH_5.3p1 server and OpenSSH 5.X clients of various versions are in use. Before diving into the depths of ssh tunneling, I must say: before poking a hole in a company’s security using a reverse tunnel or wrapping http traffic, make sure that you do not violate any stack of internal regulations such as the Internet Acceptable Use Policy. It is clear that in this case the System Administrators will immediately hunt you down and fry you, especially if you are using a tunnel to get to the server at work from home. As a System Administrator myself, I get great pleasure from discovering such characters. Believe me, with a little checking it turns out that system administrators are not idiots at all.

Well, the disclaimer has been announced, you can get started.

Building SSH tunnels is a fairly simple thing. Understanding what's going on and learning approaches can be a little more difficult. So I'll give a few typical cases to adjust the consciousness before we move on to the details of the commands. Before I had children, I traveled quite a bit. In my travels I have found myself in very strange hotels, the rooms of which had very strange Wi-Fi points access. Do you really want to connect to a hotel access point whose SSID is typed in untranslatable gobbledygook? Or at the airport, where several open networks? When I'm somewhere in the outside world, I prefer to tunnel web traffic to my rooted android via home server. When I have my laptop in my hands, I open an ssh tunnel and redirect web traffic through socks5 so that all traffic coming to me is encrypted. I trust open WAPs only insofar as I can navigate through them. What else about plaintext? I am tunneling SMTP traffic on my computer through my home server when in some places I see that outgoing SMTP is blocked. The situation is similar with POP3. Another example: you can manage X applications through a tunnel. You can wrap VNC sessions in a tunnel. One of the techniques that I started using earlier than others was reverse tunnels. In this case, you create a tunnel from a server that is behind a firewall. When you log into that SSH server, you can reestablish the connection.

Examples

Before looking at the client side, you need to do some things on the server side by editing the sshd.config configuration file, where I recommend making the following changes. Before making changes, copy the original config for safety in case something goes wrong.

If you made changes, you must restart the sshd server to apply them.

Let's move on to the keys command line.

A typical ssh tunnel (without X protocol tunneling) looks something like this:

As you might guess, the -X option tunnels X. Remember, however, that the command will tunnel your application from your remote machine to your Linux client machine. If you are on Windows, just install Cygwin/X (http://x.cygwin.com/) on your guest car. I haven't tried this myself, but as I understand it should help launch remote X application in Windows.

When you go about establishing VNC sessions, you need to be careful. If a remote VNC server is running on port 5900, make sure you are not connecting to itself afterwards. The session itself is tunneled as in other cases using a transparent command:

And now you have it, a reverse tunnel.

For clarity, daddoo and nerdboy4200 from #linuxjournal joined forces and created Mscgen, a program that parses a sequence of messages and builds a visual diagram of message exchange for different protocols. It is, of course, open source and quite terrible to look at (http://www.mcternan.me.uk/mscgen/). For the case of a reversible tunnel, with the help of their product, they built a diagram (then the author inserted a diagram into his text, on which nothing is visible - approx. trans.).

Conclusion

So, what you can do with tunneling is limited only by your imagination, we've only given a few examples here. Perhaps in subsequent posts I will tell you how to properly configure SSH on the client side.

Any system administrator has to constantly work remotely, but there are situations when you urgently need to connect to internal network nodes that are not accessible from the outside. It’s good if there is access to other nodes of a given network, but it happens that access from global network no at all, in these cases they usually use TeamViewer or similar software, but if it is possible to connect to such a network via SSH or establish a connection with an intermediate SSH server, then you can quickly and easily organize access without involving third-party software.

Very often, when it comes to remote access to networks with a low level of security, the first thing that comes to mind is a VPN, but for the sake of administrative connections, it is not always advisable to install a VPN, especially when it comes to outsourcing or an “incoming admin”. In addition, communication conditions do not always allow for a stable VPN connection, especially if you have to use mobile networks.

Moreover, in almost any network you can find a device or server that can be accessed via SSH, or there is such an intermediate server, for example, a VPS on the global network. In this case great solution There will be SSH tunnels that make it easy to organize secure communication channels, including through intermediate nodes, which eliminates the problem of having a dedicated IP address.

Strictly speaking, SSH tunnels are not full-fledged tunnels and this name should be considered as a stable name that has developed in the professional environment. The official name of the technology is SSH Port Forwarding is an optional feature of the SSH protocol that allows you to transfer a TCP packet from one side of an SSH connection to the other and during the transfer process, translate the IP header according to a predetermined rule.

Also, unlike VPN tunnels, which allow any traffic to be transmitted in any direction, the SSH tunnel has an entry point and can only work with TCP packets. In fact, this is most similar to port forwarding (as the official name suggests), only over the SSH protocol.

Let's look at the operation of the SSH tunnel in more detail. As an example, let's take the classic case of providing access to some remote server via the RDP protocol.

Let's say that there is a target server with the address 192.168.0.105 on the remote network, but there is no access to it from the external network, the only device to which we can connect is a router with the address 192.168.0.1 with which we can establish an SSH connection.

Let's dwell on very important point: sets all SSH tunnel parameters initiator connections, aka SSH client, the second end of the tunnel is always the server to which we connect, aka SSH server. IN in this context The client and server should be understood purely as sides of the connection, for example, a VPS server can act as an SSH client, and an administrator’s laptop can act as an SSH server.

The entry point can be located at any side connection, a TCP socket is opened there with specified parameters, which will accept incoming connections. The exit point cannot accept connections, but only routes packets in accordance with the translation rules.

Let's look at the diagram above. We have established an SSH tunnel from the local machine to the remote router, specifying local entry point 127.0.0.1:3389 And translation rule 192.168.0.105:3389. Once again, we draw your attention to the fact that the translation rule does not indicate the exit point, but determines the node to which packets will be sent upon exiting the tunnel. If you specify an invalid address, or the host does not accept connections, the SSH tunnel will be established, but there will be no access to the target host.

According to the specified entry point, the SSH service will create a local TCP socket that will listen for connections on port 3389. Therefore, in the RDP connection window we specify as the destination localhost or 127.0.0.1 , The RDP client opens a dynamic port and sends a packet with the destination address 127.0.0.1:3389 and source address 127.0.0.1:61256 , he knows nothing about the real destination of the packet recipient.

From the entry point Current Package will be sent to the other side of the SSH tunnel, and the destination address according to the translation rules will be changed to 192.168.0.105:3389 , and the SSH server will make a further decision according to its own routing table, replacing the source address with its own, otherwise the target server will try to send a response packet to the local address.

Thus, the RDP client works with a local socket and RDP packets do not go beyond this node; inside the tunnel they are transmitted over the SSH protocol in encrypted form, but a regular RDP connection is established between the SSH server and the RDP server on the network 192.168.0.0 , V open form. This should be taken into account when using insecure protocols, firmly remembering that if the translation rule points beyond the node with the exit point, then such a connection (between the exit point and the destination node) not defending himself via SSH.

Having figured out general outline how SSH tunnels work let's move on to practical options their use, we will consider Linux systems of the Debian/Ubuntu family as a platform, but everything stated below, with minor amendments, will be valid for any UNIX-like system.

SSH tunnel with local entry point

Local Entry Point tunnels are used to gain access to hosts on a remote network with the ability to establish an SSH connection to one of its hosts, which assumes that the remote network has a dedicated IP address.

We will consider the same option, an RDP connection to a remote server, the orange dotted line in the diagram indicates a secure SSH connection, and the blue arrows indicate a regular TCP connection.

In the very simple version we simply establish a connection from the client PC to the router on the remote network, specifying the target node in the translation rule:

Ssh -L 127.0.0.1:3389:192.168.0.105:3389 [email protected]

Key -L indicates that the entry point is located locally, then a colon indicates the address and port of the entry point and the address, port of the translation rule. The exit point is the node to which we connect, i.e. rt.example.com.

If your network also has a router (or other Linux server), then you can make it an entry point, which will allow any RDP client from local network. In theory, to do this, you should raise a tunnel like this:

Ssh -L 192.168.31.100:3389:192.168.0.105:3389 [email protected]

In this case, the SSH service would have to open a TCP socket on interface 192.168.31.100, but in practice this will not happen. This is due to the implementation features of OpenSSH, which is the standard for the vast majority of UNIX-like systems.

By default, OpenSSH opens an entry point only on local interface. It's easy to verify this:

In order to provide access to a TCP socket from external interfaces, you should use the key -g, or add to the configuration file /etc/ssh/sshd_config option:

GatewayPorts yes

However, after this the socket will accept connections from any initiator network interface:

This means that port 3389 will be open on all network interfaces, so if the entry point is an edge device, then access to the socket should be limited, for example, using iptables. For example, let’s block access from the external network (eth0 interface):

Iptables -A INPUT -i eth0 -p tcp --dport 3389 -j DROP

Thus, the working tunnel should be raised with the command:

Ssh -L -g 3389:192.168.0.105:3389 [email protected]

Please note one more thing: if the entry point matches the local interface, and for OpenSSH this is always the case, then it can be omitted by immediately starting the command from the entry point port.

We also recommend using the key if possible -g, rather than adding the option to the configuration file, since in the latter case you risk, by forgetting about this setting, opening access to unprotected services on the remote network to the outside world.

SSH tunnel with remote entry point

A tunnel with a remote entry point allows, on the contrary, to publish any local service on a remote network; one of the most common uses is access to a network without a dedicated IP address, but this requires a “white” IP from the administrator’s network.

In the first option, the remote server itself establishes a connection with the local network router. This can be done with a simple command:

Ssh -R 3389:127.0.0.1:3389 [email protected]

The -R key specifies to open the access point from the remote side of the tunnel, then we specify the port for the TCP socket and the translation, since packets arriving at the exit point should be processed locally, we also specify the local interface.

The attentive reader will notice that we have not specified the key -g, Yes it is. The point is that for tunnels with a remote entry point given key not applicable and option should be used

GatewayPorts yes

on the SSH server side.

For security reasons, we recommend using this setting with the default policy DROP for the INPUT chain, this will avoid accidental publication on external interface internal services and resources. IN minimal configuration four rules should be added to the very beginning of the INPUT chain:

Iptables -P INPUT DROP
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

The first of these sets the default deny policy for incoming packets, the second allows incoming packets initiated by the host itself (responses to outgoing packets), and the third allows all connections from the local network. Finally, the fourth rule opens port 22 for incoming SSH connections; in the same way, you can open any other port for external connections.

The second option presented in the diagram provides that the SSH tunnel is raised by network routers, in this case the command will look like this:

Ssh -R 3389:192.168.0.105:3389 [email protected]

Let us again draw your attention to the fact that our entry point is located on the opposite side of the tunnel, so the broadcast is indicated for the side of the tunnel initiator, i.e. V in this case The SSH client establishes two connections: one SSH with rt.example.com, and the second RDP with 192.168.0.105, whereas with a tunnel with a local entry point, the initiator establishes a single connection with the SSH server.

Double SSH tunnel

Quite often situations arise when you need to connect two nodes that do not have dedicated IP addresses. In this case, you usually use TeamViewer or similar third-party software, but if you have an available server with a dedicated IP address, then you can do it easier.

Let's pay attention to the diagram above. SSH allows you to build entire chains of tunnels, connecting the entry point of the next one to the exit point of the previous one. Thus, in order to get a tunnel from the admin PC to the RDP server, with both nodes having gray IP addresses, we need to create two tunnels with intermediate node.

Tunnel with a local entry point on the admin PC:

Ssh -L 3389:127.0.0.1:3390 [email protected]

And a tunnel with a remote entry point on the RDP server:

Ssh -R 3390:127.0.0.1:3389 [email protected]

We specifically pointed out remote server non-standard port For greater clarity, now let's see how it all works. Let's start with the RDP server; it raises a tunnel with a remote entry point, opening a TCP socket on the intermediate server that will accept connections on port 3390; we will specify the RDP server itself as a broadcast - 127.0.0.1:3389, i.e. all packets arriving at the entrance of this tunnel will be sent to local port 3389.

A tunnel with a local entry point on the administrator’s PC opens a local socket on port 3389, where the RDP client will connect; as a broadcast, we specify the entry point of the second tunnel - 127.0.0.1:3390.

As we have already said, there are no restrictions on the number of tunnels in the chain, but in practice the need for tunnels with more than one intermediate node arises quite rarely. It should be remembered that with each new intermediate node the reliability of the entire circuit will decrease, and the final speed will be limited to the speed of the slowest section of the path.

Dynamic SSH tunnel

Unlike those discussed above, a dynamic tunnel works differently; it opens a local TCP socket on the host, which can be used as a SOCKS4/SOCKS5 proxy to access the Internet through a remote SSH server. This can be useful for bypassing some restrictions, when there is no need to install a full-fledged VPN in another jurisdiction, and you cannot use public proxies or VPNs for security reasons.

This type of tunnel is especially convenient if you need one-time access to the Internet from another node. A simple example: a good friend of mine brought two carrier contract iPhones from the States and asked to unlock them. Difficulties this operation No secret, if the terms of the contract have not been violated, then just go to the operator’s website and fill out an application for unlocking. But the problem turned out to be that operator T-Mobile Access to this section The site was accessible only to US residents, and connections from public proxies and VPNs were rejected as unsafe.

A dynamic SSH tunnel made it possible to quickly solve this problem using VPS in the States. To create such a tunnel, enter the command:

Ssh-D 1080 [email protected]

Where 1080 is the port on which our SOCKS proxy will be available. All that remains is to configure the browser to use a local proxy server.

Another advantage of this method is that the proxy server exists only locally on your host, no additional ports need to be opened to the external network, and there is only an SSH connection between the client and the server.

This allows you to hide the nature of your Internet activity from an outside observer, which can be useful in public networks, where there is reasonable grounds to believe that traffic may be intercepted and analyzed by third parties. In this case, the SSH tunnel provides reliable encryption of transmitted data on an insecure network, but this requires complete trust in the server through which you access the Internet.

A few words about safety

Although this is beyond the scope of the article, we could not mention one feature that can bring quite unpleasant surprises. By raising the SSH tunnel using one of the above commands, you will also get, in addition to the tunnel, open console on the server you are connecting to. Take a close look at the invitation line in the screenshot below.

At the top we see an invitation from the local host, and at the bottom, after raising the tunnel, we see the invitation from the remote server. This is convenient if you need to check the communication channel or perform certain settings from the remote side, but in everyday life this can lead to serious trouble if you forget or do not pay attention to which server the console is connected to and execute commands on the remote server intended for the local node, especially if you connect with superuser rights.

Therefore, after you have checked the functionality of the tunnel, you should start it with the -N switch, which prohibits the execution of commands on the remote server, for example:

Ssh -N -L -g 3389:192.168.0.105:3389 [email protected]

And, of course, you should not use a superuser account to connect to the server; it is best to create a regular account for these purposes.

SSH tunnels on Windows

Throughout the article, we looked at SSH tunnels using the example of Linux systems and Windows users one might get the impression that these opportunities are not available to them. But this is not true; there are many SSH clients for Windows that support the creation of tunnels. We will consider the most popular of them - PuTTY. You can also run an SSH server under Windows, but this requires certain qualifications and is not always possible to achieve stable operation, so we will not consider this option.

Let's open PuTTY and on the left side of the tree go to Connection - SSH - Tunnels:

The following window will open in front of us, the main settings of the tunnel are concentrated at the bottom, and we have highlighted them with a red frame. Source port- is intended to indicate the port of the entry point, which is always located on the local interface (127.0.0.1). Destination- broadcast, i.e. where packets will be sent from the exit point. Radio switches Local - Remote - Dynamic set the tunnel type and are similar to keys -L,-R And -D.

After you have filled in all the required fields, you can add a tunnel using the button Add. To allow external hosts access to the local entry point socket, check the box Local ports accept connections from other hosts. In this case, you should also limit access to open ports means Windows Firewall or a third-party surge protector.

The server to which we connect is specified in a different section - Session, which is familiar to anyone who has ever used PuTTY, where you can save session parameters for future use.

As you can see, SSH gives the administrator flexible and powerful tool for safe remote access without the need to open ports or organize VPN channels. We hope that this material will be useful to you and will allow you to master new capabilities of seemingly familiar tools.

  • Tags:

Please enable JavaScript to view the

SSH-tunneling can help not only in matters where it is necessary to transmit unencrypted traffic over an encrypted connection, but also when you have no access to a resource on the network, but access is necessary.

Let's look at creating and setting up several options.

And so, we have a server, let's call it host-1. To him we have full access only by SSH- but we need to open Tomcat, operating on port 8082 - to which they cannot let us through.

We will consider the option with setting Windows And Putty.

Opening SSH-connection to to the desired server, let's log in.

We specify the following parameters:

Source port: any unused port on your system;
Destination port: 127.0.0.1:8082

Click Add, Then Apply.

Go to the browser settings and set the proxy parameters:

Now all that remains is to open the page http://localhost:3002 in the browser - and we get to the page Tomcat on server host-1.

If the tunnel is not working, check on the server whether packet forwarding is enabled. In the /etc/ssh/sshd_config file, find and uncomment the line:

AllowTcpForwarding yes

And restarting SSHd:

# service sshd restart Stopping sshd: [ OK ] Starting sshd: [ OK ]

Another example - we have the same external server from which we have normal access to any resources on the Internet. But from the workplace we have access to and is closed.

We carry out similar actions, but with minor differences. Settings in Putty:

Source port - leave the same, but instead Local- choose Dynamic. Click Add, Apply.

Let's go to the browser settings:

Please note that the proxy type here is not HTTP, but SOCKS.

Enjoy access to your favorite sites.

And a more interesting case.

We have the same host-1. In addition to it, there is a second server, let’s call it host-2. In addition, we have a machine with Windows, which needs to be granted access to the resource TeamCity on server host-1 on port 8111. In this case, access from Windows-we only have machines for the server host-2, and only on port 22.

To begin with, we raise the tunnel between host-1 And host-2. We carry out on host-1:

$ ssh -f -N -R host-2:8082:localhost:8111 username@host-2

So we open a tunnel, which locally (on host-1) looks at port 8111, and on the other side is the machine host-2, on which port 8082 opens and waits for incoming connections. When receiving packets on port 8082 (and only via the lo0 interface! this is important) - it will redirect them to the machine host-1 port 8111.

Regarding the lo0 interface. When installed SSH-tunnel, even when specifying the external IP of the machine - the connection is raised only from localhost, i.e. 127.0.0.1 .

Let's look at host-2:

$ netstat -anp | grep 8082 tcp 0 0 127.0.0.1:8082 0.0.0.0:* LISTEN -

To change this, you need to edit the sshd daemon configuration file - /etc/ssh/sshd_config and change the parameter:

#GatewayPorts no

But we won't do that now, this is just a note.

Let's continue. Let's move on to setup Putty On our Windows-car. Everything is simple here - we use example 1 from this article, just change the port to the desired one (in the screenshot, by the way, it is there). Let's connect Putty to the host host-2, set up tunnel. Change settings in the browser proxy— and we get what we need, specify the address http://localhost:3002:

SSH is quite sensitive to packet loss, so tunnels can be dropped frequently.

To avoid this, you can either play with the parameters in the sshd settings file - /etc/ssh/sshd_config:

#TCPKeepAlive yes #ServerAliveInterval #ServerAliveCountMax

Or use the autossh utility.

The article gives detailed analysis theory and practice of building SSH tunnels based on PuTTY. There is a lot of information on this matter on the Internet, but it is not systematic and often represents only a scattered set of practical recipes.

Terminology

To simplify the understanding of the material, the article uses terminology, which I strictly adhere to and which has a clear meaning.

Client— computer-source of requests. For example, a browser or ssh client.
Server— request processing computer. For example, a desktop on a local network.
Basic scheme— an interaction scheme in which only the Client and the Server participate.
Extended scheme- extension basic circuit, when the Client and Server are mediated by a Proxy.
Proxy— an intermediary computer between the Client and the Server in an extended scheme.
Straight tunnel— a tunnel in which the direction of initiating an SSH session and requests coincide.
Return tunnel— the direction of initiating an SSH session and client requests are opposite.
Source port(source port) - the port at one end of the tunnel where the request from the Client arrives.
Can be for PuTTY local "Local" (at the same end of the tunnel as PuTTY) and remote "Remote" (at the opposite end).
Destination(destination address) - IP address and port of the computer for which packets leaving the tunnel are intended. In the extended scheme, this is always the Server itself.

SSH tunnels are created to solve 2 independent problems:

  1. Ensuring the confidentiality of data transmitted over a secure channel
  2. Creating a connecting bridge (or several bridges) between the Client and the Server through intermediate computers, since the Client may not have direct access to the Server. In this case, confidentiality is secondary or not required at all.

SSH tunnels can be organized both in the mode of redirecting individual TCP ports (Port forwarding), and in the mode of real VPN tunnels through virtual interfaces, when traffic of any protocols and from any ports can be transmitted. In this article we will look at the first mode.

When operating in Port Forwarding mode, a packet arriving at a tunnel's input port must be transmitted unchanged to its output port. This scheme is used in the operation of Internet gateways: packets from one interface are transmitted to another without modification or analysis.

Thus, an SSH channel in this mode with its entire infrastructure resembles a virtual gateway with input and output interfaces, but only for a specific pair of TCP ports:

The arrow indicates the direction in which the SSH session is initiated. In this case, the initiator of the connection is the Client with PuTTY installed on it.

The above scheme is a basic one, in which only 2 participants interact: Client and Server. In practice, there may be several intermediate hosts between the Client and the Server. Both before reaching the entrance of a particular tunnel and after leaving it, packets can be transmitted over unprotected channels.

To establish communication via the SSH protocol, you need Account on an SSH server, which can be anything, including without any rights and even without a shell, if you open unprivileged ports from 1024 and higher for listening. Otherwise, root access and directive value is required PermitRootLogin equal yes or without-password.

Analysis of connectivity and accessibility of interaction participants

When starting to solve the problem of how to provide access from the Client to the Server, it is useful to build a diagram of the connectivity of participants in interaction using the SSH protocol, since it is through this protocol that tunnels are created, through which data of any other protocol can then be passed.

To do this, we must answer the question of where the SSH servers are located and whether they are accessible using SSH clients from other hosts.

Let's look at these steps based on an extended scheme consisting of a Client, an intermediate Proxy Server and a Server. In practice, such schemes are most common.

If you connect machines accessible via the SSH protocol with arrows, then the following options are possible:

In particular, we connect the Client with the Proxy with an arrow if the Proxy is accessible from the Client on port 22. Having sorted through all the interaction participants in pairs, we obtain a connectivity diagram. For example:

The connectivity diagram arrows show where a tunnel to the SSH server machine can be initiated.

After building the connectivity diagram, you need to make sure that the participants in the interaction are accessible to each other via arbitrary protocols and ports, since you need to somehow connect to the created tunnel, or, conversely, forward the data further. In other words, you need to check whether they ping or not. By analogy with the connectivity scheme, you can build an accessibility scheme that at least coincides with the connectivity scheme, but most often is wider than it:

The availability diagram shows in which direction data can be transmitted over a channel not protected by a tunnel.

The combination of both schemes helps answer the question of whether it is fundamentally possible to establish a connection between the Client and the Server, and if it is not, then what needs to be added to get it.

In the future, we will use these diagrams to build a communication channel.

The above scheme is very common: Client and Server (most often on Windows based) are located in different local networks behind NAT, have access to the Internet and “see” the remote Proxy server, whereas with a Proxy they are inaccessible either via SSH or other protocols. The Proxy usually has a *nix-like operating system, which has an SSH server by default.

In schemes based on *nix systems, almost all links are fully connected, since all machines have SSH servers, and SSH ports are usually open for connections.

Algorithm for building a communication channel using SSH tunnels

Let's analyze the algorithm for building a communication channel using an SSH tunnel using the example of the diagram given above, where the Client and Server are located on different local networks behind NATs, and can only be connected via the Internet using some Proxy server.

1) Drawing up an SSH connection diagram

We only have an SSH server on the Proxy, so we can initiate 2 tunnels: from the Client and from the Server:

This is a circuit with two simply connected links.

2) Drawing up an accessibility diagram

The Client and Server are behind NAT, so they are inaccessible from the outside with the Proxy, but the Proxy pings from both the Client and the Server

3) Selecting a link to create a tunnel

To ensure communication between the Client and the Server, one tunnel is sufficient - either Client-Proxy or Proxy-Client, since in the remaining section packets can be transmitted over an unsecured channel.

The Client-Proxy tunnel looks preferable, since in this case we could perform all communication operations from the Client, and from it, according to the conditions of the task, we need to work with the Server.

Packets arriving at the tunnel entrance on the Client's computer are transmitted to the Proxy and then must be redirected to the Destination address, which is the Server. However, according to the availability scheme, the Server is not accessible from the Proxy via the Internet:

Therefore, to transmit packets, you cannot do without creating a second tunnel between the Proxy and the Server:

But the first tunnel, which we pinned our hopes on, will be redundant in such a scheme - we can send packets from the Client to the Proxy through an unprotected environment directly without using a tunnel:

The Client-Proxy tunnel can be left only if it is important from a confidentiality point of view (something is transmitted through it in clear text and so on.).

4) Selecting the Proxy Server tunnel type: forward or reverse

In fact, the type of tunnel is already predetermined. Client requests arrive at the Source Port, which is located on the Proxy, and the tunnel is initiated from the Server. This means that the direction of tunnel initiation and client requests will be opposite. Therefore the tunnel will be reversed (option -R).

5) Specifying connection parameters and creating a tunnel

Thus, the following algorithm for constructing a communication channel emerges:

  1. Create an SSH connectivity diagram based on the location of SSH servers
  2. Create an accessibility diagram.
  3. Select a link: Client-Proxy or Proxy-Server (for an extended scheme)
  4. Select the tunnel initiation direction if the link is fully connected.
  5. Select the type of tunnel based on the direction of the client’s requests: direct or reverse
  6. Write port forwarding formulas in PuTTY (Source port, Destination and additional options) for each tunnel

Understanding the principles described above, it is easy to set correct settings both on the SSH-Tunnels tab in PuTTY and on the command line of the OpenSSH client. In particular, the following axioms are true:

Source port— this is the tunnel port to which Client requests are received.
If the direction of tunnel initiation and the Client's requests are the same (direct tunnel), then the port is on the same end as PuTTY and is local for PuTTY (option -L, Local).
Otherwise, the Source port is on the opposite side of the return tunnel and is remote for PuTTY (option -R, Remote)
In 99% of cases, the Source port is opened for listening on the loopback interface of the machine to which requests from the Client are received, and therefore is usually omitted. In PuTTY, there is not even a separate place for the IP address of the request source - only the Source port.

Destination- this is the IP address and port of the computer to which data is transmitted at the exit of the tunnel. If PuTTY is on Destination, then this will obviously be localhost.
Unlike a loopback IP address at the entrance of a tunnel, data at the exit of a tunnel can be sent anywhere, including to hosts with different IP addresses.

This is enough to set the correct settings for all SSH tunnel options. The most typical of them are presented below using specific examples.

I will also give the command line syntax of the OpenSSH client in terms of PuTTY, if you want to initiate a tunnel from some *nix system according to the basic scheme:

ssh [-g] [-p port] : user@Server

and according to the extended scheme:

ssh [-g] [-p port] : user@Proxy

Here under refers to a port with keys, for example: -L 5000 (forward tunnel), -R 5000 (reverse tunnel) or -D 5000 (dynamic port forwarding; omitted in this case)
[-p port]— connect to the Server or Proxy on a port other than 22.
[-g]— an option that allows connections to a local (Local) or dynamic (Dynamic) port not only from localhost, but also from external addresses.

To allow a similar ability to connect to a remote (Remote) port from external addresses, you must register in the SSH server configuration file /etc/ssh/sshd_config option:

GatewayPorts clients specified

thanks to which the inclusion of this feature is carried out at the request of the client, or

GatewayPorts yes

when this option is always enabled.

Basic scheme

The basic interaction scheme involves only 2 computers connected by a tunnel.

According to this scheme, 2 types of tunnels are possible - forward and reverse, depending on which side the SSH session is initiated from. According to this, PuTTY is always at the end of the tunnel where the arrow begins.

Extended scheme

An extension of the basic scheme is a scheme with an intermediate proxy server to which either the Client connects or from which a connection is established with the Server. There are 4 options here.

In principle, all four options for the extended scheme are equal, if we abstract from the specific implementation of the SSH client. But since we are considering working through PuTTY in this article, we can initiate tunnels only from Windows-based machines, i.e. most often either from the Client or from the Server.

Situations in which an SSH session using PuTTY is initiated from an intermediate server are quite rare, since proxy servers are usually machines without graphical shell running *nix-like OS, and instead of PuTTY there will be OpenSSH.

To complete the picture, below is the syntax of the OpenSSH client in terms of PuTTY, if you suddenly need to initiate a tunnel using OpenSSH.

Practical examples of using SSH tunnels

1. Direct tunnel according to the basic scheme

Let's look at protecting an open protocol from interception using POP3 as an example.

Instead of receiving mail on the local computer directly via the Internet and exposing ourselves to the risk of losing the password transmitted in clear text, we receive it through a tunnel with the mail server on port 110. The mail client in this case must be configured to receive letters from the localhost address :5000

The diagram is provided for illustrative purposes, since all email clients Now they can work using secure protocols, and the choice of ports is strictly limited.

Client# ssh -L 5000:Server:110 user@Server

Connectivity and accessibility scheme for a system with a Server behind NAT:

This is the case when you need to log in from one computer (Client) to another (Server) over a local network, but direct connection not provided with it. However, there is access to the Client from the Server. To do this, an SSH session is initiated from the Server, that is, from the computer to which we want to connect. As a result, a return tunnel is created.

To raise a reverse tunnel to the Client, you need to install an SSH server and specify from which remote port (Remote Source port) to which local port for PuTTY the forwarding will be performed.

The equivalent command for the OpenSSH client is:

Server# ssh -R 5000:localhost:3389 user@Client

Connectivity and accessibility scheme for a system with a Client behind NAT:

This scheme allows you to safely connect to the Internet through unverified sources, for example, Wi-Fi access points in cafes and restaurants. All traffic goes through the access point in encrypted form from the remote Server.

As you know, the browser sends requests to sites on the Internet from arbitrary ports of the WAN interface of the computer. In PuTTY, this mode is provided in the form of the Dynamic option. All browser requests through the tunnel are routed from some source port 5000 on the machine running the SSH client, and assigned dynamically at the other end. Therefore, the final port is not specified.

Since browsers cannot work directly through SSH tunnels, in the connection settings via a proxy server you need to select a connection via SOCKS (v5) to the address localhost:5000 and remove localhost or 127.0.0.1 from the “Do not use proxy for:” field if it it is registered there automatically.

The equivalent command for the OpenSSH client is:

Client# ssh -D 5000 user@Server

By adding the -g option, which is equivalent to the PuTTY “Local ports accept connections from other hosts” option, you can allow other computers to connect to the Client on the specified port and thus turn it into an access point.

The scheme is similar to the previous one, only with a reverse connectivity scheme (the Client is prohibited from accessing the Internet).

This means that we can initiate a tunnel only from the Server. Obviously, an SSH server must be deployed on the Client. For Windows based Clients good choice There will be a Bitvise SSH server on port 443. FreeSSHd server with reverse tunnels did not work for me.

So, for the scheme to work, you need to make a proxy from the Socks Server on port 5000, creating a tunnel with itself:

Server# ssh -D 5000 user@Server

And after that, establish a reverse tunnel with the Client, in which requests on port XXXX are redirected to port 5000 of our Socks proxy:

Server# ssh -R XXXX:localhost:5000 user@Client

The peculiarity of this scheme is that reverse tunnels along the chain can be forwarded further to other computers that do not have access to the Internet.

This idea is the basis of a similar circuit from this article, but in it the tunnel is initiated in the opposite direction by an expression like this:

Proxy# ssh -D 5000 -R XXXX:localhost:5000 user@Server

And only then a computer that does not have access to the Internet connects to the Server using a reverse tunnel:

Server# ssh -R YYYY:localhost:XXXX user@Computer

However, in this case, the Internet request to Server port XXXX is redirected via the reverse tunnel to the computer playing the role of the Proxy Server, and then returns to the Server to be served on it:

Obviously, this method uses an extra loop consisting of Tunnels 2 and 3, which we excluded above by organizing the distribution of the Internet directly from the Server itself.

5. Direct tunnel to an intermediate SSH server

In this case, a tunnel is created with an intermediate Proxy Server, and from it a connection is made to the final remote Server.

This scheme helps out when local computer there is no direct access to the Internet, but there is access to some server within the local network that is connected to the Internet. An example of a connectivity and availability diagram for the case when the Client and Proxy are behind NAT, and the Server is accessible from the Internet:



In another case, the Server is located on a remote local network and is not directly accessible from the Internet, but you can connect to it through an intermediate Proxy on the same local network. Possible scheme connectivity and availability for the case when the Proxy is a gateway and the Client is located behind NAT in its own LAN:



In both cases, the Client needs to connect to localhost:5000.

The equivalent command for the OpenSSH client is:

Client# ssh -L 5000:Server:3389 user@Proxy

This scheme has already been discussed in detail at the very beginning:

In this case, we need to go with home computer to a remote one, which is not accessible from the Internet, but there is an intermediate Proxy, accessible to both the Client and the Server. We found out that communication can only be established using a reverse tunnel from the Server to the Proxy.

For permission remote connection The client must also check the option . This option only works if the connection permission is set to remote port upon client request is allowed in the Proxy server ssh daemon configuration file /etc/ssh/sshd_conf:

GatewayPorts clients specified

After this, the Server should become accessible from the Client via RDP to the Proxy address:5000

The equivalent command for the OpenSSH client is:

Server# ssh -R 5000:localhost:3389 user@Proxy