如何修改此代码以便能够通过 SSH 连接到我的服务器?

Vah*_*han 12 ssh putty tunnel ubuntu

我有一个 18.04 Ubuntu 服务器,我用它通过 SSH 隧道绕过我所在国家/地区的互联网过滤/审查制度。为此,我使用该命令创建了多个用户adduser USERNAME --shell=/bin/false,并为他们提供了服务器 IP、服务器端口、用户名和密码(我将其称为帐户),以便他们可以通过我的服务器建立隧道。现在我想确保每个帐户一次只能在一台设备上使用。换句话说,我想防止多个设备使用同一帐户同时通过我的服务器建立隧道。

通过谷歌搜索,我找到了一个解决方案:我将以下内容放入文件中/root/checkConnections

#! /bin/bash

limit=$1
c=$(pgrep -xcu $PAM_USER sshd)
if [[ $c -ge "$limit" ]]; then 
    echo "Max $limit ssh connections allowed, but you have $c."
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

然后/etc/pam.d/sshd我添加了:

session required pam_exec.so stdout /root/checkConnections 1
Run Code Online (Sandbox Code Playgroud)

这段代码运行良好,并且完全符合我的要求,但它有一个明显的缺点:当我退出 putty 时,我无法再通过 ssh 连接到服务器!换句话说,当我尝试以 root 身份 ssh 到服务器时,它立即将我踢出并不允许我登录,这就是我必须重新安装服务器的原因。我怎么解决这个问题?

注意:我对 Linux 服务器世界非常陌生,所以请简单地解释一下你的解决方案。

Kam*_*ski 21

sshd您找到的脚本通过计算属于尝试通过 SSH 登录的用户的进程数来工作。如果该数字大于或等于限制(在您的情况下为 1),则脚本将返回失败,从而阻止建立会话。

\n

问题是主要的 SSH 守护进程本身是一个sshd属于 root 的进程。(在此答案中,您可以看到它sshd是一个守护进程,并且sshd属于普通用户。)当守护进程运行时,sshdroot 的进程数始终至少为 1。运行中的 SSH 守护进程的唯一存在会导致您的代码锁定根。

\n

可能的解决方案:

\n
    \n
  • 习惯以普通用户身份登录。登录后,需要时使用sudosu成为 root。这是一种常见的做法。甚至可以使用 in 来禁用或限制以 root 身份通过 SSHPermitRootLogin登录/etc/ssh/sshd_config出于安全原因您可能需要这样做。

    \n

    作为普通用户,您应该能够登录。您的脚本会将您视为任何其他普通用户,即对一个会话的限制将适用;但(与 root 不同)您将能够登录。

    \n
  • \n
  • 修改脚本,因此如果用户是 root,则无论sshd进程数如何,脚本都会返回成功。一个简单的修复方法是像这样扩展if

    \n
    if [ "$PAM_USER" != root ] && [ "$c" -ge "$limit" ]; then\n
    Run Code Online (Sandbox Code Playgroud)\n

    这意味着“如果用户不是 root 并且达到限制,则 \xe2\x80\xa6 [稍后返回失败]”;但尽早检查用户而不是pgrep徒劳地调用会更优雅。下面的代码使用了这种更优雅的方法。

    \n
  • \n
\n

如果我是你,我会合并这两个解决方案。我将以普通用户身份登录,并使该用户像 root 一样不受限制。

\n

如果用户是root或,以下脚本将返回成功vahid。限制逻辑仅对其他用户生效。

\n
#! /bin/sh\ncase "$PAM_USER" in\n   root|vahid )\n      exit 0 ;;\n   * )\n      limit="$1"\n      c="$(pgrep -xcu "$PAM_USER" sshd)"\n      if [ "$c" -ge "$limit" ]; then \n         echo "Max $limit ssh connections allowed, but you have $c."\n         exit 1\n      fi\n   ;;\nesac\n
Run Code Online (Sandbox Code Playgroud)\n

我故意使用的sh,它可能比 更轻(启动更快,使用更少的资源)bash

\n
\n

另外我认为这个条目/etc/pam.d/sshd

\n
\n
session required pam_exec.so stdout /root/checkConnections 1\n
Run Code Online (Sandbox Code Playgroud)\n
\n

可能会被绕过ssh -N。由于您/bin/false为其他用户设置,我猜ssh -N这就是您希望他们使用的内容。要使脚本即使在 的情况下也能完成其工作ssh -N,请指定account而不是session

\n
account required pam_exec.so stdout /root/checkConnections 1\n
Run Code Online (Sandbox Code Playgroud)\n

  • @Vahid (1) 我不会给你发送任何电子邮件。如果您收到一封据称是我发来的电子邮件,那么它将来自冒名顶替者。 (2) 在确定可以重新连接(可能连接到不同的用户)并从那里获得 root 访问权限之前,不要关闭正在工作的 SSH 连接。配置关键内容时,保持至少一个提升的 shell 运行是一种很好的做法。 (3) 每次重新应用任何解决方案时,请确认您使“/root/checkConnections”可执行。 (4)“把我踢出去”含糊其辞。一些日志或错误消息可能会有所帮助。如果您使用“ssh”而不是 PuTTY,我们将从“ssh -v …”获取信息。 (2认同)