惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Security @ Cisco Blogs
小众软件
小众软件
D
Docker
博客园_首页
A
About on SuperTechFans
P
Privacy International News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
A
Arctic Wolf
Spread Privacy
Spread Privacy
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Latest news
Latest news
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
大猫的无限游戏
大猫的无限游戏
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
V2EX - 技术
V2EX - 技术
SecWiki News
SecWiki News
U
Unit 42
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
S
Security Affairs
Y
Y Combinator Blog
aimingoo的专栏
aimingoo的专栏
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
T
Tenable Blog
W
WeLiveSecurity
Cloudbric
Cloudbric
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
Google Developers Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
Netflix TechBlog - Medium
F
Full Disclosure
N
News and Events Feed by Topic
D
DataBreaches.Net
P
Proofpoint News Feed
B
Blog RSS Feed
B
Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org

Morten Linderud

ACME device attestation, smallstep and pkcs11: attezt Personal infrastructure setup 2026 Self-hosting DNS for no fun, but a little profit! Easter hack: terraform-provider-openwrt SSH CA with device and identity attestation: ssh-tpm-ca-authority NixOS is not reproducible Stream to chromecast with resolved, vlc and bash Store age identities inside the TPM: age-plugin-tpm Golang crypto/ecdh and the TPM My FOSS work update coredumpctl, delve and debug packages for Go Monitoring the kernel.org Transparency Log for a year Streaming the Steam Deck to OBS mkinitcpio v31 and UEFI stubs FOSS Activities in April 2021 FOSS Activities in March 2021 Simplifying and securing the boot process FOSS Activities in February 2021 FOSS Activities in January 2021 FOSS Activities in December 2020 Kubernetes in Arch Linux FOSS Activities in November 2020 PAM Bypass: when null(is not)ok FOSS Activities in October 2020 Improving the Secure Boot user experience Packaging LXD for Arch Linux Reproducible Arch Linux Packages Mailpile, sendmail and procmail The State of Hy Morten Linderud
Store ssh keys inside the TPM: ssh-tpm-agent
Morten Linderud · 2023-10-05 · via Morten Linderud

After writing age-plugin-tpm a friend of mine at the hackerspace was super excited to finally have easy file encryption with TPM sealed keys, all without having to rely on gnupg. “This is great!” he said.

“I wish I could have my SSH keys sealed in a TPM just as easily”.

We should have left it at that.

I shouldn’t have replied with a random assortment of facts like “I know google/go-tpm now”, or “but Go has a ssh-agent protocol implementation” followed-up with “Filippo has already implemented yubikey-agent, it can’t be that hard”. So I wound up writing a new ssh agent.

https://github.com/Foxboron/ssh-tpm-agent

Client Keys

The usual way people seal SSH keys with the TPM is with the PKCS #111 support in openssh, which is… not great? From what I can tell based off on a blog post you will largely encounter a bunch of commands that only really makes sense if you are familiar with TPMs, which is a poor basis for useful security tools.

TPM keys allows us to prevent SSH keys being stolen or brute forced and strongly tie them to the client. This is useful for enterprise settings where you want to provision a known key to the hardware.

Clearly we can do better.

λ ~ » go install github.com/foxboron/ssh-tpm-agent/cmd/...@latest
go: downloading github.com/foxboron/ssh-tpm-agent v0.1.0

λ ~ » ssh-tpm-keygen
Generating a sealed public/private ecdsa key pair.
Enter file in which to save the key (/home/fox/.ssh/id_ecdsa):
Enter pin (empty for no pin):
Confirm pin:
Your identification has been saved in /home/fox/.ssh/id_ecdsa.tpm
Your public key has been saved in /home/fox/.ssh/id_ecdsa.pub
The key fingerprint is:
SHA256:q2DERbkPtV4ZLj4/QGgxpzC6TZtScUw/cXzO8xsLhDw
The key's randomart image is the color of television, tuned to a dead channel.

Done!

Now we just need an agent that will serve our key, this is provided by the ssh-tpm-agent2 binary.

λ ~ » ssh-tpm-agent --install-user-units
Installed /home/fox/.config/systemd/user/ssh-tpm-agent.service
Installed /home/fox/.config/systemd/user/ssh-tpm-agent.socket
Enable with: systemctl --user enable --now ssh-tpm-agent.socket

λ ~ » systemctl --user enable --now ssh-tpm-agent.socket
λ ~ » export SSH_AUTH_SOCK="$(ssh-tpm-agent --print-socket)"
λ ~ » ssh-add -L
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIwh5H2ICVRI1dt4PdusX2E2lRErFyNXFBsWPRCIR9isktm05s43E4uBrpXgQB4+G/F348Xi2hSeJQt3E+vmLTU= fox@framework

Lets see if it works!

λ ~ » sudo systemctl start sshd
λ ~ » cat .ssh/id_ecdsa.pub > .ssh/authorized_keys
λ ~ » ssh localhost
Last login: Mon Oct  2 20:45:06 2023 from ::1
λ ~ »

It should be noted that only RSA 2048 and ECDSA P256 keys are supported. Depending on your needs this might not be ideal, however the TPM spec doesn’t give us other key types to implement.

The goal of this tooling is to be fairly simple. It implements it’s own ssh-tpm-keygen, ssh-tpm-agent and ssh-tpm-add. The intention is to closely mirror the existing openssh tools and refrain from reinventing the wheel when it comes to the basic usage.

