Usually, we need to enter username and password combination to connect to an SSH console. If the combination is correct to that of the system's then, we get access to the server else we are denied from the access. But, there is something more secure than Password logon, we have passwordless SSH logon using the encrypted keys.
If you want to enable this secured option, we can simply disable password-logon and only allow logon using an encryption key. When using encryption keys option, the client computer generates a private and public key pair. The client then must upload the public key to the SSH server authorized_key file. Before access is granted, the server and client computer validate the key pair. If the public key on the server matches the private key submitted via the client then access will be granted else will be denied.
This is a very secure way authenticating to a SSH server and it’s a recommended method if you wish to implement secure logon with single user SSH logon.
In this tutorial, we'll gonna learn how we can setup Passwordless SSH login to Linux systems. Only the workstations having the correct matching key pair (private and public) will be allowed to logon to the SSH server, without the key paring, access will not be allowed.
Table of Contents
1) Check and Install ssh service
In some new Linux systems openssh-server is already installed by default. So before installing it, check if it is present.
# rpm -q openssh-server openssh-server-6.6.1p1-33.el7_3.x86_64
If it is not installed on your system, so do an update of your repository and install the package.
# yum check-update Loaded plugins: fastestmirror Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast base | 3.6 kB 00:00:00 extras | 3.4 kB 00:00:00 updates | 3.4 kB 00:00:00
# yum install openssh-server
2) Configuring Key Pair using ssh-keygen
To log in to your server without password, you need to use public key authentication to secure the communication. Setting this up will increase the security of your server by requiring a private SSH key to log in.
To generate ssh keys, you can use
ssh-keygen command which will generate two keys and store them in two different files. These two files are stored in a hidden folder .ssh in the user home directory. You can provide your own names for the file or by default it will be stored in id_dsa (private key) and id_dsa.pub (public key) files.
When you create your keys you will be asked for a passphrase. It is used to protect your key and you will be asked for it when you will want to connect via ssh.
# 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. The key fingerprint is: 04:d3:00:7a:25:d0:08:ab:0c:b1:29:d4:e1:7b:62:f2 root@centos-01 The key's randomart image is: +--[ RSA 2048]----+ |ooo=+.=o | |.=oo.o o. | |* ... . | |= .. . | |.o + . S | | + o | | E | | | | | +-----------------+
3) Copy Public Keys Manually or using ssh-copy-id
For no password login, you will need to copy the content of your public key to the server, so create a folder .ssh on the server and copy your "local" public key id_dsa.pub to a file
~/.ssh/authorized_keys which will be created on the server.
To do so you can do manually or by using ssh-copy-id command.
By manual copy
Create a folder .ssh on our server
# ssh email@example.com mkdir -p .ssh The authenticity of host '10.132.6.180 (10.132.6.180)' can't be established. ECDSA key fingerprint is 56:54:51:4d:fe:f4:fb:8f:f0:b4:6c:9c:0d:7c:57:4b. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.132.6.180' (ECDSA) to the list of known hosts. firstname.lastname@example.org's password:
Look the content of our public key
# cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjuK9+zkGJYy1MGjkPH3ZFoDGAm9uYQVdXWc283/yk9/9C+MazFT8mSlHYNTRpBThXH9VKbjHo2SAvm6BocB7m6b0DRErU8Hsp4PRfElDwPn/J8AE+hIkZ/bo2dMUOXTZVsdigpm8dOUCcfKKoZMvOU7C0HTBjeAoj/Nxv/4H5UBgEIg8ihVYeVplcDoT7bCmvES9bb7Ry4lrzusjdXp+mL388EGVU+46O1UNb8KE86tWdT/XTFVkSNFCA3bQLmQMWyuT/tgUEYHETcqBaTdFEGBaJ+pQ85/0b5vRCMktbrkrvPDKeM9BfQkBRKsBJxGR2Ag/HXAq7ieIKMoxs+Smr root@centos-01
Now paste the content of our public key to the remote server
# cat .ssh/id_rsa.pub | ssh email@example.com 'cat >> .ssh/authorized_keys'
By using ssh-copy-id
If you don't want to copy it manually, we can use a command which will do it for us
# ssh-copy-id -i ~/.ssh/id_rsa.pub firstname.lastname@example.org /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 email@example.com's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'firstname.lastname@example.org'" and check to make sure that only the key(s) you wanted were added.
4) Set Permission
On the server, you need to protect the public key so we will set permissions for the access of the key
# chmod 700 .ssh # chmod 600 .ssh/authorized_keys
5) SSH to partner host without password
Now that we have copied our public key to the server, we can access it by using our public key.
Enter the command below to test:
[root@centos-01 ~] # ssh email@example.com Enter passphrase for key '/root/.ssh/id_rsa': Last login: Mon Apr 17 06:01:07 2017 from 10.132.68.13 [root@centos-02 ~] #
You can see that we have been prompted for the passphrase now not the password. We are now connected to our server "centos-02" Now we need to enable only authentication by public key and disable authentication by password.
To do it, we need to edit
/etc/ssh/sshd_config file on the server. Don't delete anything; just modify the lines below like
vim /etc/ssh/sshd_config RSAAuthentication yes PubkeyAuthentication yes PasswordAuthentication no UsePAM no ChallengeResponseAuthentication no
Restart now the service
systemctl reload sshd
How to add keys using ssh-add
Now that we have configured our public for our server connection, we need to enter the passphrase. The problem is, every time that we will need to connect our server, we will be prompted to enter our passphrase which is not different for the situation where we are asking for the password.
So we need a method to automatically check our public key when connecting to our server without prompting for the passphrase. We will use the
ssh-agent command to do it
# ssh-agent $SHELL # ssh-add -L The agent has no identities.
# ssh-add Enter passphrase for /root/.ssh/id_rsa: Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
Try to log into our remote server and the result:
# ssh firstname.lastname@example.org Last login: Tue Apr 18 00:48:08 2017 from 10.132.68.13
You see that we are not prompted for the passphrase
Upgrading SSH keys for Security
It's best practice to enable SSH public key authentication rather than using passwords over the networks. However, it's equally important to renew your SSH keys on frequent time interval for more safety.
At times, people keep on using the same SSH keys over years. Notice that the DSA and RSA 1024 bit keys are deprecated. I advise you to upgrade those keys to the latest Ed25519 key with fast and compact elliptic-curve cryptography with high security signatures.
You can generate those keys with a single command
ssh-keygen -o -a 100 -t ed25519 as below:
# ssh-keygen -o -a 100 -t ed25519 Generating public/private ed25519 key pair. Enter file in which to save the key (/root/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_ed25519. Your public key has been saved in /root/.ssh/id_ed25519.pub. The key fingerprint is: 9a:aa:da:75:a3:58:22:a0:0a:f1:63:62:c2:2f:da:31 root@centos-01 The key's randomart image is: +--[ED25519 256--+ | | | | | | | | |o S | |+o o | |*oE o = | |=B.O + . | |=.*oo | +----------------+
You can have your identification file "~/.ssh/id_ed25519" saved along with your other keys in the .ssh folder. You can copy your public keys
~/.ssh/id_ed25519.pub over to the target hosts for authentication with
# eval `ssh-agent -s` Agent pid 32377 # ssh-add Enter passphrase for /root/.ssh/id_rsa: Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa) Enter passphrase for /root/.ssh/id_ed25519: Identity added: /root/.ssh/id_ed25519 (/root/.ssh/id_ed25519)
Best practice Considerations
Create a normal user account on the remote server
It is recommended to log into a server by ssh with a normal user with normal privileges. So we need to create a normal user account on the server to use for logging and we can be root for extra operations with
su - command.
We will for example create an account 'linoxide' with normal privileges
# useradd -m linoxide
Now we will copy the authorized_keys file to our new user home directory
# cp -R .ssh/ /home/linoxide/
Give the permissions to the account
# chown -R linoxide:linoxide /home/linoxide/.ssh/
Try to connect to our server with our new account
# ssh email@example.com Last login: Tue Apr 18 02:06:25 2017 [linoxide@centos-02 ~]$
Disable ssh root login
Now that we are able to access our server with the normal account, we can disable root login for the best security. So edit
/etc/ssh/sshd_config and we will modify the line
Open the file, the line should like this #PermitRootLogin yes, so we will uncomment it and modify to have the line below
Save the file and restart the service
# systemctl restart sshd
No from the client, try to connect to the server with your root account
# ssh firstname.lastname@example.org Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
You can see that our root can't connect. Now look with our normal account
# ssh email@example.com Last login: Tue Apr 18 02:10:53 2017 from 10.132.68.13 [linoxide@centos-02 ~]$
You see that we can log into the server with the normal account. Now if we need root operations, do
$ su - root Password: Last login: Tue Apr 18 02:23:20 UTC 2017 on pts/1 [root@centos-02 ~]#
Prevent ssh time out session
When we are connected by ssh to a remote server, we can get disconnected when there are no activities after a few number of minutes. This is basically idle timeout. We can prevent it by adding two lines on ssh configuration file.
If we have access to the server, modify our
/etc/ssh/sshd_config file on the server side:
# vim /etc/ssh/sshd_config
Now add the two line below at the end of the file:
ClientAliveInterval 120 ClientAliveCountMax 3
Now let me explain theses lines:
- ClientAliveInterval: sets the timeout interval during which the server sends message to the customer ssh after x seconds without activity (0 = never). If the client answers the server, the connection is maintained.
- ClientAliveCountMax: sets the maximal number of ClientAlive requests without answer which will tolerate the server before closing the connection.
If we don't have a root access to the server, we will create a
~/.ssh/config client file in our home directory
# touch ~/.ssh/config
Now add the two line below
ServerAliveInterval 120 ServerAliveCountMax 3
Hurray! We have successfully enabled Passwordless SSH logon. It is a lot secure to enable Encrypted Key Pair SSH logon . This is a very secure way authenticating to a SSH server and it’s a recommended method if you wish to implement secure logon with single user SSH logon. So, if you have any questions, suggestions, feedback please write them in the comment box below.