TL;DR - 去回答底部,"应用限制"
添加受限用户包括两个部分:
1. 创建用户
2. 配置SSH守护进程(sshd)
配置sshd
了解SSH的可能性最好的方法是阅读相关的手册页面:
SSH客户端可以在哪里执行操作?
在你可以限制某些东西之前,你需要了解SSH的功能。浏览手册页面得到以下信息:
- Shell命令执行
- 通过sftp上传文件
- 端口转发
- 客户端将(未)使用的端口转发到服务器
- 服务器将他的端口转发给客户端
- 服务器将另一主机的端口转发给客户端(类似代理)
- X11转发(显示转发)
- 身份验证代理转发
- 隧道设备的转发
来自 sshd(8)手册页面上的身份验证部分。
如果客户端成功进行身份验证,将进入准备会话的对话框。此时,客户端可以请求诸如分配伪终端、转发X11连接、转发TCP连接或转发身份验证代理连接等内容,通过安全通道进行传输。
之后,客户端要么请求一个shell,要么执行一个命令。然后双方进入会话模式。在这种模式下,任何一方都可以随时发送数据,并且这些数据将被转发到服务器端的shell或命令以及客户端的用户终端之间。
限制SSH功能的选项
影响行为的文件及其选项包括:
~/.ssh/authorized_keys
- 包含允许连接的密钥,可以给出选项:
command="command"
- 忽略用户提供的命令(如果有)。请注意,客户端可以指定TCP和/或X11转发,除非明确禁止。请注意,此选项适用于shell、命令或子系统执行。
no-agent-forwarding
- 当使用此密钥进行身份验证时,禁止身份验证代理转发。
no-port-forwarding
- 当使用此密钥进行身份验证时,禁止TCP转发。
no-X11-forwarding
- 当使用此密钥进行身份验证时,禁止X11转发。
permitopen="host:port"
- 限制本地'ssh -L'端口转发,只能连接到指定的主机和端口。
~/.ssh/environment
- 如果存在,则在登录时将此文件读入环境中。默认情况下,禁用环境处理,并通过PermitUserEnvironment选项进行控制。
~/.ssh/rc
- 包含在用户的主目录变得可访问之前要运行的初始化例程。
/etc/ssh/sshd_config
- 系统范围的配置文件
AllowAgentForwarding
- 指定是否允许ssh-agent(1)转发。
AllowTcpForwarding
ForceCommand
- "强制执行由ForceCommand指定的命令,忽略客户端提供的任何命令和~/.ssh/rc(如果存在)。使用用户的登录shell以-c选项调用该命令。"
GatewayPorts
- "指定远程主机是否允许连接到为客户端转发的端口。默认情况下,sshd(8)将远程端口转发绑定到回环地址。这样可以防止其他远程主机连接到转发的端口。可以使用GatewayPorts来指定sshd应允许远程端口转发绑定到非回环地址,从而允许其他主机连接。"
PermitOpen
:
指定允许TCP端口转发的目标。转发规范必须是以下形式之一:
PermitOpen 主机:端口
PermitOpen IPv4地址:端口
PermitOpen [IPv6地址]:端口
可以通过使用空格分隔它们来指定多个转发。可以使用'any'参数来移除所有限制并允许任何转发请求。默认情况下,允许所有端口转发请求。
PermitTunnel - 指定是否允许tun(4)设备转发。默认值为'no'
X11Forwarding - 指定是否允许X11转发。默认值为'no'
应用限制规则。
修改系统范围的配置文件
/etc/ssh/sshd_config
可以使配置即使在应用基于密码的身份验证或者在
~/.ssh/authorized_keys
中的限制被意外删除时也能生效。如果您已经修改了全局默认值,您应该相应地取消注释选项。
Match User limited-user
#AllowTcpForwarding yes
#X11Forwarding no
#PermitTunnel no
#GatewayPorts no
AllowAgentForwarding no
PermitOpen localhost:62222
ForceCommand echo 'This account can only be used for [reason]'
现在添加一个用户:
sudo useradd -m limited-user
选项
ForceCommand
可以省略,如果shell设置为非shell,例如
/bin/false
(或
/bin/true
),因为
/bin/false -c [command]
不会执行任何操作。
现在客户端只能通过SSH连接到服务器的回环地址上的62222端口(它不会监听公共IP地址)。
禁用AllowTcpForwarding
也将禁止使用-R
,从而破坏了使用这样一个受限帐户进行单个端口转发的用途。PermitOpen localhost:62222
假定服务器上的端口62222从未被使用,因为客户端可以愉快地连接并监听它。
如果系统范围的配置允许TCP转发,并禁用基于密码的身份验证,则也可以使用每个密钥的设置。编辑~/.ssh/authorized_keys
并在ssh-
之前添加下一个选项(选项和ssh-
之间有一个空格):
command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"
验证
为了确保它按预期工作,需要运行一些测试用例。在下面的命令中,如果~/.ssh/config
中没有设置登录名,则应替换host
为实际的登录名。在命令后面,显示了一个应在客户端或服务器上执行的命令(根据指定)。
# connection closed:
ssh host
# connection closed (/bin/date is not executed):
ssh host /bin/date
# administratively prohibited (2x):
ssh host -N -D 62222 # client: curl -I --socks5 localhost:62222 example.com
ssh host -N -L 8080:example.com:80 # client: curl -I localhost:8080
sftp host
# should be possible because the client should forward his SSH server
ssh host -N -R 8080:example.com:80 # server: curl -I localhost:8080
# This works, it forwards the client SSH to the server
ssh host -N -R 62222:localhost:22
# unfortunately, the client can listen on that port too. Not a big issue
ssh host -N -L 1234:localhost:62222
结论
检查清单:SSH用户不应该能够:
- 执行shell命令 - 完成
- 访问文件或将文件上传到服务器 - 完成
- 使用服务器作为代理(例如Web代理) - 完成
- 访问由于防火墙而无法公开访问的本地服务 - 部分完成,客户端无法访问除62222端口之外的其他端口,但可以监听并连接到服务器上的62222端口
- 关闭服务器 - 完成
(请注意,这些检查仅限于SSH服务器。如果您在机器上有其他易受攻击的服务,可能会允许潜在攻击者运行命令、关闭服务器等)