However, it does implement some quality of life improvements.

ssh-tpm-agent is going to scan $HOME/.ssh for TPM sealed keys (.tpm suffixed files with the TPM PRIVATE KEY PEM block). If this feature is not something you would enjoy, you can use your ssh_config to define the ssh-tpm-agent socket as the IdentityAgent and pass the public key as the IdentityFile. openssh won’t recognize these weird new .tpm keys, however the public keys are perfectly valid SSH keys.

Host localhost
    IdentityAgent /run/user/1000/ssh-tpm-agent.sock
    IdentityFile ~/.ssh/id_ecdsa.pub

You can also use ssh-tpm-agent as an ssh agent proxier and collect all your ssh-agents through one socket. In this example we will point the agent towards our GnuPG ssh agent, which has a valid SSH key. Any keys not found in our ssh-tpm-agent will be proxied to the next agent until we find a matching key.

λ ~ » ssh-tpm-agent -A "/run/user/9001/gnupg/d.9mnncqwudgr47xbf97yfancp/S.gpg-agent.ssh"
λ ~ » export SSH_AUTH_SOCK="$(ssh-tpm-agent --print-socket)"
λ ~ » ssh-add -L
ssh-rsa d2h5IGFyZSB5b3UgbG9va2luZyBhdCBteSBSU0Ega2V5Cg== cardno:7 800 346
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIwh5H2ICVRI1dt4PdusX2E2lRErFyNXFBsWPRCIR9isktm05s43E4uBrpXgQB4+G/F348Xi2hSeJQt3E+vmLTU= fox@framework

Host Keys

Someone on some forum commented it would be cool if ssh-keysign could be used with ssh-tpm-agent. ssh-keysign is what sshd uses to sign authentication requests with host keys, and at some point I learned that ssh actually defer private key look ups to the configured Agent if it encounters a public key.

That means we just need to specify HostKeyAgent and HostKey entries for the two supported key types in ssh-tpm-agent.

λ ~ » cat /etc/ssh/sshd_config.d/10-ssh-tpm-agent.conf
# This enables TPM sealed host keys

HostKeyAgent /var/tmp/ssh-tpm-agent.sock
HostKey /etc/ssh/ssh_tpm_host_ecdsa_key.pub
HostKey /etc/ssh/ssh_tpm_host_rsa_key.pub

There is also a ssh-tpm-hostkeys binary available to show the current host keys on the host system, and install user units. Please note this probably needs to be packaged correctly as it expects binaries under /usr/bin and go install does not actually do that.

λ ~ » sudo ssh-tpm-hostkeys --install-system-units
Installed /usr/lib/systemd/system/ssh-tpm-agent.service
Installed /usr/lib/systemd/system/ssh-tpm-agent.socket
Installed /usr/lib/systemd/system/ssh-tpm-genkeys.service
Enable with: systemctl enable --now ssh-tpm-agent.socket

λ ~ » sudo systemctl enable --now ssh-tpm-agent.socket
λ ~ » sudo systemctl restart sshd

λ ~ » sudo ssh-tpm-hostkeys
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCLDH2xMDIGb26Q3Fa/kZDuPvzLzfAH6CkNs0wlaY2AaiZT2qJkWI05lMDm+mf+wmDhhgQlkJAHmyqgzYNwqWY0= root@framework
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAoMPsv5tEpTDFw34ltkF45dTHAPl4aLu6HigBkNnIzsuWqJxhjN6JK3vaV3eXBzy8/UJxo/R0Ml9/DRzFK8cccdIRT1KQtg8xIikRReZ0usdeqTC+wLpW/KQqgBLZ1PphRINxABWReqlnbtPVBfj6wKlCVNLEuTfzi1oAMj3KXOBDcTTB2UBLcwvTFg6YnbTjrpxY83Y+3QIZNPwYqd7r6k+e/ncUl4zgCvvxhoojGxEM3pjQIaZ0Him0yT6OGmCGFa7XIRKxwBSv9HtyHf5psgI+X5A2NV2JW2xeLhV2K1+UXmKW4aXjBWKSO08lPSWZ6/5jQTGN1Jg3fLQKSe7f root@framework

ssh-tpm-keygen -A will also generated host keys into /etc/ssh, which is similar to what ssh-keygen currently supports as well.

There is a slight issue where sshd will use rsa-sha2-256 or rsa-sha2-512 when it feels like it. Currently only rsa-sha2-256 is supported as one TPM key can only support one hashing algorithm, ssh-tpm-agent is currently not downgrading your crypto from sha512 to sha256.

Amazingly this just works. Now we can strongly tie TPM sealed keys to the host it self. Either by provisioning ssh keys on the client, or host keys. This makes a lot of sense as these keys can not be stolen from the host itself and prevents re-use attacks.

I have also been wondering if there is a way to make some extensions to the login protocol which would allow ssh host attestation towards clients. This would be be useful for cases where you are remote unlocking a host and would like some assurances from the host itself before typing a sensitive password.

Hopefully this project is useful for more people! There is some release candidates published and I intend to fix a package for Arch Linux soon’ish, there is also a Nix package in the works.

Now, I have been wondering if I can hook up go-tpm with uhid

Back to posts