Create an SSH public and private key pair for Linux VMs
This article shows you how to generate an SSH public and private key pair to use with Linux VMs. With an SSH key pair, you can create Virtual Machines on Azure that default to using SSH keys for authentication, eliminating the need for passwords to log in. Passwords can be guessed, and open your VMs up to relentless brute force attempts to guess your password. VMs created with Azure Templates or the azure-cli
can include your SSH public key as part of the deployment, removing a post deployment configuration step of disabling password logins for SSH.
Quick Commands
Run the following commands from a Bash shell, replacing the examples with your own choices.
SSH keys are by default kept in the ~/.ssh
directory. If you do not have a ~/.ssh
directory, the ssh-keygen
command creates it for you with the correct permissions. The -N
cli flag is the password to encrypt the private SSH key and is not your user password.
ssh-keygen \
-t rsa \
-b 2048 \
-C "ahmet@myserver" \
-f ~/.ssh/id_rsa \
-N mypassword
There is now a id_rsa
and id_rsa.pub
SSH key pair in the ~/.ssh
directory.
ls -al ~/.ssh
Verify that ssh-agent
is running:
eval "$(ssh-agent -s)"
Add the newly created key to ssh-agent
:
ssh-add ~/.ssh/id_rsa
If you have already created a VM you can install the new SSH public key to your Linux VM with:
ssh-copy-id -i ~/.ssh/id_rsa.pub ahmet@myserver
Test the login using keys instead of a password:
ssh -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes -i ~/.ssh/id_rsa ahmet@myserver
Last login: Tue April 12 07:07:09 2016 from 66.215.22.201
$
SSH is successfully configured if you are not prompted for an SSH private key password, or a login password to the VM.
Detailed Walkthrough
Using SSH public and private keys is the easiest way to log in to your Linux servers. Public-key cryptography provides a much more secure way to log in to your Linux or BSD VM in Azure than passwords, which can be brute-forced far more easily.
Your public key can be shared with anyone; but only you (or your local security infrastructure) possess your private key. The SSH private key should have a very secure password (source:xkcd.com) to safeguard it. This password is just to access the private SSH key and is not the user account password. When you add a password to your SSH key, it encrypts the private key using 128-bit AES, so that the private key is useless without the password to decrypt it. If an attacker stole your private key and that key did not have a password, they would be able to use that private key to log in to any servers that have the corresponding public key. If a private key is password protected it cannot be used by that attacker, providing an additional layer of security for your infrastructure on Azure.
This article creates ssh-rsa formatted key files, which are recommended for deployments on the Resource Manager. ssh-rsa keys are required on the portal for both classic and Resource Manager deployments.
Disable SSH passwords by using SSH keys
Azure requires at least 2048-bit, ssh-rsa format public and private keys. To create the keys use ssh-keygen
, which asks a series of questions and then writes a private key and a matching public key. When an Azure VM is created, the public key is copied to ~/.ssh/authorized_keys
. SSH keys in ~/.ssh/authorized_keys
are used to challenge the client to match the corresponding private key on an SSH login connection. When an Azure Linux VM is created using SSH keys for authentication, Azure configures the SSHD server to not allow password logins, only SSH keys. Therefore, by creating Azure Linux VMs with SSH keys, you can help secure the VM deployment and save yourself the typical post-deployment configuration step of disabling passwords in the sshd_config config file.
Using ssh-keygen
This command creates a password secured (encrypted) SSH key pair using 2048-bit RSA and it is commented to easily identify it.
SSH keys are by default kept in the ~/.ssh
directory. If you do not have a ~/.ssh
directory, the ssh-keygen
command creates it for you with the correct permissions.
ssh-keygen \
-t rsa \
-b 2048 \
-C "ahmet@myserver" \
-f ~/.ssh/id_rsa \
-N mypassword
Command explained
ssh-keygen
= the program used to create the keys
-t rsa
= type of key to create which is the RSA format [wikipedia](https://en.wikipedia.org/wiki/RSA_(cryptosystem)
-b 2048
= bits of the key
-C "myusername@myserver"
= a comment appended to the end of the public key file to easily identify it. Normally an email is used as the comment but you can use whatever works best for your infrastructure.
Classic portal and X.509 certs
If you are using the Azure classic portal, it requires X.509 certs for the SSH keys. No other types of SSH public keys are allowed, they must be X.509 certs.
To create an X.509 cert from your existing SSH-RSA private key:
openssl req -x509 \
-key ~/.ssh/id_rsa \
-nodes \
-days 365 \
-newkey rsa:2048 \
-out ~/.ssh/id_rsa.pem
Classic deploy using asm
If you are using the classic deploy model (Azure service management CLI asm
), you can use an SSH-RSA public key or an RFC4716 formatted key in a pem container. The SSH-RSA public key is what was created earlier in this article using ssh-keygen
.
To create a RFC4716 formatted key from an existing SSH public key:
ssh-keygen \
-f ~/.ssh/id_rsa.pub \
-e \
-m RFC4716 > ~/.ssh/id_ssh2.pem
Example of ssh-keygen
ssh-keygen -t rsa -b 2048 -C "ahmet@myserver"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ahmet/.ssh/id_rsa): id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
14:a3:cb:3e:78:ad:25:cc:55:e9:0c:08:e5:d1:a9:08 ahmet@myserver
The keys randomart image is:
+--[ RSA 2048]----+
| o o. . |
| E. = .o |
| ..o... |
| . o.... |
| o S = |
| . + O |
| + = = |
| o + |
| . |
+-----------------+
Saved key files:
Enter file in which to save the key (/home/ahmet/.ssh/id_rsa): ~/.ssh/id_rsa
The key pair name for this article. Having a key pair named id_rsa is the default and some tools might expect the id_rsa private key file name so having one is a good idea. The directory ~/.ssh/
is the default location for SSH key pairs and the SSH config file. If not specified with a full path, ssh-keygen
will create the keys in the current working directory, not the default ~/.ssh
.
A listing of the ~/.ssh
directory.
ls -al ~/.ssh
-rw------- 1 ahmet staff 1675 Aug 25 18:04 id_rsa
-rw-r--r-- 1 ahmet staff 410 Aug 25 18:04 rsa.pub
Key Password:
Enter passphrase (empty for no passphrase):
ssh-keygen
refers to a password as "a passphrase." It is strongly recommended to add a password to your key pairs. Without a password protecting the key pair, anyone with the private key file can use it to log in to any server that has the corresponding public key. Adding a password offers more protection in case someone is able to gain access to your private key file, given you time to change the keys used to authenticate you.
Using ssh-agent to store your private key password
To avoid typing your private key file password with every SSH login, you can use ssh-agent
to cache your private key file password. If you are using a Mac, the OSX Keychain securely stores the private key passwords when you invoke ssh-agent
.
Verify and use ssh-agent and ssh-add to inform the SSH system about the key files so that the passphrase will not need to be used interactively.
eval "$(ssh-agent -s)"
Now add the private key to ssh-agent
using the command ssh-add
.
ssh-add ~/.ssh/id_rsa
The private key password is now stored in ssh-agent
.
Using ssh-copy-id
to install the new key
If you have already created a VM you can install the new SSH public key to your Linux VM with:
ssh-copy-id -i ~/.ssh/id_rsa.pub ahmet@myserver
Create and configure an SSH config file
It is a recommended best practice to create and configure an ~/.ssh/config
file to speed up log ins and for optimizing your SSH client behavior.
The following example shows a standard configuration.
Create the file
touch ~/.ssh/config
Edit the file to add the new SSH configuration:
vim ~/.ssh/config
Example ~/.ssh/config
file:
# Azure Keys
Host fedora22
Hostname 102.160.203.241
User ahmet
# ./Azure Keys
# Default Settings
Host *
PubkeyAuthentication=yes
IdentitiesOnly=yes
ServerAliveInterval=60
ServerAliveCountMax=30
ControlMaster auto
ControlPath ~/.ssh/SSHConnections/ssh-%r@%h:%p
ControlPersist 4h
IdentityFile ~/.ssh/id_rsa
This SSH config gives you sections for each server to enable each to have its own dedicated key pair. The default settings (Host *
) are for any hosts that do not match any of the specific hosts higher up in the config file.
Config file explained
Host
= the name of the host being called on the terminal. ssh fedora22
tells SSH
to use the values in the settings block labeled Host fedora22
NOTE: Host can be any label that is logical for your usage and does not represent the actual hostname of any server.
Hostname 102.160.203.241
= the IP address or DNS name for the server being accessed.
User ahmet
= the remote user account to use when logging in to the server.
PubKeyAuthentication yes
= tells SSH you want to use an SSH key to log in.
IdentityFile /home/ahmet/.ssh/id_id_rsa
= the SSH private key and corresponding public key to use for authentication.
SSH into Linux without a password
Now that you have an SSH key pair and a configured SSH config file, you are able to log in to your Linux VM quickly and securely. The first time you log in to a server using an SSH key the command prompts you for the passphrase for that key file.
ssh fedora22
Command explained
When ssh fedora22
is executed SSH first locates and loads any settings from the Host fedora22
block, and then loads all the remaining settings from the last block, Host *
.