Many people have known SSH for a long time, but, like me, not everyone is suspicious about the possibilities that lie behind these magical three letters. I would like to share my little experience of using SSH for solving various administrative tasks.
Table of contents:
1)
Local TCP forwarding2)
Remote TCP forwarding3)
TCP forwarding chain through several nodes4)
TCP forwarding ssh connections5)
SSH VPN Tunnel6)
besparolnym in short7)
Thank you (links)1) Local TCP forwarding
Let's start with a simple - local TCP forwarding:
')

We have a remote server “host2” with some application, say, a PostgreSQL server that accepts TCP connections on port 5432. At the same time, it is quite logical that there is a firewall on this server that does not allow direct connections from outside to port 5432, but there is SSH access (port 22 by default, I recommend to change it). It is required to connect from our workstation "host1" by the client application to the PostgreSQL server on "host2".
To do this, on “host1” in the console type:
host1# ssh -L 9999:localhost:5432 host2
Now on “host1” we can connect to the PostgreSQL server via local port 9999:
host1# psql -h localhost -p 9999 -U postgres
If on "host1" WindowsFor example, in PuTTy it is done like this:
Go through the settings tree: Connection → SSH → Tunnels.
Next, in the field “Source port” we drive 9999, in “Destination” - localhost: 5432, and click Add.
Do not forget after that save session settings, if required.

How it worksAfter successfully connecting to the SSH server on “host2”, on “host1”, the SSH client starts listening on port 9999. When connected to port 9999 on “host1”, the SSH server on “host2” connects to localhost (which is for “host2” itself) to port 5432 and sends the data received by the ssh client to “host1” on port 9999 over this connection.
IMPORTANT! All connections indicated on the diagrams with arrows are separate TCP connections (sessions).
SSH server setupPort forwarding is usually already enabled in the default sshd settings.
/ etc / ssh / sshd_config:
AllowTcpForwarding yes
We can also connect to the application not on the “host2” itself, but on any machine accessible to it:

To do this, when forwarding ports, instead of “localhost”, we indicate the name of the host, for example, “host3”:
host1# ssh -L 9999:host3:5432 host2
It is important to note here that “host3” must be known (if this is the name, not the IP address) and is available for the host2 machine.
It is also possible through “host1” to provide access to any other node (let's call it “host1A”) to the service on “host3”:

To do this, insert into the ssh connection command the IP address of the interface on which local port 9999 will be raised:
ssh -L 0.0.0.0:9999:host3:5432 host2
In this example, port 9999 will be open on all available on “host1” IPv4 interfaces.
2) Remote TCP forwarding
But what to do if, for example, “host2” does not have a white IP address, is it behind NAT or in general all incoming connections to it are closed? Or, for example, Windows is on “host2” and there is no possibility to install an SSH server?
For this case, there is Remote TCP forwarding:

Now you need to establish an ssh connection in the opposite direction - from “host2” to “host1”. Those. Our administrative workstation will be an SSH server and will be accessible via SSH with “host2”, and on “host2” we will need to connect with an SSH client:
ssh -R 9999:localhost:5432 host1
If on "host2" WindowsFor example, in PuTTy it is done like this:
Go through the settings tree: Connection → SSH → Tunnels.
Next, in the field “Source port” we drive in 9999, in “Destination” - localhost: 5432, and below we select “Remote”, and click Add.
Do not forget after that save session settings, if required.

How it worksAfter successful connection, on “host1” the SSH server starts listening to port 9999. When connected to port 9999 on “host1”, the SSH client on “host2” connects to localhost (which is also “host2” for itself) to port 5432 and sends over this connection the data received by the ssh server on "host1" on port 9999.
Also, you will have additional security issues on “host1” if you do not trust the host2 node. However, this is beyond the scope of this article.
And, of course, you must somehow (yourself or with help) initiate an ssh connection from “host2” by entering the above command, and “host1” must have a white IP address and an open SSH port.
After installing an ssh connection, everything works in the same way as the previous chapter.
3) TCP forwarding chain through several nodes
In closed networks, it often happens that the node we need is directly unavailable. Those. we can go to the desired host only by the chain, for example, host1 → host2 → host3 → host4:
host1# ssh host2
host2# ssh host3
host3# ssh host4
host4# echo hello host4
This can occur, for example, if these nodes are gateways, or if only gateways to neighboring subnets are accessible on them.
In this case, we can also do TCP forwarding along the chain:

