You get the following message when you connect to your EC2 (Amazon Linux) instance:

The authenticity of host 'robtest.thorn.tech (35.169.173.252)' can't be established.
RSA key fingerprint is SHA256:0Lb2Nqu60KRgkpjzP4XvmwV4/eSqGPYW81NVP9PjSXA.
Are you sure you want to continue connecting (yes/no)?

This wiki page shows you how to sign each EC2 instance. Then a user needs to add a public key to their known_hosts file, and he can log into all signed EC2 instances without getting prompted.

Background

Web browsers have X509 root certificates pre-installed. This lets you trust SSL certificates of sites that you've never visited before.

Unfortunately, OpenSSH (SSH and SFTP) do not support X509 or PKI. So this means you can't use an SSL cert from VeriSign to bypass the authenticity prompt.

What you can do though is create your own self-managed certificate authority (CA). You can sign one (or many) servers. And any client with your public key will trust your servers.

Instructions

On your EC2 server

Make sure there's a DNS entry for domain pointing to the EC2 instance's Elastic IP. I'm using the domain robtest.thorn.tech; just replace this with your own hostname.

Run this command to create a key pair:

sudo su
cd /root
ssh-keygen -f cert_signer

Enter and confirm a passphrase, or hit <enter> twice to skip.

This creates two files:

  • cert_signer: This is the private key that you'll use to sign all of your servers. You might want to move this to a safe place.
  • cert_signer.pub: This is the public key that you'll give to all your users.

Run this command to sign the EC2 instance you're currently logged into:

ssh-keygen -s cert_signer -I cert_signer -h -n robtest.thorn.tech -V +52w /etc/ssh/ssh_host_rsa_key.pub

Here's a brief explanation of the options:

  • -s: This is the signing option
  • cert_signer: This is the private key from the above step.
  • n robtest.thorn.tech: Replace this with your own domain
  • -V +52w: This is one year. You can make this duration longer if you wish.
  • /etc/ssh/ssh_host_rsa_key.pub: This is the server's public host key that you're signing. This (or in my case, the ssh_host_ecdsa_key.pub contents) is what ends up in your known_hosts file after first login.

This creates the following file:

/etc/ssh/ssh_host_rsa_key-cert.pub

This file ends in -cert.pub, and it's a signed version of your server's public host key.

Next, add the following line to your /etc/ssh/sshd_config file (near line 20 is a good place to put it):

HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub

This exposes your signed public host key.

Restart sshd so that your changes stick:

service sshd restart

Now, get the contents of your cert_signer public key:

cat /root/cert_signer.pub

You'll see something like this (it's all a single line):

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTZeLBUF8jjArKTp4s4IGL7ru12rKOItURsvnelBGQE8298SFrkFMJ1xokJvWm2DZkHvE1wLoceAC4iITGck9JDfEtwA8NlqxkBmyeBSuArQxF1H5p0FpVtLxyx4U/PDTgWdTY6WBH/DgaP4eUAjdTfs/50QFnP+6ciF1RKjp8Y11gJH037MThL5DLwYPWv4LNIkWwfOdHhf5KJ7zOSYvGkpr/oGYKXjSQ9BdnPatLhgRHcqItpvg3XDLafVAxvtQ3ZqIADqemscg/PXhOsjCqWeedJFMow3yDe1IL5rbGeBLR7pAijsI3MC3vyGHggHW1lljFOvUFTUcYwy+1Y2u/ root@ip-172-31-0-143

Keep this Terminal window open, because you'll need this output in a later step.

On your local Mac

The remaining steps will be performed on your local Mac.

Open up a new Terminal tab.

Open up ~/.ssh/known_hosts.

Delete all the contents to give you a fresh start.

Now, paste in the following onto a single line:

@cert-authority robtest.thorn.tech ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTZeLBUF8jjArKTp4s4IGL7ru12rKOItURsvnelBGQE8298SFrkFMJ1xokJvWm2DZkHvE1wLoceAC4iITGck9JDfEtwA8NlqxkBmyeBSuArQxF1H5p0FpVtLxyx4U/PDTgWdTY6WBH/DgaP4eUAjdTfs/50QFnP+6ciF1RKjp8Y11gJH037MThL5DLwYPWv4LNIkWwfOdHhf5KJ7zOSYvGkpr/oGYKXjSQ9BdnPatLhgRHcqItpvg3XDLafVAxvtQ3ZqIADqemscg/PXhOsjCqWeedJFMow3yDe1IL5rbGeBLR7pAijsI3MC3vyGHggHW1lljFOvUFTUcYwy+1Y2u/ root@ip-172-31-0-143

The text above consists of 3 pieces:

  • @cert-authority: This is a marker that indicates the following key is a certificate authority key.
  • robtest.thorn.tech: Replace this with your own domain. You can use a wildcard, such as *.example.com.
  • ssh-rsa AAAAB3NzaC1...Ywy+1Y2u/ root@ip-172-31-0-143: This is the full contents of cert_signer.pub. Make sure to include the ssh-rsa at the beginning. Of course, replace this with your own key you generated earlier.

Now, you should be able to log into the EC2 server without getting prompted.

ssh ec2-user@robtest.thorn.tech

Also see: