4 个版本 (2 个破坏性)
0.3.0 | 2024 年 2 月 29 日 |
---|---|
0.2.1 | 2024 年 2 月 10 日 |
0.2.0 | 2024 年 2 月 10 日 |
0.1.0 | 2024 年 1 月 19 日 |
#3 in #primary-key
每月下载量 101 次
66KB
1K SLoC
sshd-openpgp-auth
此工具提供服务器端功能,以创建和管理作为 SSH 主机密钥信任锚点的 OpenPGP 证书。
更具体地说,sshd-openpgp-auth
透明地管理 OpenPGP 证书的生命周期以及 SSH 主机密钥作为其认证子密钥的有效性。它功能丰富的命令行界面允许导入来自 SSH 公钥文件的宿主密钥以及 known_hosts 文件格式 的字符串,延长主密钥的有效期,撤销任何子密钥,并将密钥部署到 Web Key Directory (WKD)。
作为补充客户端工具,ssh-openpgp-auth
用于验证由 sshd-openpgp-auth
创建的信任锚点和 OpenPGP 子密钥。
安装
要安装此工具,请使用 cargo
cargo install sshd-openpgp-auth
依赖项
此工具可以从系统上的现有 SSH 主机密钥添加子密钥。为此,只需访问 SSH 公钥即可。
在导入远程机器的公共 SSH 主机密钥(以 known_hosts 文件格式)时,可以直接使用 ssh-keyscan
的输出(通常是 OpenSSH 安装的一部分)。
使用 sshd-openpgp-auth
此工具不需要配置文件,并依赖于默认设置,这些设置可以在命令行和专用环境变量中覆盖。
默认情况下,SSH公钥在/etc/ssh/
中查找,OpenPGP证书存储在/var/lib/sshd-openpgp-auth/
中。因此,在默认的OpenPGP证书位置使用该工具时,应作为单独的系统用户运行!此存储库为sysusers.d和tmpfiles.d提供了contrib目录中的集成,以支持此场景。
然而,通过使用--openpgp-dir
和--fingerprint
选项来定义存储OpenPGP证书的目录和通过OpenPGP指纹识别特定的OpenPGP证书,完全可能管理其他主机的信任锚,并使用自己的用户进行此操作。
以下小节提供了对sshd-openpgp-auth
提供的各种命令的广泛概述。对于更详细的概述,请参阅命令的--help
输出。
初始化信任锚
要为主机的SSH设置开始提供基于OpenPGP的认证,需要创建一个OpenPGP证书,该证书作为信任锚。
为了演示目的,假设我们正在使用自定义的临时存储位置来存储我们的OpenPGP证书,不使用系统的SSH主机密钥(生成主机密钥需要ssh-keygen
,通常为OpenSSH的一部分)并且想要在名为example.com
的主机上工作。
export SSH_DIR="$(mktemp -d)"
export SOA_SSH_DIR="$SSH_DIR/etc/ssh/"
export LOCAL_SSH_DIR="$SOA_SSH_DIR"
export SOA_OPENPGP_DIR="$(mktemp -d)"
export LOCAL_OPENPGP_DIR="$SOA_OPENPGP_DIR"
mkdir -vp "$SOA_SSH_DIR"
ssh-keygen -A -f "$SSH_DIR"
sleep 2
sshd-openpgp-auth init "example.com"
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
添加SSH主机密钥
系统上的SSH主机密钥可以通过两种方式添加到OpenPGP证书中:本地和远程。
本地主机密钥
要添加本地SSH主机密钥,请使用add
子命令。
sshd-openpgp-auth add
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
unset SOA_SSH_DIR
远程主机密钥
假设我们正在codeberg.org,并希望使用sshd-openpgp-auth
将服务的主机SSH公钥添加到另一个主机上的信任锚中。此示例需要ssh-keyscan
。
export PREV_SOA_OPENPGP_DIR="$SOA_OPENPGP_DIR"
export SOA_OPENPGP_DIR="$(mktemp -d)"
sshd-openpgp-auth init "codeberg.org"
sshd-openpgp-auth list
set +o pipefail
ssh-keyscan -t ecdsa,ed25519,rsa codeberg.org | sshd-openpgp-auth add --known-hosts
set -o pipefail
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
export REMOTE_OPENPGP_DIR="$SOA_OPENPGP_DIR"
export SOA_OPENPGP_DIR="$PREV_SOA_OPENPGP_DIR"
添加第三方证书
客户端工具ssh-openpgp-auth
可以根据PGPKI(即信任网)验证主机的OpenPGP证书的真实性。在这种情况下,客户端工具的用户通常信任一个中央证书颁发机构(CA):另一个OpenPGP证书持有者,它为该主机的OpenPGP证书签名。
假设主机example.com
将使用用户ID为admin@central-ca.com
的OpenPGP证书进行认证。
export CA_TMPDIR="$(mktemp -d)"
# create a temporary CA key
sq key generate --userid 'SSH CA <[email protected]>' --output "$CA_TMPDIR/ca_key.tsk"
sq inspect --certifications "$CA_TMPDIR/ca_key.tsk"
# certify the host's key using the CA key
sq pki certify --output "$CA_TMPDIR/example_certification.pgp" "$CA_TMPDIR/ca_key.tsk" "$SOA_OPENPGP_DIR/"*.tsk "<[email protected]>"
sq inspect --certifications "$CA_TMPDIR/example_certification.pgp"
现在可以通过将其与主机的可转移密钥(TSK)合并来直接导入创建的证书。
sshd-openpgp-auth merge "$CA_TMPDIR/example_certification.pgp"
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
在主机的TSK中管理如上所述的第三方证书具有优点,即证书在将主机密钥导出到WKD时直接可用。
导出到Web密钥目录
《sshd-openpgp-auth》的一个优点是,它可以在现有的基于OpenPGP的生态系统中用于证书检索:WKD。
使用export
子命令,可以将证书导出到本地目录,该目录可以直接由Web服务器提供服务。
export SOA_WKD_OUTPUT_DIR="$(mktemp -d)"
sshd-openpgp-auth export "example.com"
export SOA_WKD_OUTPUT_DIR="$(mktemp -d)"
sshd-openpgp-auth export "example.com" --wkd-type "direct"
延长有效期
当使用此工具时,所有添加的子密钥都依赖于OpenPGP主密钥的有效期。
使用extend
子命令可以延长主密钥的有效期。
假设管理员想要将OpenPGP证书的有效期延长到默认值以上。
sshd-openpgp-auth extend --threshold 365 --expiry 730
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
撤销认证子密钥
有时有必要撤销一个或所有认证子密钥。这样做的原因可能是管理员想要使用更强的加密算法创建新的SSH主机密钥,弃用旧的密钥,或者在最坏的情况下替换受损的密钥。
以下小节将探讨不同的场景。
密钥已被取代
这是默认的撤销操作,用于新OpenPGP认证子密钥替换旧密钥的场景。
让我们再次想象我们是codeberg.org,并想用新的SSH主机密钥替换当前的密钥。我们将添加新创建的SSH主机密钥,然后撤销旧的密钥,同时附加一条指向新子密钥的消息。
export SOA_OPENPGP_DIR="$REMOTE_OPENPGP_DIR"
export SOA_SSH_DIR="$LOCAL_SSH_DIR"
sshd-openpgp-auth list
sshd-openpgp-auth add
sshd-openpgp-auth list
export REMOTE_SUBKEYS=( $(sshd-openpgp-auth list | grep '✅' | cut -f 2 -d ' ') )
sshd-openpgp-auth revoke --subkey-fingerprint "${REMOTE_SUBKEYS[0]}" --message "Superseded by ${REMOTE_SUBKEYS[1]}"
sshd-openpgp-auth revoke --subkey-fingerprint "${REMOTE_SUBKEYS[2]}" --message "Superseded by ${REMOTE_SUBKEYS[3]}"
sshd-openpgp-auth revoke --subkey-fingerprint "${REMOTE_SUBKEYS[4]}" --message "Superseded by ${REMOTE_SUBKEYS[5]}"
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
密钥已退役
在此示例中,假设我们只想退役单个SSH主机密钥(例如,因为我们不再支持相关的算法)。
export SOA_OPENPGP_DIR="$LOCAL_OPENPGP_DIR"
sshd-openpgp-auth list
export REMOTE_SUBKEYS=( $(sshd-openpgp-auth list | grep '✅' | cut -f 2 -d ' ') )
sshd-openpgp-auth revoke --subkey-fingerprint "${REMOTE_SUBKEYS[0]}" --reason retired --message "We stopped supporting RSA"
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
密钥已受损
让我们也来看看最坏的情况:我们的主机已被入侵,攻击者窃取了我们的SSH主机密钥,以便能够冒充我们的主机。
sshd-openpgp-auth revoke --all --reason compromised --message "This host has been compromised today!"
sshd-openpgp-auth list
sq inspect --certifications "$SOA_OPENPGP_DIR/"*.tsk
添加Keyoxide DNS证明
为了提高主机证书的可信度,还可以插入Keyoxide的真实性证明。
sshd-openpgp-auth proof dns add
上述操作将在证书中添加一个注释,表示关于证书所使用的域所有权的声明。客户端可以通过WKD或OpenPGP密钥服务器检索证书,并尝试验证此声明。
为了允许客户端验证附加注释的标识声明,必须在主机的DNS区域文件中添加特定的证明,格式如下TXT
记录
openpgp4fpr:FINGERPRINT
其中FINGERPRINT
是密钥指纹的小写十六进制表示。
几个授权密钥的示例
$ dig +short TXT metacode.biz
"openpgp4fpr:0e3bb828432962f4e33c9a74d1f809bb3f02ede9"
"openpgp4fpr:198c722a4bac336e9daaae44579d01b3abe1540e"
"openpgp4fpr:653909a2f0e37c106f5faf546c8857e0d8e8f074"
对于OpenPGP CA安装,OpenPGP CA证书的指纹也应出现在DNS区域的TXT
记录中。
更多技术细节请参阅Keyoxide DNS证明页面。
资金来源
该项目由NGI Assure资助,该基金由NLnet设立,并得到欧洲委员会Next Generation Internet计划的支持。了解更多信息请访问NLnet项目页面。
许可证
该项目根据您的选择,受以下任一许可证的约束
。
贡献
除非您明确说明,否则您提交给本仓库的任何有意包含的贡献,根据Apache-2.0许可证的定义,应以上述双重许可,且不附加任何额外条款或条件。
依赖项
~19–28MB
~383K SLoC