当前位置: 首页>>技术教程>>正文


如何为端口转发创建受限制的SSH用户?

, , ,

问题描述

ændrüksuggested a reverse connection用于与其他人建立简单的SSH连接(用于远程帮助)。为此,需要额外的用户来接受连接。该用户需要能够通过服务器转发他的端口(服务器充当代理)。

我如何创建一个只能执行上述操作的受限用户?

新用户不能够:

  • 执行shell命令

  • 访问文件或将文件上传到服务器

  • 使用服务器作为代理(例如webproxy)

  • 访问因防火墙而无法公开访问的本地服务

  • 杀死服务器

总结一下,我如何创建一个只能连接到SSH服务器而没有权限的受限制的SSH用户,所以我可以通过这个连接与他的电脑连接?

最佳解决思路

长话短说 – 进入答案的底部,“应用限制”

添加受限用户包括两部分:1.创建用户2.配置SSH守护进程(sshd)

配置sshd

了解SSH可能性的最佳地点是阅读相关手册页:

SSH客户端可以在哪里执行操作?

在限制某些内容之前,您需要了解SSH的功能。通过手册页随地吐痰:

  • Shell命令执行

  • 通过sftp上传文件

  • 转发端口

    • 客户端将(未)使用的端口转发给服务器

    • 服务器将其端口转发给客户端

    • 服务器将另一主机的端口转发给客户端(proxy-ish)

  • X11转发(显示转发)

  • 认证代理转发

  • 转发隧道设备

manual page of sshd(8)的认证部分:

If the client successfully authenticates itself, a dialog for preparing the session is entered. At this time the client may request things like allocating a pseudo-tty, forwarding X11 connections, forwarding TCP connections, or forwarding the authentication agent connection over the secure channel.

After this, the client either requests a shell or execution of a command. The sides then enter session mode. In this mode, either side may send data at any time, and such data is forwarded to/from the shell or command on the server side, and the user terminal in the client side.

限制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 – system-wide配置文件

    • AllowAgentForwarding – 指定是否允许ssh-agent(1)转发。

    • AllowTcpForwarding

    • ForceCommand – “强制执行由ForceCommand指定的命令,忽略由客户端提供的任何命令以及〜/.ssh /rc(如果存在)。该命令通过使用带有-c选项的用户登录shell进行调用。

    • GatewayPorts – “指定是否允许远程主机连接到为客户端转发的端口。默认情况下,sshd(8)将远程端口转发绑定到环回地址,以防止其他远程主机连接到转发的端口。指定sshd应允许远程端口转发绑定到non-loopback地址,从而允许其他主机连接。“

    • PermitOpen

      指定允许TCP端口转发的目标。转发规范必须是以下形式之一:PermitOpen host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port
      可以通过用空格分隔多个转发来指定转发规范。 ‘any’的参数可用于删除所有限制并允许任何转发请求。默认情况下允许所有端口转发请求。

    • PermitTunnel – 指定是否允许tun(4)设备转发。默认值是’no’

    • X11Forwarding – 指定是否允许X11转发。默认值是’no’

应用限制

修改system-wide配置文件/etc/ssh/sshd_config允许即使应用password-based身份验证或~/.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 设置为non-shell(如/bin/false)(或/bin/true),则ForceCommand选项可以省略,因为/bin/false -c [command]不会执行任何操作。

现在,客户端只能通过SSH连接到服务器环回地址上的端口62222(它不会侦听公共IP地址)

禁用AllowTcpForwarding也将禁止使用-R,从而阻止使用此类受限帐户转发单个端口。 PermitOpen localhost:62222假定服务器上的端口62222从未被使用,因为客户端可以愉快地连接并监听它。

如果在system-wide配置中允许TCP转发并禁用了password-based认证,则也可以使用per-key设置。编辑~/.ssh/authorized_keys并在ssh-之前添加下一个选项(在选项和ssh-之间留有空格):

command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"

Verify

为确保它按预期工作,需要运行一些测试用例。在下面的命令中,如果没有在~/.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密钥的身份验证(putty或任何unix ssh应该支持这一点)。

  • 像平常一样添加用户(‘adduser’或任何其他工具)

  • 创建用户.ssh目录和.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 ) <<EOF
no-agent-forwarding,no-X11-forwarding,command="read a; exit" ssh-rsa AAAB3NzaC1y....2cD/VN3NtHw== smoser@brickies
EOF
  • 禁止访问此帐户的密码。

your_user $ sudo usermod --lock ssh_forwarder

现在,用户可以进入系统的唯一方式是通过访问正确的ssh密钥,并且ssh将为他们运行“/bin /bash -c ‘read a’”,无论他们尝试运行什么。 ‘read a’将直接读取直到换行,然后shell将退出,因此用户只需点击’enter’即可终止连接。

在’command=’中可以做很多其他的事情。有关更多信息,请参阅man authorized_keys并搜索’command’。

如果您不喜欢击中输入杀死连接的事实,则可以对’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’。 Googling不是很有帮助。看起来像’no-port-forwarding,permitremoteopen = 10001’对于允许ssh -R 6901:localhost:6901是有用的。

这是一个解决方案。它绝对可以改进,任何远程端口的打开都应该被仔细检查。如果我的目标是允许我的祖母连接到我的局域网,那么我可以使用vnc查看她的屏幕,并且访问这些键仅限于她,我个人会感到相当安全。如果这是针对一个企业的话,那么就需要进行更彻底的调查。有一点需要注意的是ssh -N根本不需要shell,因此’command=’代码不会执行。

其他可能更安全的机制可能包括为用户创建自定义 shell ,甚至用apparmour将其锁定。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/859.html,未经允许,请勿转载。