SSH
Creating a Ssh Key
Linux / MacOS
Once your key is created you should find it located in ~/.ssh
using the default options it the path would be ~/.ssh/id_ed25519
for the private key and ~/.ssh/id_ed25519.pub
for the public key.
Putty
Attention:
Make sure you have putty installed for this to work.
If you do not have it installed use the package manager of your choice
[!example] Using winget to install Putty
[!example] Creating a new putty key
Extracting Keys
To use your putty key on without putty you will need to extract the keys. Keep track of where you extra the key too and the file names created, you will need this information later. Also treat these keys like you would a password, they're sensitive information that needs to be protected.
Public Key
To get your public key from your putty key you will need to extract it
Private Key
To get your private key from your putty key you will need to extract it
Convert Openssh Key to Putty Key
To convert an openssh key to putty key you will need the private key file as well as any passwords that may or may not be securing that key. This will most likely not apply to anyone unless they want to take an existing key and use in putty
TPM
WIP
Getting Started
Check to see if you have /dev/tpm0
on your system. If you do make sure you have tpm2-pkcs11 installed. This is needed to act as a smart card interface. This will allow us to generate and store the private key in the TPM. Making it way more secure than just leaving a private key in your ~/.ssh directory.
Next check the group on /dev/tpmrm0
and add that group to your user, most likely it will be tss
so do sudo usermod -a -G tss "$(whoami)"
and then relogin.
Create the Keys
tpm2_ptool init
tpm2_ptool addtoken --pid=1 --label=ssh --userpin=PASSWORDHERE --sopin=RECOVERYPASSWORDHERE
tpm2_ptool addkey --label=ssh --userpin=PASSWORD --algorithm=ecc256
Reading the Public Key
Take the output from here and add that to the authorized keys file on whatever system you need to connect to.
Using the TPM Key
You'll need to point ssh to the identiy file that is the tpm using -I /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so
. This is easier done in your ~/.ssh/config
file. To set it for everything add this at the bottom of your config
Using Your SSH Key
To use your key, simply ssh to a server. It should instantly allow you in without prompting. Putty users will have to enter their user name depending on how they have their connection configured.
If you're having problems you may need to add the keys to your ssh-agent. ssh-agent -a ~/.ssh/id_ed25519
Putty should do this for you, you may have to go into the connection settings and tell it to use the key. I believe moba works the same way.
Agent Forwarding
For MacOS you will need to do ssh-add --apple-use-keychain
to add your keys to the keychain for Agent Forwarding to work correctly
When you use agent forwarding it will allow your keys to be used on a remote system that you're connected too. You do this with the -A
flag so ssh -A user@host
however you can configure your ssh config to do this for you automatically. Make sure you place this at the END of your config
host *
says use these options on anything that matches. This is why we put it at the bottom of ~/.ssh/confg
because it works on a first match priceable. compression yes
means that it will use compression, this is helpful for low-bandwidth connections and data transfers. StrictHostKeyChecking no
says don't alert me to accept keys. Not a great idea for most things, but not something we can avoid with our current setup. ForwardAgent yes
means that it will forward the ssh-agent to the destination connection. This is the main thing we want, the other options are helpful but not required.
SSH Agent Forwarding via Sudo
Now that you're forwarding your agent and you're able to ssh into other systems from the system you're connected to, let's assume you need to become root or another user. To do this you will need to forward your shell and environment. Do do this you will do sudo -E -s
or sudo -E -s -u username
. this will allow you to forward your agent from your system, to a remote system, over sudo, and use your keys that way. The -E
flag forwards your environment and the -s
forwards your shell.
This example forwards your agent, connects to a host, then drops you into root with your agent forwarded
SSH Host Jumping
To use another host as a jumpbox you have to use the -J
flag. You can combine this with the -A
to forward your agent too.
# Use a system to connect to another system
ssh -J user@jump-box user@destination-server
# Jump from jumpbox to jumpbox2 to jumpbox3 to destination
ssh -J user@jumpbox,user@jumpbox2,user@jumpbox3 user@destination
If you're forwarding your agent and your public key is on the various servers you can jump to all of them adding the -A
flag.
Faster SSH
Getting faster ssh connections is simple and easy, you can use the ControlMaster option!
This tells ssh to use a socket to reconnect to ssh and hold it open for 600 seconds. This is really helpful if you're bouncing around to different systems and have to reconnect to them. It can cause some problems if you're opening a lot of connections at once. In practice I've only hit a problem a handful of times though and I make A LOT of connections via ssh. So YMMV. If you have problems just remove, comment out, or place it on specific connections rather than all (*
) connections
SSH Key Signing
Signing Data
Now let's take a step further! How about signing files, data, etc? You can do that with your ssh key! Why would you want to do this? You can ensure data integrity and prove that the data came from you.
So lets break this down -Y sign
is telling it that you're going to sign something, then comes the path to your private key, next is the name space, since we're signing a file we tell it -n file
.
Verifying Data
Okay, so we signed a file, but how do we verify it?
ssh-keygen -Y verify -f allowed_signers -I hugh.smalley@lexisnexisrisk.com -n file -s FILENAMEHERE.sig <FILENAMEHERE
Just like signing -Y verify
is telling it that we want to verify something. -f allow_signers
is telling it the name of the file with the information to lookup public keys. Much like the authorized_keys file lets ssh know they's keys are allowed to connect.
For example here's my keys in the allowed_signers file.
hugh.smalley@lexisnexisrisk.com sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIPEroRTKtLMu9EXxFXXNm8bzA1w/c4v7gFKeFPXmHII1AAAABHNzaDo= Yubikey 5
hugh.smalley@lexisnexisrisk.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFuAYj8uDz7o5qJzHrEohvfpX/RWBoqudHRoaD+6dR+X Macbook Pro
The first section is a comma delineated list of identifiers eg email addresses. The next section is the type of key, eg ssh-ed25519, ssh-rsa, etc. Lastly the public key.
To continue the -I
says the name of the identity to check in the allowed_signers file.-n file
is again the name space, -s
is the signature file and <FILENAMEHERE
is the file we're checking.
You can wrap this up in some functions to throw into your .bashrc,.zshrc,etc..
ssh_sign () {
ssh-keygen -Y sign -f ~/.ssh/id_ed25519 -n file "${1}"
}
ssh_verify () {
ssh-keygen -Y verify -f allowed_signers -I "${1}" -n file -s "${2}.sig" <"${2}"
}
Code Signing
Now configure git so it knows about your signing key
git config --global gpg.format ssh
git config --global user.signingkey "${HOME}/.ssh/id_ed25519.pub"
Now when you commit on git add a -S to sign it!
If you want to skip adding the S then set:
Now you can sign commits and other data with ssh!
SSH Certificates
WIP
A SSH CA is a certificate authority that can issue and sign SSH certificates for authentication. SSH certificates are similar to SSH keys, but they have additional features such as expiration dates and identity information. To create a SSH CA, you need to generate a SSH key pair using the ssh-keygen command and specify a file name and a comment for the CA key¹². For example:
$ ssh-keygen -t rsa -b 4096 -f host_ca -C host_ca
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in host_ca.
Your public key has been saved in host_ca.pub.
This will create a private key file host_ca and a public key file host_ca.pub. The public key file can be used to verify certificates issued by the CA, while the private key file should be kept secure and only used by the CA to sign certificates¹².
Source: Conversation with Bing, 5/3/2023
(1) How to configure SSH Certificate-Based Authentication - goteleport.com. https://goteleport.com/blog/how-to-configure-ssh-certificate-based-authentication/.
(2) 14.3.3. Creating SSH CA Certificate Signing Keys. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-creating_ssh_ca_certificate_signing-keys.
(3) GitHub - cloudtools/ssh-ca: Management utilities to support a …. https://github.com/cloudtools/ssh-ca.
(4) Using a CA with SSH - lorier.net. https://www.lorier.net/docs/ssh-ca.html.
(5) How to configure and setup SSH certificates for SSH authentication. https://dev.to/gvelrajan/how-to-configure-and-setup-ssh-certificates-for-ssh-authentication-b52.
To use the CA to sign certificates, you need to have the public keys of the hosts or users that you want to issue certificates for. Then you can use the ssh-keygen command with the -s option to specify the CA private key and the -I option to specify a certificate identity²³. For example, to sign a user's public key and create a user certificate, you can use a command like this:
This will create a file named id_rsa-cert.pub that contains the user certificate. The certificate identity can be any alphanumeric value, but it is recommended to use the user name or host name for clarity²³. To sign a host's public key and create a host certificate, you need to add the -h option²³. For example:
This will create a file named ssh_host_rsa_key-cert.pub that contains the host certificate.
Source: Conversation with Bing, 5/3/2023
(1) 14.3.3. Creating SSH CA Certificate Signing Keys Red Hat Enterprise …. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-creating_ssh_ca_certificate_signing-keys.
(2) How to configure and setup SSH certificates for SSH authentication. https://dev.to/gvelrajan/how-to-configure-and-setup-ssh-certificates-for-ssh-authentication-b52.
(3) SSH Best Practices using Certificates, 2FA and Bastions. https://goteleport.com/blog/how-to-ssh-properly/.
To configure SSH to trust the CA, you need to copy the CA's public key to the hosts or users that you want to trust the certificates issued by the CA. For user authentication, you need to create a file named /etc/ssh/trusted_user_ca_keys on the SSH server and paste the CA's public key in it¹³⁴. For example:
This will tell the SSH server to trust any user certificate signed by the CA. For host authentication, you need to create or update a file named /etc/ssh/ssh_known_hosts on the SSH client and paste the CA's public key in it with a @cert-authority prefix⁵. For example:
This will tell the SSH client to trust any host certificate signed by the CA for any host under the example.com domain.
Source: Conversation with Bing, 5/3/2023
(1) Configuring your OpenSSH servers to trust your SSH CA hosted by. https://docs.venafi.com/Docs/22.4/TopNav/Content/SSH/SSHCertificates/t-ssh-certificate-configure-openssh-trust-venafi-ca.php.
(2) How to configure SSH Certificate-Based Authentication - goteleport.com. https://goteleport.com/blog/how-to-configure-ssh-certificate-based-authentication/.
(3) How to configure and visualize an SSH CA · GitHub - Gist. https://gist.github.com/seanw2020/924c50e4c8428ad2d030db99cc819e20.
(4) Scalable and secure access with SSH - Engineering at Meta. https://engineering.fb.com/2016/09/12/security/scalable-and-secure-access-with-ssh/.
(5) How to configure and setup SSH certificates for SSH authentication. https://dev.to/gvelrajan/how-to-configure-and-setup-ssh-certificates-for-ssh-authentication-b52.
To revoke a certificate issued by the CA, you need to add the certificate to a file named /etc/ssh/revoked_keys on the SSH server and specify the file name in the sshd_config file as follows:
This will tell the SSH server to reject any authentication attempt using the revoked certificate¹. To test if a certificate has been revoked, you can use the ssh-keygen command with the -Qf option to query the revocation list for the presence of the certificate¹. For example:
This will return either id_rsa-cert.pub: revoked or id_rsa-cert.pub: valid depending on the status of the certificate. Alternatively, you can revoke a CA certificate by changing the cert-authority directive to revoke in the known_hosts file¹. For example:
This will tell the SSH client to reject any host certificate signed by the revoked CA for any host under the example.com domain.
Source: Conversation with Bing, 5/3/2023
(1) 14.3.8. Revoking an SSH CA Certificate - Red Hat Customer Portal. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-revoking_an_ssh_ca_certificate.
(2) How to Revoke SSH Certificates - CybersecurityHQ.io. https://www.cybersecurityhq.io/blog/how-to-revoke-ssh-certificates.
(3) Hashicorp Vault revoke SSH signed certificate - Stack Overflow. https://stackoverflow.com/questions/68812537/hashicorp-vault-revoke-ssh-signed-certificate.
You can specify additional options for the certificates when you sign them using the ssh-keygen command. Some of the options are:
- -V to specify the validity interval of the certificate. For example, -V +1h means the certificate is valid for one hour from now²⁴.
- -n to specify the principals (user names or host names) that are allowed to use the certificate. For example, -n darren means only the user named darren can use the certificate²⁴.
- -z to specify a serial number for the certificate. For example, -z 1 means the certificate has a serial number of 1²⁴.
- -O to specify one or more certificate options that can restrict or permit certain features. For example, -O no-agent-forwarding means the certificate cannot be used to forward an authentication agent²³.
For example, to sign a user's public key and create a user certificate that is valid for one hour, allows only the user named darren to use it, has a serial number of 1, and does not allow agent forwarding, you can use a command like this:
This will create a file named id_rsa-cert.pub that contains the user certificate with the specified options⁴.
Source: Conversation with Bing, 5/3/2023
(1) How to configure and setup SSH certificates for SSH authentication. https://dev.to/gvelrajan/how-to-configure-and-setup-ssh-certificates-for-ssh-authentication-b52.
(2) How to configure SSH Certificates And User Principals - CottonLinux. https://cottonlinux.com/ssh-certificates/.
(3) 14.3.5. Creating SSH Certificates - Red Hat Customer Portal. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-signing_ssh_certificates.
(4) How do I specify the key exchange method in OpenSSH?. https://superuser.com/questions/744816/how-do-i-specify-the-key-exchange-method-in-openssh.
(5) Get self signed certificate of remote server - Stack Overflow. https://stackoverflow.com/questions/9072376/configure-git-to-accept-a-particular-self-signed-server-certificate-for-a-partic.
(6) How to configure SSH Certificate-Based Authentication - goteleport.com. https://goteleport.com/blog/how-to-configure-ssh-certificate-based-authentication/.
Certificate Authority
WIP
Host Certificates
WIP
Client Certificates
WIP
Congrats
you did it!
See Also
Github has a guide for creating, using, and adding ssh keys. I suggest you read that if you want to know more or add your keys to github.
Ledger's guide to TPM2 on Debian is really good and provided a lot of information on how to do TPM ssh
Pandasauce guide on smart cards