SSH 公钥认证不仅提供无密码登录的便利,还支持细粒度的访问控制。通过 authorized_keys 中的选项,可以限制持有该公钥的用户能够执行的操 作——比如禁止端口转发、限制允许执行的命令、甚至限定登录来源 IP。这些选项是 SSH 服务器安全加固的重要手段。
authorized_keys 基础回顾#
在深入限制选项之前,先回顾 authorized_keys 文件的基本格式:
1
|
[options] ssh-rsa AAAAB3NzaC1... user@hostname
|
options 部分是可选的,多个选项用逗号分隔。这一部分就是我们控制公钥权限的入口。
常用限制选项详解#
1. command:强制执行特定命令#
command 选项强制使用该公钥登录时只能执行指定的命令,忽略客户端发送的任何命令。
1
2
|
# 限制只能执行特定命令
command="/usr/bin/git-shell-wrapper" ssh-ed25519 AAAA... user@workstation
|
实际效果:
1
2
|
$ ssh git@server
# 强制执行 /usr/bin/git-shell-wrapper,忽略用户输入的其他命令
|
这在提供 git 访问权限时特别有用,确保用户只能运行 git 相关操作,无法获得完整 shell。
2. from:限制登录来源 IP#
from 选项限定公钥只能从特定主机或网络登录。
1
2
3
4
5
6
7
8
9
10
11
|
# 只允许从特定 IP 登录
from="192.168.1.100" ssh-ed25519 AAAA... user@workstation
# 允许从特定网段登录(支持通配符)
from="192.168.1.*" ssh-ed25519 AAAA... user@workstation
# 允许从多个来源
from="192.168.1.100,10.0.0.50" ssh-ed25519 AAAA... user@workstation
# 允许从特定域名(需反向解析)
from="*.example.com" ssh-ed25519 AAAA... user@workstation
|
验证来源限制:
1
2
3
|
# 从非允许 IP 尝试登录会被拒绝
$ ssh -i ~/.ssh/id_ed25519 user@server
Permission denied (publickey).
|
3. no-pty:禁止分配伪终端#
no-pty 防止为该公钥分配交互式终端,适合只执行自动化任务的场景。
1
2
|
# 禁止分配终端
no-pty ssh-ed25519 AAAA... automated-script-key
|
这可以防止用户在登录后执行交互式命令,减少误操作风险。
4. no-X11-forwarding / no-agent-forwarding:禁用 X11 和 Agent 转发#
这两个选项分别禁止 X11 转发和 SSH Agent 转发:
1
2
3
4
5
6
7
8
|
# 禁用 X11 转发
no-X11-forwarding ssh-ed25519 AAAA... user@workstation
# 禁用 Agent 转发
no-agent-forwarding ssh-ed25519 AAAA... user@workstation
# 同时禁用两者
no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA... user@workstation
|
5. no-port-forwarding / no-user-rc:禁用端口转发#
no-port-forwarding 禁止通过该会话建立端口转发:
1
2
3
4
5
6
|
# 禁用端口转发
no-port-forwarding ssh-ed25519 AAAA... user@workstation
# 尝试建立端口转发会被拒绝
$ ssh -i ~/.ssh/id_ed25519 -L 8080:localhost:80 user@server
# 警告:port forwarding is disallowed for this key
|
no-user-rc 禁止执行用户目录下的 ~/.ssh/rc 文件,防止恶意 rc 脚本自动执行。
6. environment:设置环境变量#
可以在登录时设置特定环境变量:
1
2
|
# 设置环境变量
environment="TEAM=infrastructure" ssh-ed25519 AAAA... user@workstation
|
在 sshd_config 中需要启用 PermitUserEnvironment 才能生效。
7. tunnel:强制建立 Tunnel设备#
tunnel=n 强制建立指定的 tunnel 设备:
1
2
|
# 强制使用 tunnel 设备 0
tunnel=0 ssh-ed25519 AAAA... user@workstation
|
8. limit:限制带宽#
limit 选项限制该连接的最大带宽:
1
2
3
4
5
|
# 限制为 1Mbps
limit=1M ssh-ed25519 AAAA... user@workstation
# 限制为 10Mbps
limit=10M ssh-ed25519 AAAA... user@workstation
|
9. Expiry(过期时间)设置#
通过 expires 和 valid_after 设置公钥的有效期:
1
2
3
4
5
|
# 设置过期时间(UTC 时间)
expires="2026-12-31T23:59:59Z" ssh-ed25519 AAAA... temp-key
# 设置生效时间
valid_after="2026-01-01T00:00:00Z" ssh-ed25519 AAAA... future-key
|
组合使用示例#
多个选项可以组合使用,实现精细的权限控制:
1
2
3
4
5
6
7
8
|
# 自动化部署密钥:只能从 CI 服务器登录,只能执行部署脚本,禁止端口转发和终端
from="10.0.0.20",command="/usr/local/bin/deploy.sh",no-pty,no-port-forwarding,no-agent-forwarding ssh-ed25519 AAAA... ci-deploy-key
# Git 访问密钥:只能执行 git 操作,只能从公司网络登录
from="192.168.1.0/24",command="git-shell",no-pty,no-port-forwarding ssh-ed25519 AAAA... git-access-key
# 临时访问密钥:限时有效,只能从特定 IP 登录,无终端
from="203.0.113.50",no-pty,expires="2026-07-20T00:00:00Z" ssh-ed25519 AAAA... temp-access-key
|
验证配置#
查看已配置的选项#
1
2
3
4
5
|
# 查看用户的 authorized_keys 文件
cat ~/.ssh/authorized_keys
# 使用 sshd -T 查看默认配置
sshd -T | grep -i authorizedkeyscommand
|
测试限制是否生效#
1
2
3
4
5
6
7
8
9
10
|
# 测试 no-pty
ssh -i ~/.ssh/restricted_key user@server
# 应该无法获得终端
# 测试 no-port-forwarding
ssh -i ~/.ssh/restricted_key -L 8080:localhost:80 user@server
# 应该显示警告或拒绝
# 测试 from 限制
# 从非允许 IP 登录应该被拒绝
|
安全最佳实践#
-
最小权限原则:只为每种用途创建单独的公钥,使用最严格的必要限制
-
来源 IP 限制:尽量使用 from 限制登录来源,减少密钥泄露后的攻击面
-
禁用完整终端:对于自动化任务使用 no-pty,对于需要交互的场景也考虑限制
-
禁止端口转发:除非明确需要,否则都应禁用端口转发
-
设置过期时间:临时访问使用 expires 设置明确的有效期
-
审计日志:定期检查 /var/log/auth.log(Linux)或 /var/log/secure(RHEL)中的 SSH 登录记录
authorized_keys 提供的限制选项是 SSH 安全加固的重要工具。通过合理组合这些选项,可以实现:
- 命令限制:用户只能执行预定义的命令
- 来源限制:只能从特定 IP 或网络登录
- 功能限制:禁止端口转发、X11 转发、Agent 转发等
- 时间限制:设置公钥的生效和失效时间
- 带宽限制:控制连接的最大带宽
将这些限制与 SSH 服务器的全局配置(如 Match 块、AllowUsers、AllowGroups)结合,可以构建多层次的 SSH 访问控制体系。
参考来源#