允许用户设置 SSH 隧道,但仅此而已

Posted

技术标签:

【中文标题】允许用户设置 SSH 隧道,但仅此而已【英文标题】:Allow user to set up an SSH tunnel, but nothing else 【发布时间】:2010-09-05 16:48:35 【问题描述】:

我希望允许用户在特定端口(例如 5000)上设置到特定机器的 SSH 隧道,但我希望尽可能限制此用户。 (身份验证将使用公钥/私钥对)。

我知道我需要编辑相关的 ~/.ssh/authorized_keys 文件,但我不确定要在其中放入什么内容(公钥除外)。

【问题讨论】:

【参考方案1】:

见this post on authenticating public keys。

您需要记住的两个主要事项是:

    确保你chmod 700 ~/.ssh 将公钥块附加到授权密钥

【讨论】:

【参考方案2】:

您将通过用户使用的任何 ssh 客户端在用户机器上生成一个密钥。例如,pUTTY 有一个实用程序来做这件事。它将生成私钥和公钥。

生成的公钥文件的内容会放在authorized_keys文件中。

接下来,您需要确保将 ssh 客户端配置为使用生成公钥的私钥。这相当简单,但根据所使用的客户端略有不同。

【讨论】:

【参考方案3】:

您可能希望将用户的 shell 设置为 the restricted shell。在用户的 ~/.bashrc 或 ~/.bash_profile 中取消设置 PATH 变量,他们将无法执行任何命令。稍后,如果您决定允许用户执行一组有限的命令,例如 lesstail,那么您可以将允许的命令复制到单独的目录(例如 @987654326 @) 并更新 PATH 以指向该目录。

【讨论】:

但这并不妨碍用户在 ssh 命令行上指定不同的命令,例如 ssh use@host "/bin/bash",是吗? 是的,假设 user@host 有 rbash 作为 shell。见The Restricted Shell 好的,我试过了,你是对的。由于指定的命令是由登录shell执行的,所以执行/bin/bash会失败,因为它包含斜杠。 虽然应该说允许less 可能是个坏主意,因为从那里你可以使用!/bin/bash 逃到一个不受限制的shell。有关其他示例,请参阅pen-testing.sans.org/blog/2012/06/06/…。所以允许单独的命令应该非常非常小心,如果有的话。【参考方案4】:

我可以使用公钥设置 authorized_keys 文件以记录 我不确定的是我需要的其他信息 限制允许该帐户执行的操作。例如,我知道我可以 输入命令,例如:

no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding

您可能希望在您的 authorized_keys 文件中出现如下所示的一行。

permitopen="host.domain.tld:443",no-pty,no-agent-forwarding,no-X11-forwardi
ng,command="/bin/noshell.sh" ssh-rsa AAAAB3NzaC.......wCUw== zoredache 

【讨论】:

【参考方案5】:

除了 no-X11-forwarding 之类的 authorized_keys 选项之外,实际上还有一个您需要的选项:permitopen="host:port"。通过使用此选项,用户只能建立到指定主机和端口的隧道。

关于 AUTHORIZED_KEYS 文件格式的详细信息,请参考 man sshd。

【讨论】:

您还需要将“no-pty”指定为选项集的一部分。如果您仅使用“permitopen”,那么您将限制到给定主机/端口的隧道......但您仍将允许交互式 shell。 使用 permitopen 限制端口转发是否也会锁定 ssh -w 要求的隧道设备转发类型? @JohnHart:no-pty 也不限制 shell 访问,您仍然可以访问 shell,只是不会显示提示;您仍然可以发出命令并很好地查看输出。如果您想限制来自.ssh/authorized_keys 的shell 访问,则需要command="..." 选项。【参考方案6】:

在 Ubuntu 11.10 上,我发现我可以阻止带有和不带有 -T 的 ssh 命令,并阻止 scp 复制,同时允许端口转发通过。

具体来说,我在绑定到 localhost:6379 的“somehost”上有一个 redis-server,我希望通过 ssh 隧道安全地共享到其他具有密钥文件并将通过 ssh 登录的主机:

$ ssh -i keyfile.rsa -T -N -L 16379:localhost:6379 someuser@somehost

这将导致redis-server,“somehost”上的“localhost”端口6379出现在本地执行ssh命令的主机上,重新映射到“localhost”端口16379。

在远程“somehost”上这是我用于authorized_keys的:

cat .ssh/authorized_keys   (portions redacted)

no-pty,no-X11-forwarding,permitopen="localhost:6379",command="/bin/echo do-not-send-commands" ssh-rsa rsa-public-key-code-goes-here keyuser@keyhost

no-pty 会阻止大多数想要打开终端的 ssh 尝试。

permitopen 解释了允许转发哪些端口,在本例中端口 6379 是我要转发的 redis-server 端口。

command="/bin/echo do-not-send-commands" 如果某人或某物确实设法通过 ssh -T 或其他方式向主机发送命令,则返回“do-not-send-commands”。

来自最近的一个Ubuntuman sshd,authorized_keys/命令描述如下:

command="命令" 指定在使用此键时执行命令 用于身份验证。用户提供的命令(如果有)是 忽略。

尝试使用 scp 安全文件复制也将失败,并回显“do-not-send-commands”我发现 sftp 在此配置下也会失败。

