
TPMシールドキーを作成・管理するSSHエージェント。ハードウェア結合認証に対応し、キー生成、インポート、ラッピング、PIN保護、プロキシフォールバックをサポートします。
ssh-tpm-agent は、ssh-agent 互換のエージェントで、Trusted Platform Module (TPM) によって鍵を作成し、SSH サーバーに対する認証に使用できるようにします。
TPM シールド鍵は、Trusted Platform Module (TPM) 内部で作成され、.tpm サフィックスが付いたファイルにシールドされた秘密鍵です。これらは生成されたハードウェアにバインドされており、他のマシンに転送することはできません。
これにより、既存の PKCS11 ライブラリを ssh-agent や SSH クライアントにサイドロードする代わりに、ネイティブクライアントを利用できます。
このプロジェクトは、go-tpm-keyfiles プロジェクトを通じて実装された TPM 2.0 Key Files を使用しています。
ssh-agent。ssh-agent サーバーへのプロキシサポート。TPM を直接利用する代わりに、--swtpm または export SSH_TPM_AGENT_SWTPM=1 を使用して、swtpm によってバックアップされた ID を作成できます。これは /var/tmp/ssh-tpm-agent の下に保存されます。
swtpm はセキュリティ特性を提供しないため、テスト目的でのみ使用する必要があることに注意してください。
このプラグインをインストールする最も簡単な方法は、以下を実行することです。
go install github.com/foxboron/ssh-tpm-agent/cmd/...@latest
または、プリビルド済みバイナリ をダウンロードしてください。
# Create key
$ 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 passphrase (empty for no passphrase):
Enter same passphrase again:
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:NCMJJ2La+q5tGcngQUQvEOJP3gPH8bMP98wJOEMV564
The key's randomart image is the color of television, tuned to a dead channel.
$ cat /home/fox/.ssh/id_ecdsa.pub
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOTOsMXyjTc1wiQSKhRiNhKFsHJNLzLk2r4foXPLQYKR0tuXIBMTQuMmc7OiTgNMvIjMrcb9adgGdT3s+GkNi1g=
# Using the socket
$ ssh-tpm-agent -l /var/tmp/tpm.sock
$ export SSH_AUTH_SOCK="$(ssh-tpm-agent --print-socket)"
$ ssh [email protected]
注: ssh-tpm-agent では、コマンドラインフラグ -o または --owner-password を使用して TPM オーナーパスワードを指定できます(推奨)。または、環境変数 SSH_TPM_AGENT_OWNER_PASSWORD を使用することもできます。
日常的に TPM からキーを使用しながら、リモートの安全なストレージにキーをバックアップしたい場合に便利です。
# Create a key, or use an existing one
$ ssh-keygen -t ecdsa -f id_ecdsa
Generating public/private ecdsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_ecdsa
Your public key has been saved in id_ecdsa.pub
The key fingerprint is:
SHA256:bDn2EpX6XRX5ADXQSuTq+uUyia/eV3Z6MW+UtxjnXvU fox@framework
The key's randomart image is:
+---[ECDSA 256]---+
| .+=o..|
| o. oo.|
| o... .o|
| . + .. ..|
| S . . o|
| o * . oo=*|
| ..+.oo=+E|
| .++o...o=|
| .++++. .+ |
+----[SHA256]-----+
# Import the key
$ ssh-tpm-keygen --import id_ecdsa
Sealing an existing public/private ecdsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_ecdsa.tpm
The key fingerprint is:
SHA256:bDn2EpX6XRX5ADXQSuTq+uUyia/eV3Z6MW+UtxjnXvU
The key's randomart image is the color of television, tuned to a dead channel.
ソケットアクティベーションサービスを使用すると、システムが必要としたときに ssh-tpm-agent を起動できます。
# Using the socket
$ ssh-tpm-agent --install-user-units
Installed /home/fox/.config/systemd/user/ssh-tpm-agent.socket
Installed /home/fox/.config/systemd/user/ssh-tpm-agent.service
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 [email protected]
# Start the usual ssh-agent
$ eval $(ssh-agent)
# Create a strong RSA key
$ ssh-keygen -t rsa -b 4096 -f id_rsa -C ssh-agent
...
The key fingerprint is:
SHA256:zLSeyU/6NKHGEvyZLA866S1jGqwdwdAxRFff8Z2N1i0 ssh-agent
$ ssh-add id_rsa
Identity added: id_rsa (ssh-agent)
# Print looonnggg key
$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc[...]8TWynQ== ssh-agent
# Create key on the TPM
$ ssh-tpm-keygen -C ssh-tpm-agent
Generating a sealed public/private ecdsa key pair.
Enter file in which to save the key (/home/fox/.ssh/id_ecdsa):
Enter passphrase (empty for no passphrase):
Confirm passphrase:
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:PoQyuzOpEBLqT+xtP0dnvyBVL6UQTiQeCWN/EXIxPOo
The key's randomart image is the color of television, tuned to a dead channel.
# Start ssh-tpm-agent with a proxy socket
$ ssh-tpm-agent -A "${SSH_AUTH_SOCK}" &
$ export SSH_AUTH_SOCK="$(ssh-tpm-agent --print-socket)"
# ssh-tpm-agent is proxying the keys from ssh-agent
$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc[...]8TWynQ== ssh-agent
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNo[...]q4whro= ssh-tpm-agent
$ ssh-tpm-agent --no-load &
2023/08/12 13:40:50 Listening on /run/user/1000/ssh-tpm-agent.sock
$ export SSH_AUTH_SOCK="$(ssh-tpm-agent --print-socket)"
$ ssh-add -L
The agent has no identities.
$ ssh-tpm-add $HOME/.ssh/id_ecdsa.tpm
Identity added: /home/user/.ssh/id_ecdsa.tpm
$ ssh-add -L
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJCxqisGa9IUNh4Ik3kwihrDouxP7S5Oun2hnzTvFwktszaibJruKLJMxHqVYnNwKD9DegCNwUN1qXCI/UOwaSY= test
クライアント側で、階層の下にプライマリキーを作成します。この例では、SRK を使用したオーナー階層を使用します。
出力ファイル srk.pem は、鍵を作成するリモート側に転送する必要があります。これはクライアントプロビジョニングの一部として行うことができます。
$ tpm2_createprimary -C o -G ecc -g sha256 -c prim.ctx -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda' -f pem -o srk.pem
リモート側では、パスワードなしの p256 SSH 鍵を作成し、クライアント側の srk.pem を使用して ssh-tpm-keygen でラップします。
$ ssh-keygen -t ecdsa -b 256 -N "" -f ./ecdsa.key
# OR with openssl
$ openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out ecdsa.key
# Wrap with ssh-tpm-keygen
$ ssh-tpm-keygen --wrap-with srk.pub --wrap ecdsa.key -f wrapped_id_ecdsa
クライアント側では、wrapped_id_ecdsa を展開してロード可能な鍵にすることができます。
$ ssh-tpm-keygen --import ./wrapped_id_ecdsa.tpm -f id_ecdsa.tpm
$ ssh-tpm-add id_ecdsa.tpm
ssh-tpm-agent は、ホスト鍵を TPM 内に保存することもサポートしています。
$ sudo ssh-tpm-keygen -A
2023/09/03 17:03:08 INFO Generating new ECDSA host key
2023/09/03 17:03:08 INFO Wrote /etc/ssh/ssh_tpm_host_ecdsa_key.tpm
2023/09/03 17:03:08 INFO Generating new RSA host key
2023/09/03 17:03:15 INFO Wrote /etc/ssh/ssh_tpm_host_rsa_key.tpm
$ 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 ssh-tpm-hostkeys --install-sshd-config
Installed /etc/ssh/sshd_config.d/10-ssh-tpm-agent.conf
Restart sshd: systemd restart sshd
$ systemctl enable --now ssh-tpm-agent.socket
$ systemd 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-keyscan -t ecdsa localhost
# localhost:22 SSH-2.0-OpenSSH_9.4
localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCLDH2xMDIGb26Q3Fa/kZDuPvzLzfAH6CkNs0wlaY2AaiZT2qJkWI05lMDm+mf+wmDhhgQlkJAHmyqgzYNwqWY0=
ssh-tpm-keygen で作成した公開鍵を ssh 設定内で使用することが可能です。
以下の例では、ssh-tpm-agent を使用し、またエージェントからすべての identity が漏洩しないように公開鍵も指定しています。
Host example.com
IdentityAgent $SSH_AUTH_SOCK
Host *
IdentityAgent /run/user/1000/ssh-tpm-agent.sock
IdentityFile ~/.ssh/id_ecdsa.pub
MIT ライセンスの下でライセンスされています。LICENSE または https://opensource.org/licenses/MIT を参照してください。