Here, ports 9991, 9992, 9993 are chosen for clarity, in practice you can use the same port (for example, 9999), if it is free on all nodes.
Total need to run the following command chain:
host1# ssh -L 9991:localhost:9992 host2
host2# ssh -L 9992:localhost:9993 host3
host3# ssh -L 9993:localhost:5432 host4
How it worksAfter successful execution of the above commands, the following is done on the nodes:
- “host1”: opens port 9991, when connected to which data is redirected via ssh connection to port 9992 to “host2”;
- “host2”: opens port 9992, when connected to which data is redirected via ssh connection to port 9993 to “host3”;
- on “host3”: opens port 9993, when connected to which data is redirected via ssh connection to port 5432 on “host4”;
Thus, when connecting to port 9991 to “host1”, data is redirected along the chain to “host4” to port 5432.
IMPORTANT! All connections indicated on the diagrams with arrows are separate TCP connections (sessions).
4) TCP forwarding ssh connections
Sometimes it is necessary to connect via ssh to a server that is directly unavailable, and access is possible only through a chain of ssh servers (see previous chapter). Now we have the necessary knowledge to do the following:

host1# ssh -L 2222:localhost:2222 host2
host2# ssh -L 2222:host4:22 host3
Thus, on port 2222 on “host1” we now have forvarding on the SSH port (22) on “host4”. We can connect:
host1# ssh -p 2222 localhost
host4# echo hello host4
It would seem, why is it necessary? For example, here's why:
# host4
host1# scp -P 2222 /local/path/to/some/file localhost:/path/on/host4
# host4
host1# scp -P 2222 localhost:/path/on/host4 /local/path/to/some/file
# TCP forwarding host4
host1# ssh -p 2222 -L 9999:localhost:5432 localhost
host1# psql -h localhost -p 9999 -U postgres
# , ssh -p ,
# scp -P
Well, in general, it's great that now “host4” is so close :)
Conclusion: you can do TCP forwarding at a high level of nesting.
RSA fingerprint notesIn some cases, scp will not work until you first log in via ssh -p 2222 localhost and accept the remote server's RSA fingerprint.
If you use the same port (2222) to access different remote servers, there will be RSA fingerprint errors that remain from the previous server. It will need to be removed from ~ / .ssh / known_hosts.
5) SSH VPN Tunnel
TCP port forwarding is a great opportunity. But what if we need more? Access over UDP, access to multiple ports and hosts, access to dynamic ports? The answer is obvious - VPN. And the almighty SSH from version 4.3 and here will come to our aid.
Looking ahead, I’ll say: this SSH functionality works well if you need a temporary solution for some administrative tasks. This option is far from the most suitable for building permanent VPNs, since it assumes TCP-over-TCP, which will have a bad effect on the connection speed.
More about TCP forwardingBut TCP port forwarding using SSH, if there is enough of it, in many cases will gain VPN performance, since when TCP port forwarding only application data is transmitted, not the original packets along with the headers, see link:
http: //blog.backslasher.net/ssh-openvpn-tunneling.html SSH server setup:PermitTunnel is turned off by default in sshd settings, it needs to be enabled in / etc / ssh / sshd_config:
PermitTunnel yes
or
PermitTunnel point-to-point
IMPORTANT : to raise the new network interface of the tunnel on both the ssh client and ssh server requires superuser rights. You can argue about how insecure it is, but in most cases the settings on the ssh server are enough:
PermitRootLogin without-password
Thus, you prohibit root login with a password, and allow only by other means, for example, using the RSA key, which is much safer.
Restart sshd:
sudo service sshd restart # centos
or
/etc/init.d/ssh restart # (debian/ubuntu)
The tunnel rises when using the magic key -w:
host1# sudo ssh -w 5:5 root@host2
Where 5: 5 is the interface number on the local machine and on the remote one, respectively. Here you may be confused that ifconfig will not issue a “tun5” in the interface list. This is because it is in the "down" state, but if you call "ifconfig -a" or "ifconfig tun5", the interface will be visible:
host1# ifconfig tun5
tun5 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Assigning IP addresses to interfaces and raising them:
host1# sudo ifconfig tun5 192.168.150.101/24 pointopoint 192.168.150.102
host2# sudo ifconfig tun5 192.168.150.102/24 pointopoint 192.168.150.101
If there is a firewall, do not forget to allow connections from the tun5 interface:
host1# #
host1# sudo iptables-save > /tmp/iptables.rules.orig
host1# sudo iptables -I INPUT 1 -i tun5 -j ACCEPT
host2# #
host2# sudo iptables-save > /tmp/iptables.rules.orig
host2# sudo iptables -I INPUT 1 -i tun5 -j ACCEPT
It is not necessary to do this on host1, here it is done only for ping to work in both directions.
Enjoying ping:
host1# ping 192.168.150.102
host2# ping 192.168.150.101
If we consider an earlier example with PostgreSQL, now the scheme will be as follows:

And the command to connect to the PostgreSQL server will look like this:
host1# psql -h 192.168.150.102 -U postgres
Well, then you can do any of these nodes by the gateway, if you want to provide access not to one node, but to the network. For example:
host2# # IP forwarding
host2# sudo sysctl -w net.ipv4.ip_forward=1
host2# # IP forwarding host1
host2# sudo iptables -I FORWARD 1 -s 192.168.150.101 -j ACCEPT
host2# # IP forwarding host1
host2# sudo iptables -I FORWARD 1 -d 192.168.150.101 -j ACCEPT
host2# # IP host1
host2# sudo iptables -t nat -A POSTROUTING -s 192.168.150.101 -j MASQUERADE
host1# # , host2 192.168.2.x, host1
host1# # host2 192.168.2.x
host1# sudo ip route add 192.168.2.0/24 via 192.168.150.2
host1# # host1
host1# ping 192.168.2.1
After the end of the work, do not forget to return net.ipv4.ip_forward and the firewall to its original state.
host1# sudo iptables-restore < /tmp/iptables.rules.orig
host2# sudo iptables-restore < /tmp/iptables.rules.orig
Under the spoiler a more interesting case with the temporary sharing of the InternetSuppose you need to set up a server in a closed network where Internet access is prohibited, but nevertheless you have a loophole there — access via a single ssh server or chain of ssh servers. Suppose you need Internet access to set up a server. It is then easier to set up temporary Internet access yourself on the server that you need to set up than to ask the attendants to do this.
Suppose there is ssh access from your host1 host machine to the host2 server, from it to host3, and from there to the host4 you need. Then we do TCP forwarding for ssh (if you can connect directly to host4 from host1, skip this step):
host1# ssh -L 2222:localhost:2222 host2
host2# ssh -L 2222:host4:22 host3
Next, connect to host4 and raise the tun5 interface:
host1# sudo ssh -p 2222 -w 5:5 root@localhost
host1# # host4 : sudo ssh -w 5:5 root@host4
host1# sudo ifconfig tun5 192.168.150.101/24 pointopoint 192.168.150.102
host4# sudo ifconfig tun5 192.168.150.102/24 pointopoint 192.168.150.101
We look at the routing table on host4, let's say we see the following:
host4# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.150.0 0.0.0.0 255.255.255.0 U 0 0 0 tun5
192.168.56.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
0.0.0.0 192.168.56.254 0.0.0.0 UG 0 0 0 eth0
IMPORTANT ! Next, we most likely want to make the default route interface tun5 with the gateway 192.168.150.101, through which the Internet will be available. Therefore, at this stage it is important to know exactly which routes need to be added in order to replace the default route. This is important because quite often routes to individual networks are not prescribed separately, but simply set a default route (0.0.0.0/0) with a gateway, through which all inter-network traffic goes. Moreover, it is likely that your ssh connection to the server also uses the original default gateway.
For simplicity, in this example, assume that no routes other than 192.168.56.0/24 are needed for normal operation of the server and that the previous ssh host host3 has an IP address from the same network.
We memorize and write somewhere the original route table with the default gateway:
host4# route -n > routes.orig
We configure our host1 to work as a gateway to the Internet for host4:
host1# # IP forwarding
host1# sudo sysctl -w net.ipv4.ip_forward=1
host1# #
host1# sudo iptables-save > /tmp/iptables.rules.orig
host1# # IP forwarding host4
host1# sudo iptables -I FORWARD 1 -s 192.168.150.102 -j ACCEPT
host1# # IP forwarding host4
host1# sudo iptables -I FORWARD 1 -d 192.168.150.102 -j ACCEPT
host1# # IP host4
host1# sudo iptables -t nat -A POSTROUTING -s 192.168.150.102 -j MASQUERADE
Just in case, you can register gray networks on the gateway from the current route by default.If not spelled out:
sudo ip route add 192.168.0.0/16 via 192.168.56.254
sudo ip route add 10.0.0.0/8 via 192.168.56.254
sudo ip route add 172.16.0.0/12 via 192.168.56.254
Change the default route to host4 (CAUTION, see warning above!):
host4# sudo ip route replace default via 192.168.150.101
host4# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.150.0 0.0.0.0 255.255.255.0 U 0 0 0 tun5
192.168.56.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
0.0.0.0 192.168.150.101 0.0.0.0 UG 0 0 0 tun5
If we do not need the entire Internet, but only specific IP addresses / masks, then we can not change the default route, but add only the addresses we need through the gateway to tun5.
Checking what the Internet is:
host4# ping 8.8.8.8
Fine. It remains to configure the DNS. There are many ways to do this, the easiest way is to edit the /etc/resolv.conf file and add lines to it:
nameserver 8.8.8.8
nameserver 8.8.4.4
After that, the Internet should be fully accessible:
host4# ping ya.ru
After finishing work, do not forget to return everything to its original state:
host1# # host1
host1# sudo iptables-restore < /tmp/iptables.rules.orig
host1# # net.ipv4.ip_forward
host2# # - host4:
host2# sudo ip route replace default via 192.168.56.254
host2# # DNS- /etc/resolv.conf
6) besparolnym in short
I think everyone already knows that password authorization is not about us. But just in case, I will shove here a brief instruction on setting up authentication using the RSA key:
1. On client machines, we generate the user the RSA key:
client1# ssh-keygen -t rsa
By default, the private key is stored in ~ / .ssh / id_rsa, and the public key is saved in ~ / .ssh / id_rsa.pub. Keep the private key as the apple of the eye and do not give it to anyone, do not copy it anywhere.
When creating a key, you can set a password (passphrase) with which the key will be encrypted.
2. Client public keys need to be saved on the ssh server in the file ~ / .ssh / authorized_keys (~ this is the home directory of the user that will log in), each on a separate line. In order not to do this manually, on each client you can use the command:
ssh-copy-id user@sshserver
Where user is the user name on the server, sshserver is the name or IP address of the ssh server.
Permissions to the file ~ / .ssh / authorized_keysUPD from
sabio : In case of manual creation of the ~ / .ssh / authorized_keys file on the ssh server, the following rights must be set:
chmod 0700 ~/.ssh
chmod 0600 ~/.ssh/authorized_keys
3. Check that you can log into the server using the key, without entering the password (not to be confused with the passphrase):
ssh user@sshserver
I recommend not to close at least one active ssh session with the server until you finally finish the configuration and make sure that everything works.
4. Disable the password entry in the / etc / ssh / sshd_config file on the SSH server:
PasswordAuthentication no
The ability to log in with a public key is usually already enabled by default:
PubkeyAuthentication yes
I usually also disable the following two options:
GSSAPIAuthentication no
UseDNS no
In some cases, this allows you to speed up the connection process (for example, when the server does not have Internet access).
5. Restart sshd:
service sshd restart
or
/etc/init.d/ssh restart
In case of errors, it is useful to look at the / var / log / secure log or use the -v, -vv or -vvv options to display the detailed connection log:
ssh -vvv user@sshserver
7) Thank you (links)
help.ubuntu.com/community/SSH_VPNhabrahabr.ru/post/87197blog.backslasher.net/ssh-openvpn-tunneling.html