我认为在以前的一些答案中提出的受限 shell 建议也是一个好主意。 另外,我同意这里详细介绍的所有内容都可以通过阅读“man sshd”并在其中搜索“authorized_keys”来确定

【讨论】:

虽然no-pty 不允许打开交互式视图,但它不会阻止命令执行,因此用户可以编辑authorized_keys 文件,如果他有类似ssh server 'sed -i -e s/no-pty// ~/.ssh/authorized_keys' 的访问权限。跨度> @synapse command="/bin/echo do-not-send-commands",也在上面列出,旨在阻止命令。并提供信息。你是打算让你的例子打败上面的整个设置,还是只评论 no-pty? 值得一提的是,管理员没有义务授予用户对 authorized_keys 文件或包含目录的所有权,它甚至不存在于用户的主目录中(假设 ssh 服务器已针对其位置进行了正确配置) ?? @DanFarrell .ssh/authorized_keys 将归 root、wheel 或谁所有? @AndrewWolfe 通常,~user/.ssh/authorized_keys 将归 user 所有,user 将管理用于访问帐户的授权密钥。 SSH 对权限很挑剔,可能会对~/.ssh/ 及其内容施加期望。我做了一个sudo chown root: .ssh/authorized_keys,它似乎阻止了我登录,但根据过去的经验,我知道用户不必拥有该文件 - 如果您愿意,root 可以管理它。【参考方案7】:

如果您只想允许访问特定命令(例如 svn),您还可以在授权密钥文件中指定该命令:

command="svnserve -t",no-port-forwarding,no-pty,no-agent-forwarding,no-X11-forwarding [KEY TYPE] [KEY] [KEY COMMENT]

来自http://svn.apache.org/repos/asf/subversion/trunk/notes/ssh-tricks

【讨论】:

【参考方案8】:

我的解决方案是为仅可能在隧道中的用户提供没有交互式 shell,将 /etc/passwd 中的 shell 设置为 /usr /bin/tunnel_shell.

只需创建带有无限循环的可执行文件/usr/bin/tunnel_shell

#!/bin/bash
trap '' 2 20 24
clear
echo -e "\r\n\033[32mSSH tunnel started, shell disabled by the system administrator\r\n"
while [ true ] ; do
sleep 1000
done
exit 0

这里有完整的解释: http://blog.flowl.info/2011/ssh-tunnel-group-only-and-no-shell-please/

【讨论】:

CTRL+Z 将从脚本中转义,让您可以完全访问 bash... 尝试在脚本的开头添加“trap '' 20”(不带引号) 感谢提示,我添加了一些中断信号的捕获 我只是使用 /bin/cat 作为“shell”。似乎工作正常。不知道有任何针对 cat 的攻击,即使您确实找到了一些设法使其崩溃的输入模式,您的 ssh 会话也会终止。 @BigPapoo:你真的测试过吗?我看不出它会逃到哪里。如果你在 shell 中运行tunnel_shell,你将拥有shell -> /bin/bash tunnel_shell,所以你当然可以逃回 shell,但是如果你设置了tunnel_shell as用户的外壳,据我所知,您只会运行/bin/bash tunnel_shell,没有外壳可以逃逸。我测试了它,无法用 ctrl-z 逃脱。如果您确实尝试过并且可以逃脱,您可以发布设置吗?同样,如果您知道任何说明它应该这样工作的文档,您可以发布吗?【参考方案9】:

我做了一个如下所示的 C 程序:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void sig_handler(int signo)

    if (signo == SIGHUP)
        exit(0);


int main()

    signal(SIGINT, &sig_handler);
    signal(SIGTSTP, &sig_handler);

    printf("OK\n");
    while(1)
        sleep(1);
    exit(0);

我将受限用户的 shell 设置为这个程序。

我不认为受限用户可以执行任何操作,即使他们执行ssh server command,因为命令是使用 shell 执行的,而这个 shell 不执行任何操作。

【讨论】:

【参考方案10】:

这里有一篇我觉得很有用的好帖子: http://www.ab-weblog.com/en/creating-a-restricted-ssh-user-for-ssh-tunneling-only/

想法是:(使用新的受限用户名“sshtunnel”)

useradd sshtunnel -m -d /home/sshtunnel -s /bin/rbash
passwd sshtunnel

请注意,我们使用 rbash(restricted-bash)来限制用户可以做什么:用户不能 cd(更改目录)并且不能设置任何环境变量。

然后我们将/home/sshtunnel/.profile 中用户的 PATH 环境变量编辑为空 - 这个技巧会使 bash 找不到任何要执行的命令:

PATH=""

最后我们通过设置以下权限来禁止用户编辑任何文件:

chmod 555 /home/sshtunnel/
cd /home/sshtunnel/
chmod 444 .bash_logout .bashrc .profile

【讨论】:

以上是关于允许用户设置 SSH 隧道,但仅此而已的主要内容,如果未能解决你的问题,请参考以下文章

通过ssh隧道连接

反向 SSH 隧道监控

通过 DataGrip 上的 ssh 隧道更快地连接

通过 ssh 迁移工作台 - 如何设置隧道

来自 Heroku 的 SSH 隧道

SSH隧道到远程服务器的问题