Using SSH effectively
The swiss army knife for managing secure multiserver environments.
SSH(Secure SHell) is typically used to log into a remote machine and execute commands on the remote shell. It was designed to provide a secure channel between client and server, over an unsecured network like internet. It was built back in 1995 in order to replace earlier protocols like telnet that did not provide strong authentication nor guarantee confidentiality.
Beyond its basic usage SSH can provide other not so well known capabilities as you can find on this article. All the examples was executed on CentOS 8 machines for both the client and the server but you can replicate them on any other linux distro.
Completely get rid of passwords
SSH is using passwords by default in order to authenticate a client on the server but, under the hood, it is using public key cryptography to authenticate the remote client and allow him to log in remotely. So if a public key that matches your private key is already present on the server, the password is no longer required. And this is how we are doing it.
Log in to any linux machine as "superusr1" and generate your own ssh key pair:
$ ssh-keygen -t ed25519 -C "Production key pair"
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/superusr1/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/superusr1/.ssh/id_ed25519. Your public key has been saved in /home/superusr1/.ssh/id_ed25519.pub. The key fingerprint is: SHA256:WvStGiPaYpuzYNSb1tQIx7vIgX5tHMSNWAKjKxhWJ8I Production key pair The key's randomart image is: +--[ED25519 256]--+ |..o+... | | Eo.o* o | |o. o * o | |oo o + = . . | |+ o o = S . . | |.o . X = . | | + B O o . | | . ++= . + | | .==. . | +----[SHA256]-----+
This will create the files /home/superusr1/.ssh/id_ed25519 and /home/superusr1/.ssh/id_ed25519.pub that are your new private and public key respectively.
It is always a good idea to secure your private key with a strong passphrase. This will complicate its usage in case of a leak. You can also change your passphrase with:
$ ssh-keygen -p
...if your keys are in their default position which is the ".ssh" directory under your home directory.
Now copy your public key on the remote server (this step will require the password for the remote user):
$ ssh-copy-id superusr1@remotesrv1
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/superusr1/.ssh/id_ed25519.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys Password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'superusr1@remotesrv1'" and check to make sure that only the key(s) you wanted were added.
You can now follow the above instructions and try logging into the machine, with:
$ ssh superusr1@remotesrv1
Enter passphrase for key '/home/superusr1/.ssh/id_ed25519': Last login: Tue Jan 7 15:54:48 2020 from 192.168.122.20 The server is Owner's property. Unauthorized access is forbidden by the law. superusr1@remotesrv1:~>
As you can see the remote system is not asking for password anymore but it is asking for the passphrase of your private key created before, in order to open it and use it for the authentication. If you provided the right passphrase and your private key is matching with the public that exists on the server, you are welcomed with a message and you are released to use the remote shell.
Now, because, there is no gain from getting rid of superusr1's password if we are enforced typping a strong passphrase for every usage of the private key, an agent is created for us, called "ssh agent". This agent can load one or more private keys and provide them where are needed. Start it with the command:
SSH_AUTH_SOCK=/tmp/ssh-n9D417KSd4hm/agent.2139; export SSH_AUTH_SOCK; SSH_AGENT_PID=2140; export SSH_AGENT_PID; echo Agent pid 2140;
In order to allow every new SSH session to communicate with the agent you need to set the above environment variables SSH_AUTH_SOCK and SSH_AGENT_PID. So it is faster to start the agent using the following command:
$ eval $(ssh_agent)
We can check the private keys loaded and load a new key with the commands:
$ ssh-add -l
The agent has no identities.
Now if we execute:
$ ssh superusr1@remotesrv1
Last login: Tue Jan 7 15:55:25 2020 from 192.168.122.20 The server is Owner's property. Unauthorized access is forbidden by the law. superusr1@remotesrv1:~>
From now on, passwords are no longer required with ssh and secure copy(scp) commands.
Now lets try to become root on remote server:
superusr1@remotesrv1:~> sudo su -
[sudo] password for superusr1:
As you can see the remote system is asking for superusr1's password again. Lets avoid that typping too.
Firstly configure agent forwarding on your SSH client machine which simply means going to the file /etc/ssh/ssh_config and set the parameter:
Next we need to make a change on the remote server's Pluggable Authentication Modules (PAM). At first, install PAM's module for authentication with ssh-agent:
$ dnf install pam_ssh_agent_auth
Then edit file /etc/pam.d/sudo file adding the follwing lines under #%PAM-1.0 and before everything else:
auth sufficient pam_ssh_agent_auth.so file=~/.ssh/authorized_keys auth required pam_env.so readenv=1 user_readenv=0 session required pam_env.so readenv=1 envfile=/etc/default/locale user_readenv=0 ...
The last thing you need to do is edit /etc/sudoers file on the remote machine running:
...as root and add:
Defaults env_keep += SSH_AUTH_SOCK
Now you can login to the remote system and escallate your privileges without typing any password. You can even use the remote server's ssh client to log into other systems without password as long as the ssh agent is forwarded and your public key is authorized!
SSH server as socks proxy
$ ssh -qND "<local_ip>:<local_port>" -C <remote_user>@<remote_server>
$ ssh -qND "127.0.0.1:8080" -C superusr1@remotesrv1
After that you can set a socks proxy as 127.0.0.1, port 8080 on applications like firefox routing every internet connection through the secured channel with the remote server. Check this for details.
Exposing a remote port locally aka local forwarding
$ ssh -L <local_ip>:<local_port>:<remote_ip>:<repote_port> <remote_user>@<remote_server>
$ ssh -L 127.0.0.1:3389:192.168.122.21:3389 superusr1@remotesrv1
With this you can access a virtual machine's remote desktop service that lives on the remote server, connecting locally on 127.0.0.1, port 3389.
Exposing a local port remotely aka remote forwarding
$ ssh -R <remote_ip>:<remote_port>:<local_ip>:<local_port> <remote_user>@<remote_server>
$ ssh -R 127.0.0.1:24800:192.168.122.20:24800 superusr1@remotesrv1
This will allow the remotesrv1 to connect as a synergy client to the synergy server running locally on 192.168.122.20, port 24800.
- Posted by Kostas Koutsogiannopoulos · Jan. 11, 2020