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(过期时间)设置

通过 expiresvalid_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 登录应该被拒绝

安全最佳实践

  1. 最小权限原则:只为每种用途创建单独的公钥,使用最严格的必要限制

  2. 来源 IP 限制:尽量使用 from 限制登录来源,减少密钥泄露后的攻击面

  3. 禁用完整终端:对于自动化任务使用 no-pty,对于需要交互的场景也考虑限制

  4. 禁止端口转发:除非明确需要,否则都应禁用端口转发

  5. 设置过期时间:临时访问使用 expires 设置明确的有效期

  6. 审计日志:定期检查 /var/log/auth.log(Linux)或 /var/log/secure(RHEL)中的 SSH 登录记录

总结

authorized_keys 提供的限制选项是 SSH 安全加固的重要工具。通过合理组合这些选项,可以实现:

  • 命令限制:用户只能执行预定义的命令
  • 来源限制:只能从特定 IP 或网络登录
  • 功能限制:禁止端口转发、X11 转发、Agent 转发等
  • 时间限制:设置公钥的生效和失效时间
  • 带宽限制:控制连接的最大带宽

将这些限制与 SSH 服务器的全局配置(如 Match 块、AllowUsersAllowGroups)结合,可以构建多层次的 SSH 访问控制体系。

参考来源