Damn, I forgot the password.
– Me
This is a crosspost of my medium post.
In your company network, or home network, you have access to several computers, and you probably want to interact with some of them, start some tasks, check some logs, reboot them and so on.
Of course, you are already using ssh to do so.
If you are still typing a username and password each time you log in somewhere, stop it.
Passwords are obsolete
Stop losing your time, looking at your excel to get the password or such, and use the power of the public-key cryptography. Smart people did that for a reason.
The principle is simple :
- you have a (private) key in a file on your computer
- the other computer has your (public) key in a file
- those keys are strongly related
When you are going to connect to the other computer, both ssh and sshd (the daemon waiting for connections) will talk to each other and will check if they can make some kind of association using the keys each of them have. If they succeed, it means your are the one with the good private key (only your computer stores it, nothing else), it knows you, you are how you claim to be, and therefore you have access.
Can be used with GitHub, BitBucket, anything
Note that this approach does not only apply to the networks where you ssh, but to the whole Internet such as when you are using GitHub, BitBucket, or anything that has a login and password.
You are not doing pure ssh command-line into them but you are pushing data into them. Data that need to be authenticated. That’s why they offer the possibility to add some public keys for your account (through their UI) that will be in pair with the private key you have stored on your local computer.
Time to do some hacking
Here is my key
First, we need to generate those keys on our local computer :
# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub.
By default, we won’t put any passphrase, even if that can be considered as a bad practice.
That will generate a private key in the file /root/.ssh/id_rsa :
-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA/gV3aLUTDenLFw7hkkfNcJT4pbnt7gQVcjga4Rik4+hIU6a6 ... -----END RSA PRIVATE KEY-----
Never share this, never ever.
And its related public key in /root/.ssh/id_rsa.pub :
ssh-rsa AAAAB3NzaC1yc2EAAAADA...slxyu9Ki8Hn6jWR root@computer
The keys are related to your user and hostname. You are going to copy that line to any server you want to access. It will use the user@hostname to find out if it has a public key from you.
A message can be encrypted using this public key, only by its private key.
Note that it’s popular to add some options to ssh-keygen, to generate a stronger key and set explicitly the user name in id_rsa.pub such as :
$ ssh-keygen -t rsa -b 4096 -C ""
It’s dangerous to go alone, take this
Now, we are going to copy our public key to the server. That will make it be able to identify ourself and let us the access.
The default path used by sshd is .ssh/authorized_keys in the home folder of the user you want to connect with on the server :
root@local:~# ssh john@server
Path is : /home/john/.ssh/authorized_keys
You can create it manually if it doesn’t exist yet.
Its content is quite simple, one line per public key (several users could connect as john on the server) :
$ cat .ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAADA...slxyu9Ki8Hn6jWR root@computer ssh-rsa 2cvUZEP4ZuMtElv/Iu6M6...w8Qoa4A3b8a+YNl trainee@macos
As soon as you save the file, you’ll be able to connect from your local computer on the server, no question asked.
root@local:~# ssh john@server john@server:~$
One-way only
This config is a one-way only. You can’t connect from the server to the local. If you’d like to do so, you must perform the same actions but from the other side (generate keys on the server and add the public key to the local computer).
But, do not considerer this. A user on a server should never be able to connect to another computer. You should always get exit to your local computer, then connect to the other server. Do not connect nodes between them, it can introduce security issues.
One computer to rule them all
Once you put your public key somewhere, never generate your keys set on your computer. Otherwise you’ll lose the ability to connect on the servers you set up, because the public key won’t “match” the private key. ssh-keygen will warn you if that’s the case, but better not to try. ;-)
.ssh/config
Even the username can be optional
Another great feature is to avoid to type the username you want to login with on the server.
Instead of :
root@local:~# ssh
It would be nice to do :
root@local:~# ssh staging
And have automatically “john” as user (because this is the one set up with the keys).
To do so, edit the file .ssh/config and add something like :
Host staging HostName staging.host.lan User john
You can add as many hosts as you want in this file. It’s simply some kind of mapping between a name you give “Host” and User@HostName.
Beyond hosts
This file is not only useful to declare Host mappings. It can contain way more configuration bits, such as :
Host * ServerAliveInterval 60
This is to avoid the famous “broken pipe” you’ll get if you are inactive in a ssh session. That will send keep alive packets to be sure the connection stays up.
Beyond ssh
The keys are not only used by ssh.
scp is also compatible (to copy files from/to another host):
$ scp -r staging:/tmp/logs .
It follows the same rule as ssh : using .ssh/config and the set of keys on both sides.
But it’s not enough
Note that for further security, your keys should have a passphrase (that we set to blank in our example), and that you should use ssh-agent to, again, avoid to type it when needed.
Come say hi on twitter :