TT Lab
开始
学习 学习路径 课程

SSH 与文件传输

把密钥认证立起来

在 TT Lab 中继续学习

目标

创建 SSH 密钥并设置好权限,把它登记到 authorized_keys 中,并真正连接。然后确认带有 command= 限制的密钥是否真的只能执行那一条命令。

为什么重要

公钥认证失败,大多不是因为密码学,而是因为文件权限问题。如果 ~/.ssh 对组可写(group-writable),sshd 会悄悄拒绝密钥,转而询问密码——因为其他用户可以把自己的密钥写进 authorized_keys。也就是说,权限本身就是认证策略。此外,command= 限制在部署自动化中几乎是必需的。即使 CI 服务器的密钥泄露,也可以让这把密钥只能运行指定的一条命令。

这个实验环境的 127.0.0.1:2222 上运行着一个真正的 sshd。虽然在同一个 Pod 内,但从 SSH 的角度看,它是一台完整的第二台服务器。

步骤

  1. 在 /root/.ssh/id_labhub 创建一对无密码短语(passphrase)的 ed25519 密钥。
  2. 把权限设置为:/root/.ssh 为 700,/root/.ssh/id_labhub 为 600,/root/.ssh/id_labhub.pub 为 644。
  3. 把刚创建的公钥追加到 /root/.ssh/authorized_keys。文件权限必须是 600。
  4. 用 ssh-keyscan 获取 127.0.0.1 的 2222 端口的主机密钥,并登记到 /root/.ssh/known_hosts。
  5. 用该密钥连接 root@127.0.0.1:2222,在远端执行 hostname,并把结果保存到 /root/ssh/connect.txt。
  6. 在 /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。
  7. 在 /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。
  8. 创建 /root/ssh/keys.txt。其中必须包含登记在 authorized_keys 中的所有密钥的指纹列表,并且至少要有 2 行。

参考

创建密钥对

在 /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 有列出文件中密钥指纹的选项。连注释也会一起输出。