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
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
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