How to not remember any password ?

February 20, 2016



    In our company or home network, we have access to several computers. We probably want to interact with some of them, start some tasks, check some logs, reboot them and so on.

    Of course, we are already using ssh to do so. But, if you are still typing a username and password each time you log in somewhere, please stop.

    Summary

    Passwords are obsolete

    We should stop losing our time, by looking at some excel to get the password or such, and use the power of the public-key cryptography. Smart people created that for a reason.

    The principle is simple :

    • We have a (private) key in a file on our computer.
    • The other computer has our (public) key in a file.
    • Those keys are strongly related.

    When we 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 talk to each other using the keys each of them have. If they succeed, it means we are the one with the good private key (only our computer stores it, nothing else), we are how we claim to be, and therefore we have access.

    Keys can be used with GitHub, BitBucket, anything

    This keys approach does not only apply to the networks where we ssh.

    It applies to the whole Internet, such as GitHub, BitBucket, or anything that has a login and password.

    We are not doing pure ssh command-line with them but we are pushing data into them. Data that need to be authenticated.

    That’s why they offer the possibility to add some public keys for our account (through their UI) that will work in pair with the private key we have stored on our 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 /root/.ssh/id_rsa:

    -----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEA/gV3aLUTDenLFw7hkkfNcJT4pbnt7gQVcjga4Rik4+hIU6a6
    ...
    -----END RSA PRIVATE KEY-----

    We must never share this, never ever.

    Its related public key is in /root/.ssh/id_rsa.pub:

    ssh-rsa AAAAB3NzaC1yc2EAAAADA...slxyu9Ki8Hn6jWR root@computer

    The keys are related to our user and hostname.

    We are going to copy that line to any server we want to access. It will use the user@hostname to find out if it has a public key for us.

    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 "email@example.com"

    It’s dangerous to go alone, take this

    Now, we are going to copy our public key to the server.

    We will be able to identify ourself to the server and get the access.

    The default path used by sshd is .ssh/authorized_keys in the home folder of the user we want to connect:

    root@local:~# ssh john@server

    The path on the server would be: /home/john/.ssh/authorized_keys.

    We 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 we save the file, we’ll be able to connect from our local computer on the server, no question asked.

    root@local:~# ssh john@server
    john@server:~$

    One-way only

    This configuration is a one-way only.

    We can’t connect from the server to the local, we need the reverse association.

    If we want that, we must perform the same actions but from the other side (generate keys on the server and add the public key to our local computer).

    But that’s considered a bad practice: a user on a server should never be able to connect to another computer. We should always exit to our local computer, then connect to the other server. We should not connect nodes between them, it can introduce security issues.

    Never reset the public key

    Once we put our public key somewhere, we should never generate again our keys on our computer.

    Otherwise we’ll lose the public/private keys association and thus, the ability to connect to the servers we set up. The public key on the servers won’t “match” anymore our local private key.

    Hopefully, ssh-keygen will warn us if that’s the case.

    .ssh/config

    The username is optional

    Another great feature is to avoid typing the username we want to login with on the server.

    Instead of :

    root@local:~# ssh john@staging

    We’d like to do:

    root@local:~# ssh staging

    While having automatically john as username on the server.

    To do so, we can edit the file .ssh/config and add something like :

    Host staging
        HostName staging.host.lan
        User john

    We can add as many hosts as we want in this file: it’s simply a list of mappings.

    Generic ssh option

    .ssh/config is not only useful to declare Host mappings.

    It can contain way more configuration bits, such as :

    Host *
        ServerAliveInterval 60

    This can avoid us the famous broken pipe we’ll get if we are inactive in a ssh session.

    That will send keep alive packets to be sure the connection stays up.

    Copy files using ssh

    The keys are not only used by ssh.

    scp is also compatible (used 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.

    For a better security

    For a better security, our keys should have a passphrase (that we set to blank in our example).

    We should also use ssh-agent to avoid typing it when needed.


    Feel free to share this article: 

    Join the club and receive an email when I post a new article! No spam ever, no worries.

    Me, Stéphane Derosiaux

    Hi, I'm Stéphane, CTO of Conduktor, a major Apache Kafka Platform. I live in France. Enthousiast and eager to learn, I'm always seeking for challenges. Find out more about me.



    Ready to work with me?

    Tell me everything!
    © Copyright 2018-2022 · Stéphane Derosiaux · All Rights Reserved.