如何为端口转发创建受限制的SSH用户?
ændrük 建议使用反向连接以便与其他人轻松建立SSH连接(用于远程帮助)。 为此,需要额外的用户来接受连接。 该用户需要能够通过服务器转发其端口(服务器充当代理)。
如何创建一个只能执行上述操作的受限用户?
新用户必须无法 :
- 执行shell命令
- 访问文件或将文件上传到服务器
- 使用服务器作为代理(例如webproxy)
- 访问由于防火墙而无法公开访问的本地服务
- 杀死服务器
总结一下,如何创建一个只能在没有权限的情况下连接到SSH服务器的受限SSH用户,这样我就可以通过该连接与他的计算机连接?
TL; DR – 回答底部,“应用限制”
添加受限用户包括两部分:1。创建用户2.配置SSH守护程序(sshd)
配置sshd
了解SSH可能性的最佳位置是阅读相关的手册页:
- SSH(1)
- ssh_config中(5)
- 的sshd(8)
- sshd_config中(5)
SSH客户端在哪里可以执行操作?
在限制某些内容之前,您需要了解SSH的function。 通过手册页吐出产生:
- Shell命令执行
- 通过sftp上传文件
- 转发端口
- 客户端将(未)使用的端口转发到服务器
- 服务器将其端口转发给客户端
- 服务器将另一台主机的端口转发给客户端(proxy-ish)
- X11转发(显示转发)
- validation代理转发
- 转发隧道设备
从sshd(8)手册页的Authentication部分:
如果客户端成功validation自身,则会输入准备会话的对话框。 此时,客户端可以请求诸如分配伪tty,转发X11连接,转发TCP连接或通过安全信道转发认证代理连接之类的事情。
在此之后,客户端请求shell或执行命令 。 然后双方进入会话模式。 在这种模式下,任何一方都可以随时发送数据,并且这些数据被转发到/从服务器端的shell或命令以及客户端的用户终端转发。
限制SSHfunction的选项
更改行为的文件及其选项包括:
-
~/.ssh/authorized_keys
– 包含允许连接的键,可以给出选项:-
command="command"
– 忽略用户提供的命令(如果有)。 请注意,除非明确禁止,否则客户端可以指定TCP和/或X11转发 。 请注意,此选项适用于shell,命令或子系统执行。 -
no-agent-forwarding
– 当此密钥用于身份validation时,禁止身份validation代理转发。 -
no-port-forwarding
– 当此密钥用于身份validation时,禁止TCP转发 -
no-X11-forwarding
– “当此密钥用于身份validation时禁止X11转发。” -
permitopen="host:port"
– 限制本地’ssh -L’端口转发,使其只能连接到指定的主机和端口。
-
-
~/.ssh/environment
– 此文件在登录时读入环境(如果存在)。 默认情况下禁用环境处理,并通过PermitUserEnvironment选项进行控制 -
~/.ssh/rc
– 包含在用户主目录可访问之前运行的初始化例程。 -
/etc/ssh/sshd_config
– 系统范围的配置文件-
AllowAgentForwarding
– 指定是否允许ssh-agent(1)转发。 -
AllowTcpForwarding
-
ForceCommand
– “强制执行ForceCommand指定的命令,忽略客户端提供的任何命令,如果存在,则忽略〜/ .ssh / rc。使用带有-c选项的用户登录shell调用该命令。” -
GatewayPorts
– “指定是否允许远程主机连接到为客户端转发的端口。默认情况下,sshd(8)将远程端口转发绑定到环回地址。这可以防止其他远程主机连接到转发端口.GatewayPorts可用于指定sshd应该允许远程端口转发绑定到非环回地址,从而允许其他主机连接。“ -
PermitOpen
:
-
指定允许TCP端口转发的目标。 转发规范必须是以下forms之一:
PermitOpen host:port PermitOpen IPv4_addr:port PermitOpen [IPv6_addr]:port
可以通过用空格分隔多个转发来指定它们。 “any”的参数可用于删除所有限制并允许任何转发请求。 默认情况下,允许所有端口转发请求。
PermitTunnel
– 指定是否允许tun(4)设备转发。 默认为“否”X11Forwarding
– 指定是否允许X11转发。 默认为“否”适用限制
修改系统范围的配置文件/etc/ssh/sshd_config
允许应用配置,即使应用了基于密码的身份validation或者意外删除了~/.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
如果将shell设置为/bin/false
(或/bin/true
)之类的非shell,则可以省略选项ForceCommand
因为/bin/false -c [command]
将不执行任何操作。
现在客户端只能通过SSH连接到服务器的环回地址上的端口62222(它不会侦听公共IP地址)
禁用AllowTcpForwarding
也会禁止使用-R
,从而无法使用此类受限帐户转发单个端口。 PermitOpen localhost:62222
假设服务器上的端口62222永远不会被使用,因为客户端可以愉快地连接到它并监听它。
如果在系统范围配置中允许TCP转发并禁用基于密码的身份validation,则也可以使用每个键设置。 编辑~/.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命令 – 完成
- 访问文件或将文件上传到服务器 – 完成
- 使用服务器作为代理(例如webproxy) – 完成
- 访问由于防火墙而无法公开访问的本地服务 – 部分地 ,客户端无法访问除62222之外的其他端口,但可以侦听并连接到服务器上的端口62222
- 杀死服务器 – 完成 (请注意,这些检查仅限于SSH服务器。如果您在计算机上有其他易受攻击的服务,则可能允许可能的攻击者运行命令,终止服务器等)
我确信有很多解决方案,比我提议的更强大。 但是,这可能足以满足您的需求。 为了做到这一点,我假设用户能够进行基于ssh密钥的身份validation(putty或任何unix ssh应该支持此function)。
-
像往常一样添加用户(’adduser’或任何其他工具)
-
创建用户.ssh dir和.ssh / authorized_keys
your_user $ sudo -Hu ssh_forwarder /bin/bash ssh_forwarder $ cd ~ ssh_forwarder $ mkdir .ssh ssh_forwarder $ ( umask 066 && cat > .ssh/authorized_keys ) <
- 禁用对此帐户的密码访问权限。
your_user $ sudo usermod --lock ssh_forwarder
现在,用户进入系统的唯一方法是通过访问正确的ssh密钥,ssh将运行“/ bin / bash -c”为他们读取“”,无论他们尝试运行什么。 'read a'将直接读取直到换行符,然后shell将退出,因此用户只需点击'enter'即可终止连接。
你可以在'command ='中做很多其他事情。 有关更多信息,请参阅man authorized_keys
并搜索“command”。
如果你不喜欢按Enter键杀死连接的事实,你可以使用类似下面的'command ='条目:
command="f=./.fifo.$$ && mkfifo $f && trap \"rm -f $f\" EXIT && read a <$f && echo $a; exit;"
这只是在用户主目录中创建一个临时fifo,然后尝试从中读取。 什么都不会写入该文件,因此这将无限期地挂起。 此外,如果您想强制终止该连接,您可以执行以下操作:
your_user$ echo GOODBYE | sudo tee ~ssh_forwarder/.fifo.*
这应该使用非常少的资源,并且在该脚本中没有任何东西应该出错,这不会以终止shell结束。
sleep 1h; echo You have been here too long. Good bye.
我没有看到你如何允许用户远程转发( ssh -R
)但限制( ssh -L
)。 也许可以使用'permitopen'。 谷歌搜索不是很有帮助。 看起来像'no-port-forwarding,allowremoteopen = 10001'这样的东西对于允许ssh -R 6901:localhost:6901
会很有用。
这是一个解决方案。 它绝对可以改进,并且应该仔细检查远程端口的任何打开。 如果我的目标是允许我的祖母连接到我的局域网,那么我可以使用vnc查看她的屏幕,并且访问这些密钥仅限于她,我个人会觉得相当安全。 如果这是针对企业的,则需要进行更彻底的调查。 有一点需要注意的是ssh -N
根本不请求shell,因此'command ='代码不会执行。
其他可能更安全的机制可能包括为用户创建自定义shell,甚至用apparmour将其锁定。