把密钥认证立起来
目标
创建 SSH 密钥并设置好权限,把它登记到 authorized_keys 中,并真正连接。然后确认带有 command= 限制的密钥是否真的只能执行那一条命令。
为什么重要
公钥认证失败,大多不是因为密码学,而是因为文件权限问题。如果 ~/.ssh 对组可写(group-writable),sshd 会悄悄拒绝密钥,转而询问密码——因为其他用户可以把自己的密钥写进 authorized_keys。也就是说,权限本身就是认证策略。此外,command= 限制在部署自动化中几乎是必需的。即使 CI 服务器的密钥泄露,也可以让这把密钥只能运行指定的一条命令。
这个实验环境的 127.0.0.1:2222 上运行着一个真正的 sshd。虽然在同一个 Pod 内,但从 SSH 的角度看,它是一台完整的第二台服务器。
步骤
- 在
/root/.ssh/id_labhub创建一对无密码短语(passphrase)的 ed25519 密钥。 - 把权限设置为:
/root/.ssh为 700,/root/.ssh/id_labhub为 600,/root/.ssh/id_labhub.pub为 644。 - 把刚创建的公钥追加到
/root/.ssh/authorized_keys。文件权限必须是 600。 - 用
ssh-keyscan获取127.0.0.1的 2222 端口的主机密钥,并登记到/root/.ssh/known_hosts。 - 用该密钥连接
root@127.0.0.1:2222,在远端执行hostname,并把结果保存到/root/ssh/connect.txt。 - 在
/root/.ssh/config中创建Host lab2块。其中必须包含HostName 127.0.0.1、Port 2222、User root、IdentityFile /root/.ssh/id_labhub、IdentitiesOnly yes五行。然后确认ssh lab2 hostname能够成功,并把结果保存到/root/ssh/alias.txt。 - 在
/root/.ssh/id_restricted创建第二把 ed25519 密钥,把它的公钥追加到authorized_keys,但要在该行的最前面加上restrict,command="/bin/hostname"选项。用该密钥执行ssh -i /root/.ssh/id_restricted -p 2222 root@127.0.0.1 id时,输出的必须是hostname的结果,而不是id的结果。把该输出保存到/root/ssh/restricted.txt。 - 创建
/root/ssh/keys.txt。其中必须包含登记在authorized_keys中的所有密钥的指纹列表,并且至少要有 2 行。
参考
- 用
ssh-keygen -t ed25519 -N '' -f <경로>(占位符为路径)创建无密码短语的密钥。 - 以
ssh-keyscan -p 2222 127.0.0.1 >> /root/.ssh/known_hosts的形式登记主机密钥。 - 用
ssh-keygen -lf /root/.ssh/authorized_keys可以查看文件中所有密钥的指纹。 - 常见错误 1:在第 3 步用
>覆盖,导致原有的密钥消失。务必使用>>。 - 常见错误 2:在第 7 步的选项与密钥之间加了逗号。选项列表与密钥类型之间是空格。
创建密钥对
在 /root/.ssh/id_labhub 创建一对无密码短语(passphrase)的 ed25519 密钥。
用 ssh-keygen 的 -t 指定类型,-f 指定输出路径,-N 指定密码短语。为了自动评分,请把密码短语留空。
设置权限
把权限设置为:/root/.ssh 为 700,/root/.ssh/id_labhub 为 600,/root/.ssh/id_labhub.pub 为 644。
目录和文件的推荐权限不同。只有公钥可以让其他人读取。
登记公钥
把刚创建的公钥追加到 /root/.ssh/authorized_keys。文件权限必须是 600。
authorized_keys 是每行存放一把公钥的文本文件。不要删除已有的行,请追加。
登记主机密钥
用 ssh-keyscan 获取 127.0.0.1 的 2222 端口的主机密钥,并登记到 /root/.ssh/known_hosts。
ssh-keyscan 有指定端口的选项,非标准端口在 known_hosts 中以方括号形式记录。
用密钥连接
用该密钥连接 root@127.0.0.1:2222,在远端执行 hostname,并把结果保存到 /root/ssh/connect.txt。
用 -i 指定密钥,用 -p 指定端口。把要在远端执行的命令作为参数附在后面,连接后就会立即执行该命令。
通过客户端配置创建别名
在 /root/.ssh/config 中创建 Host lab2 块。其中必须包含 HostName 127.0.0.1、Port 2222、User root、IdentityFile /root/.ssh/id_labhub、IdentitiesOnly yes 五行。然后确认 ssh lab2 hostname 能够成功,并把结果保存到 /root/ssh/alias.txt。
在 Host 块中写入 HostName、Port、User、IdentityFile、IdentitiesOnly。这样不加任何选项,只用别名就能连接。
创建限制命令的密钥
在 /root/.ssh/id_restricted 创建第二把 ed25519 密钥,把它的公钥追加到 authorized_keys,但要在该行的最前面加上 restrict,command="/bin/hostname" 选项。用该密钥执行 ssh -i /root/.ssh/id_restricted -p 2222 root@127.0.0.1 id 时,输出的必须是 hostname 的结果,而不是 id 的结果。把该输出保存到 /root/ssh/restricted.txt。
在 authorized_keys 行的最前面用逗号列出选项。用 restrict 关闭全部功能,再用 command 只允许一项。
审计已登记的密钥
创建 /root/ssh/keys.txt。其中必须包含登记在 authorized_keys 中的所有密钥的指纹列表,并且至少要有 2 行。
ssh-keygen 有列出文件中密钥指纹的选项。连注释也会一起输出。