Last active
February 19, 2024 03:15
Revisions
-
Sean Wingert revised this gist
Nov 14, 2019 . 1 changed file with 1 addition and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,5 @@ # How to configure an SSH CA, with visuals  ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). -
Sean Wingert revised this gist
Sep 27, 2019 . 1 changed file with 36 additions and 36 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,11 +26,11 @@ sudo ssh-keygen -t rsa -b 4096 -C "SSH CA for users created September 25, 2019 b sudo chmod 400 /usr/local/sshca/{hosts-ca,users-ca} # only allow the owner to read these sudo chmod 444 /usr/local/sshca/{users-ca.pub,hosts-ca.pub} # Upload the users CA to the server1. This overwrites the destination! scp /usr/local/sshca/users-ca.pub root@server1:/etc/ssh/ # Copy the hosts CA's pub key. This overwrites the destination! scp /usr/local/sshca/hosts-ca.pub root@client1:/etc/ssh/ ``` ### SSH Server (sshd) @@ -40,8 +40,8 @@ Configure the ssh server to trust the users CA, and thus any certs it signs. We' # Log into the CA computer. ssh you@ca # Update server1's sshd_config ssh root@server1 bash <<\EOF comment="# Added by configuration-manager@foo.com" keyword_pair="TrustedUserCAKeys /etc/ssh/users-ca.pub" path="/etc/ssh/sshd_config" @@ -59,25 +59,24 @@ EOF ``` ### SSH Client (ssh) Configure the ssh client to trust the hosts CA, and thus any certs it signs. We'll use root to modify /etc/ssh. ```bash # Log into the CA computer. ssh you@ca # Create or update client1's /etc/ssh/ssh_known_hosts. By default, it doesn't exist. ssh root@client1 bash <<\OUTER # set permissions chmod 774 /etc/ssh/ssh_known_hosts chmod 774 /etc/ssh/hosts-ca.pub # Allow client1 to connect to servers from these domains tee -a /etc/ssh/ssh_known_hosts <<INNER # Added by configuration-manager@foo.com @cert-authority \*.domain1.com,\*.domain2.com $(cat /etc/ssh/hosts-ca.pub) INNER OUTER ``` ### Sign an ssh server's public keys using hosts-ca @@ -86,20 +85,20 @@ OUTER ssh you@ca # For clarity, create a directory to hold the ssh server's public keys mkdir -p /usr/local/sshca/hosts/server1 # Download the public certs # Alternatively, ssh-keyscan works but would allow man-in-the-middle. scp root@server1:/etc/ssh/ssh_host_\{rsa_key.pub,dsa_key.pub,ecdsa_key.pub,ed25519_key.pub\} /usr/local/sshca/hosts/server1/ # Sign all of server1's public keys, thus creating certificates with extension .pub sudo ssh-keygen -s /usr/local/sshca/hosts-ca -I "i am server1" -h -n server1,server1.foo.com,192.168.0.1 -V +56w5d /usr/local/sshca/hosts/server1/ssh_host_*.pub # Copy all server1's newly signed certs back to server1 scp /usr/local/sshca/hosts/server1/ssh_host_*-cert.pub root@server1:/etc/ssh/ # Add the signed certs to sshd_config ssh root@server1 bash <<\EOF comment="# Added by configuration-manager@foo.com" path="/etc/ssh/sshd_config" @@ -129,33 +128,33 @@ ssh you@ca mkdir -p /usr/local/sshca/users/user1 # Download the user's public cert scp user1@client1:/home/user1/.ssh/id_rsa.pub /usr/local/sshca/users/user1/ # Sign the user's public key, thus creating a certificate named id_rsa-cert.pub # Note: the user mentioned in the -n option must exist on the ssh server and allow ssh connections sudo ssh-keygen -s /usr/local/sshca/users-ca -I "user1@client1" -n "user1" -V +52w \ /usr/local/sshca/users/user1/id_rsa.pub # Optionally investigate the cert's details: ssh-keygen -Lf /usr/local/sshca/users/user1/id_rsa-cert.pub # Copy the signed certificate back to the user's .ssh directory scp /usr/local/sshca/users/user1/id_rsa-cert.pub user1@client1:/home/user1/.ssh/ # Test from the ssh client. ssh user1@client1 ssh -vvv server1 # You should NOT be prompted. Troubleshoot otherwise. Use ssh-agent for any priv key passwords. ``` ## Single-purpose Keys This allows you to create a certificate whose public key can only perform one task, like running /usr/local/scripts/myscript.sh. The intention here is for `user1` to run `sudo /usr/local/bin/myscript.sh`. ```bash # Log into client1 ssh user1@client1 # Create a new keypair ssh-keygen -t rsa -b 4096 -C "user1@client1: single purpose key: sudo myscript.sh" -f /home/user1/.ssh/id_rsa-myscript # Try this key when connecting tee -a /home/user1/.ssh/config <<\EOF @@ -167,29 +166,30 @@ EOF chmod 700 /home/user1/.ssh/config # Log into CA ssh user1@client1 # Set up a directory mkdir -p /usr/local/sshca/users/user1 # Download the pub key scp user1@client1:/home/user1/.ssh/id_rsa-myscript.pub /usr/local/sshca/users/user1/ # Sign it # NOTES: permit-pty helps troubleshooting (you can see error output) and avoids "PTY allocation request failed on channel 0". # : For details, see ForceCommand and permit-pty in man sshd_config # : -n means approved (for login) principals. They are expected to exist on server1 (or configure AuthorizedPrincipalsFile) sudo ssh-keygen -s /usr/local/sshca/users-ca -I "signed: user1@client1: single purpose key: myscript.sh" \ -n "user1,user1@foo.com" -V +52w -O clear -O permit-pty -O force-command="/usr/local/bin/myscript.sh" \ /usr/local/sshca/users/user1/id_rsa-myscript.pub # Optionally inspect it ssh-keygen -Lf /usr/local/sshca/users/user1/id_rsa-myscript-cert.pub # Upload to client1 scp /usr/local/sshca/users/user1/id_rsa-myscript-cert.pub user1@client1:/home/user1/.ssh/ # Test it ssh user1@client1 ssh server1 ``` -
Sean Wingert revised this gist
Sep 26, 2019 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ # How to configure an SSH CA, with visuals   ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). -
Sean Wingert revised this gist
Sep 26, 2019 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,6 @@ # How to configure an SSH CA, with visuals [image1](https://gist.github.com/seanw2020/5035ca7036ac899dd3142cb004aefb34/raw/f68bf11491d563b6bfaaeb60d13e4501eb1d0f6d/configure-CAs.png) [image1](https://gist.github.com/seanw2020/5035ca7036ac899dd3142cb004aefb34/raw/f68bf11491d563b6bfaaeb60d13e4501eb1d0f6d/sign-and-use-certs.png) ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). -
Sean Wingert revised this gist
Sep 26, 2019 . 2 changed files with 0 additions and 0 deletions.There are no files selected for viewing
Binary file not shown.Binary file not shown. -
Sean Wingert revised this gist
Sep 26, 2019 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,4 @@ # How to configure an SSH CA, with visuals ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). -
Sean Wingert revised this gist
Sep 26, 2019 . 2 changed files with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changesFile renamed without changes -
Sean Wingert revised this gist
Sep 26, 2019 . 3 changed files with 2 additions and 1 deletion.There are no files selected for viewing
File renamed without changesFile renamed without changesThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,6 @@ # How to configure an SSH CA, with visuals   ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). -
Sean Wingert revised this gist
Sep 26, 2019 . 3 changed files with 3 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,6 @@ # How to configure an SSH CA, with visuals  ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). -
seanw2020 created this gist
Sep 26, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,191 @@ ## SSH CA For details, see "Mastering SSH", Second Edition, Chapter 14: Certificate Authorities. Also see 'man ssh-keygen': "ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication. Certificates consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are signed by a Certification Authority (CA) key. Clients or servers may then trust only the CA key and verify its signature on a certificate rather than trusting many user/host keys. Note that OpenSSH certificates are a different, and much simpler, format to the X.509 certificates used in ssl(8). ### Create two CAs Choose a computer to act as the CA. We'll call this the CA computer (not CA host, since "host" is overloaded here). In this example, only root can sign keys, thus sudo. ```bash # Log into the CA computer. ssh you@ca # Prepare sudo mkdir -p /usr/local/sshca/{users,hosts} sudo chmod 1771 /usr/local/sshca # sticky bit (first 1) prevents non-owners from renaming files. # 11 allows cat of .pub files sudo chmod 774 /usr/local/sshca/{users,hosts} sudo chgrp -R $(id -g -n) /usr/local/sshca # recursively change group to your group # Create two CAs: 1 to sign hosts and 1 to sign users. These are openssh, not openssl, CAs sudo ssh-keygen -t rsa -b 4096 -C "SSH CA for hosts created September 25, 2019 by John Smith" -f /usr/local/sshca/hosts-ca sudo ssh-keygen -t rsa -b 4096 -C "SSH CA for users created September 25, 2019 by John Smith" -f /usr/local/sshca/users-ca # Protect them sudo chmod 400 /usr/local/sshca/{hosts-ca,users-ca} # only allow the owner to read these sudo chmod 444 /usr/local/sshca/{users-ca.pub,hosts-ca.pub} # Upload the users CA to the server. This overwrites the destination! scp -P 22 /usr/local/sshca/users-ca.pub root@server:/etc/ssh/ # Copy the hosts CA's pub key. This overwrites the destination! scp -P 22 /usr/local/sshca/hosts-ca.pub root@client:/etc/ssh/ ``` ### SSH Server (sshd) Configure the ssh server to trust the users CA, and thus any certs it signs. We'll use root to modify /etc/ssh. ```bash # Log into the CA computer. ssh you@ca # Update server's sshd_config ssh -p 22 root@server bash <<\EOF comment="# Added by configuration-manager@foo.com" keyword_pair="TrustedUserCAKeys /etc/ssh/users-ca.pub" path="/etc/ssh/sshd_config" # If not present in sshd_config, append the keyword pair grep -q -F "${keyword_pair}" "${path}" || printf "\n%s\n%s" "${comment}" "${keyword_pair}" >> "${path}" # Make readable chmod 444 "${path}" # Restart sshd. This does not disconnect existing connections. sudo /etc/init.d/ssh restart # if you have upstart or system v sudo systemd restart sshd # if you have systemd EOF ``` ### SSH Client (ssh) Configure the ssh client to trust the hosts CA, and thus any certs it signs. We'll use root to modify /etc/ssh. ```bash # Log into the CA computer. ssh you@ca # Create or update the client's /etc/ssh/ssh_known_hosts. By default, it doesn't exist. ssh root@client -p 22 bash <<\OUTER # set permissions chmod 774 /etc/ssh/ssh_known_hosts chmod 774 /etc/ssh/hosts-ca.pub # Allow the client to connect to servers from these domains tee -a /etc/ssh/ssh_known_hosts <<INNER # Added by configuration-manager@foo.com @cert-authority \*.domain1.com,\*.domain2.com $(cat /etc/ssh/hosts-ca.pub) INNER OUTER ``` ### Sign an ssh server's public keys using hosts-ca ```bash # Log into the CA computer. ssh you@ca # For clarity, create a directory to hold the ssh server's public keys mkdir -p /usr/local/sshca/hosts/server # Download the public certs # Alternatively, ssh-keyscan works but would allow man-in-the-middle. scp -P 22 root@server:/etc/ssh/ssh_host_\{rsa_key.pub,dsa_key.pub,ecdsa_key.pub,ed25519_key.pub\} /usr/local/sshca/hosts/server/ # Sign all of server's public keys, thus creating certificates with extension .pub sudo ssh-keygen -s /usr/local/sshca/hosts-ca -I "i am server" -h -n server,server.foo.com,192.168.0.1 -V +56w5d /usr/local/sshca/hosts/server/ssh_host_*.pub # Copy all server's newly signed certs back to server scp -P 22 /usr/local/sshca/hosts/server/ssh_host_*-cert.pub root@server:/etc/ssh/ # Add the signed certs to sshd_config ssh root@server -p 22 bash <<\EOF comment="# Added by configuration-manager@foo.com" path="/etc/ssh/sshd_config" # Only add the keyword pair if it's not already there for part in rsa dsa ecdsa ed25519; do pubpath="/etc/ssh/ssh_host_${part}_key-cert.pub" keyword_pair="HostCertificate ${pubpath}" if [ -f "${pubpath}" ]; then grep -q -F "${keyword_pair}" "${path}" || printf "\n%s\n%s" "${comment}" "${keyword_pair}" >> "${path}" fi done # Restart sshd. This does not disconnect existing connections. sudo /etc/init.d/ssh restart # if you have upstart or system v sudo systemd restart sshd # if you have systemd EOF ``` ### Sign an ssh client's public key using users-ca This assumes the user already has a keypair: id_rsa and id_rsa.pub. ```bash # Log into the CA computer. ssh you@ca # For clarity, create a directory to hold the ssh user's public keys mkdir -p /usr/local/sshca/users/user1 # Download the user's public cert scp -P 22 user1@client:/home/user1/.ssh/id_rsa.pub /usr/local/sshca/users/user1/ # Sign the user's public key, thus creating a certificate named id_rsa-cert.pub # Note: the user mentioned in the -n option must exist on the ssh server and allow logins sudo ssh-keygen -s /usr/local/sshca/users-ca -I "user1@foo.com" -n "user1" -V +52w \ /usr/local/sshca/users/user1/id_rsa.pub # Optionally investigate the cert's details: ssh-keygen -Lf /usr/local/sshca/users/user1/id_rsa-cert.pub # Copy the signed certificate back to the user's .ssh directory scp -P 22 /usr/local/sshca/users/user1/id_rsa-cert.pub user1@client:/home/user1/.ssh/ # Test from the ssh client. ssh user1@client ssh -vvv server # You should NOT be prompted. Troubleshoot otherwise. Use ssh-agent for any priv key passwords. ``` ## Single-purpose Keys This allows you to create a certificate whose public key can only perform one task, like running /usr/local/scripts/myscript.sh. The intention here is for `user1` to run `sudo /usr/local/bin/myscript.sh`. ```bash # Log into the client ssh user1@client # Create a new keypair ssh-keygen -t rsa -b 4096 -C "user1@foo.com: single purpose key: sudo myscript.sh" -f /home/user1/.ssh/id_rsa-myscript # Try this key when connecting tee -a /home/user1/.ssh/config <<\EOF # Added by configuration-manager@foo.com" IdentityFile ~/.ssh/id_rsa-myscript EOF # Set required permissions. Details in man ssh_config: chmod 700 /home/user1/.ssh/config # Log into CA ssh user1@client # Set up a directory mkdir -p /usr/local/sshca/users/user1 # Download the pub key scp -P 22 user1@client:/home/user1/.ssh/id_rsa-myscript.pub /usr/local/sshca/users/user1/ # Sign it # NOTE: permit-pty helps troubleshooting (you can see error output) and avoids "PTY allocation request failed on channel 0". # NOTE: For details, see ForceCommand and permit-pty in man sshd_config sudo ssh-keygen -s /usr/local/sshca/users-ca -I "signed: user@foo.com: single purpose key: myscript.sh" \ -n "user1" -V +52w -O clear -O permit-pty -O force-command="/usr/local/bin/myscript.sh" \ /usr/local/sshca/users/user1/id_rsa-myscript.pub # Optionally inspect it ssh-keygen -Lf /usr/local/sshca/users/user1/id_rsa-myscript-cert.pub # Upload to client scp -P 22 /usr/local/sshca/users/user1/id_rsa-myscript-cert.pub user1@client:/home/user1/.ssh/ # Test it ssh user1@client ssh server ```