Anyone who has made it this far deserves praise, but has only sniffed the surface. Now it's finally time to get down to business.
SSH is considered secure by many, probably due to the word „secure“ in „Secure Shell“. „Secure“ only refers to the fact that all content of an SSH connection is strongly encrypted, so it cannot be intercepted.
In reality, SSH is the Swiss army knife for overriding security settings. How to use this and how to protect yourself against it is described here.
What is actually meant by an SSH tunnel? An established SSH connection can be used to transport a wide variety of data, so to speak, on a piggyback. If you think of an SSH connection as a cable between two endpoints and the cable separates into individual strands, the SSH connection is the insulation and the tunnels are the individual fibers it encloses. So, under the protection of the isolation (the encrypted SSH connection), many wires (the tunnels) can be used for other purposes.
Let's look at the helpful use of a tunnel with an example. I work from home and use SSH access to access the company network. I have a connection and can issue commands on individual servers, but I don't have access to the company's intranet. But I would like to and start with a simple tunnel. Web servers usually listen on port 80 or 443, depending on whether http or https is used. So what I need to view an internal website of the server webserver.firma.de in the browser is a connection on ports 80 and/or 443. Unfortunately I only have access via port 22 (SSH).
A small SSH tunnel can help here:
ssh -L 8080:webserver.firma.de:80 -L 8443:webserver.firma.de:443 email@example.com
That was the whole secret. Let's see what happens. The „-L 8080:webserver.firma.de:80“ option opens port 8080 on my PC and forwards the traffic arriving there via the SSH connection to „sshserver.firma.de“. This, in turn, takes the data that SSH can't actually handle and forwards it in a friendly manner to port 80 of „webserver.firma.de“. If I now enter „http://localhost:8080“ in the browser, I suddenly get to the desired page. The same applies to ports 8443 and 443 when using https.
Does that also work the other way around? Can I contact Gmail even though the company's proxy and firewall prohibit it? SSH and the tunnels are also the solution here.
ssh -R 8443:mail.google.com:443 firstname.lastname@example.org
Problem solved. Port 8443 is opened on the „sshserver.firma.de“ server and my SSH client is kind enough to forward incoming traffic to „mail.google.com“. The escape from the oh so secure company network was successful.
That doesn't seem practical if I want to access several of the company's web servers from home. But the developers of SSH have thought of everything. The key to the company is called „Socks Proxy“ or „Dynamic Forwarding“. Any program that supports the use of a proxy server can benefit from this.
ssh -D 3128 email@example.com
starts a socks proxy on my pc listening on port 3128. Traffic coming in there is shoveled over the SSH connection to „sshserver.firma.de“ and distributed as desired (i.e. dynamically) by the counterpart there. If I now switch on the Socks5 proxy in my web browser and set it to „localhost“ port 3128, I can access all of the company's web servers to which „sshserver.firma.de“ has network access. Nice story and helpful for the home office. However, I have my doubts as to whether it is desired.
If the „break-in“ is so easy, what about the „break-out“? In order to reach the entire Internet (browser, mail etc.) from the company, even though firewalls and proxies try to stop me, all it takes is SSH. But since it can be assumed that the company blocks the SSH port in addition to the browser ports, I have to do a little tricking. I need two things
The SSH server is the least of the problems, I just start the service on my home PC. Access from the company to this SSH server is easy to establish with a tunnel
ssh -R 2222:localhost:22 firstname.lastname@example.org
and now on the „sshserver.firma.de“ the command
ssh -D 3292 -p 2222 heimuser@localhost
A little more complex, but definitely within the realm of possibility with two commands.
Of course, you can also use an existing tunnel to create another tunnel in it. The multiple nesting makes it almost impossible to decrypt such a connection, since one does not know how many levels exist. Furthermore, an existing tunnel can be used to hide a VPN in that tunnel. This creates the possibility of connecting a secure network to the home network or to the Internet.
If you look at the other side, i.e. not that of the SSH client but that of the SSH server administrator, you seriously have to ask yourself whether SSH connections can be allowed at all. As always when configuring highly flexible solutions, the answer is a resounding yes, but.
SSH offers not only the client-side possibilities, but also the limitation on the server side. In the following we turn to individual configuration settings.
There are different options for logging on to an SSH server:
The „AuthenticationMethods“ configuration parameter controls which type is permitted or required. A simple two-factor authentication can be implemented by giving the value „publickey,password publickey,keyboard-interactive“. The server now requires both a public key and a password. Registration is only permitted in combination.
The use of public keys can be regulated by letting the administrator instead of each user maintain the authorized_keys file. This file is usually in the ~/.ssh/ directory. If you move this by specifying e.g
only the administrator can enter public keys in a place where the user does not have write access. In combination with signed public keys (see TrustedUserCAKeys), the use of unsigned public keys can be prevented.
So there are a number of options at the authentication level to only grant access to trustworthy users.
The use of tunnels should be regulated. Two parameters allow such a restriction:
AllowTcpForwarding no PermitOpen none
If the use of a tunnel is desired or essential, it can be specifically allowed in a match block
Match Group tunnel AllowTcpForwarding yes PermitOpendbserver:1521
Restricting the opening of a port to certain scripts that have been checked and are therefore considered safe can also help. The corresponding parameter is „ForceCommand“ and can also be used within a match block. Mandatory commands and other restrictions can also be placed in the signature of a public key (alternatively, in the case of unsigned keys, this is done in the authorized_keys file).
Specifying „PermitTunnel no“ in sshd_config prevents the establishment of VPNs that are hidden in an SSH session. This parameter can also be used in a match block.
If a client is allowed to open a port, you have to decide whether the port can only be used by the computer on which it was opened, or whether it can also be accessed by other computers. The „GatewayPorts“ parameter controls this and the default of „No“ should only be changed if you fully understand what the man page says about it.
If you have to grant access to strangers, you have to limit their options as much as possible. Establishing a CHROOT environment locks such users in a „cage“ and potential harm is limited to the contents of the CHROOT environment. Instructions for creating a CHROOT environment are easy to find on the internet. ChrootDirectory /path/to/chroot