启用 SSH shell 访问但禁用 SFTP 访问

sos*_*unk 25 security linux ssh sftp

我已经为这个问题寻找了一个可行的答案,大多数答案都包括关于为什么不这样做的建议。但是,这是场景,以及它的必要性:

我有一个控制台应用程序,在每个用户的 .profile 中,都有一个应用程序的启动命令,在启动它的命令之后,有一个“退出”命令,它将它们从系统中注销。我只希望他们能够通过它提供的界面访问这个控制台应用程序。启动时,应用程序向用户显示可通过应用程序访问的客户端列表,每个客户端都有自己的数据目录。用户只能访问他们需要访问的客户端。

现在问题来了:如果我给用户 SSH 访问权限,他们也将能够使用 SFTP 客户端登录,这将使他们能够直接访问应用程序的数据目录,这是非常不受欢迎的,因为这也会给他们访问他们不应该访问的数据目录。

在使用 telnet/FTP 组合时,这是一件非常简单的事情,但现在我想让用户从互联网上的任何地方访问,我一直无法找到一种方法将他们从 SFTP 中排除,而仍然允许他们访问可以运行应用程序的外壳。

cpa*_*ast 31

正如其他人所提到的,禁用sftp还远远不够 - 具有不受限制ssh访问权限的用户可以查看其帐户有权查看的任何文件,可以修改他们有权修改的任何内容,并且可以轻松下载他们可以阅读的任何内容到自己的机器。阻止他们这样做的唯一方法是实际限制他们的访问。依赖于.profile限制用户也不理想,因为这不是它的用途(编辑:正如 Aleksi 在他的回答中提到的,绕过实际上是微不足道的.profile;问题.profile是它是为了方便,而不是为了安全,所以它不是旨在限制用户。使用为安全设计的东西,如下面的东西,以提供安全)。

有两种基本方法可以做到这一点:您可以通过文件权限限制它们,或者强制它们仅执行您的控制台应用程序。第二种方法更好:将应该限制在控制台应用程序中的用户分配到一个组(例如customers);然后,在 中sshd_config,添加以下几行:

Match Group customers
ForceCommand /path/to/app
Run Code Online (Sandbox Code Playgroud)

这样做的目的是使该组中用户的所有连接都打开控制台应用程序;他们不能启动其他任何东西,包括sftp服务器工具。这也阻止他们对系统做任何其他事情,与 不同的是.profile,它使用 SSH 服务器本身(.profile在 shell 中限制它们,ForceCommand还防止做其他不涉及启动 shell 的事情)。也不像.profile,这是为了安全而设计的;它专门用于抵御恶意用户逃避它。

(可能较差的)替代方案将涉及创建一个新用户来运行控制台应用程序。然后,您将数据目录限制为该用户,设置该用户拥有的控制台应用程序,并u+s在程序上进行设置。这是setuid位;这意味着运行控制台程序的人是在程序所有者的许可下这样做的。这样,用户自己就无法访问目录,他们只能通过程序获取它。但是,您可能应该只使用ForceCommand,因为这会将所有访问权限限制为“仅运行此程序”。

  • 我想补充一点,`ForceCommand` 不会阻止 SSH 端口转发。 (6认同)

Wes*_*ley 24

编辑:

如果不明显,以下答案并不是一种安全方法,可以防止任何对服务器具有 shell 访问权限的人使用 SFTP。这只是一个解释如何从外部可见性中禁用它的答案。有关用户级安全性的讨论,请参阅 @cpast 和 @Aleksi Torhamo 的回答。如果安全是您的重点,那么这个答案就不是正确的答案。如果简单的服务可见性是您的重点,那么这就是您的答案。

我们现在继续原来的答案:


注释掉 sshd_config 中的 sftp 支持(当然还有 restart sshd):

#Subsystem sftp /usr/lib/openssh/sftp-server

  • 这听起来不太合理。如果您可以在服务器上执行任意命令,则可以执行 sftp 服务器端程序。即使未安装,您也可以将其重新实现为长 shell 命令,并让 sftp 客户端发送此命令而不是 sftp。此方法可能会降低使用 sftp 的便利性,但无法阻止可以运行任意命令的用户使用这些命令进行文件传输。 (16认同)
  • 有时行可以是“子系统 sftp 内部 sftp” (2认同)

Ale*_*amo 15

不要尝试这样做,.profile因为它不提供任何安全性并且完全没有限制!

这不要紧,你放什么.profile,因为你可以绕过它通过简单地发出指令到SSH命令行中运行,像这样:ssh user@host command。您仍然可以通过执行ssh -t user@host bash.

禁用 sftp 子系统,如另一个答案中所述,根本没有帮助。子系统本质上只是命令的别名,您仍然可以通过执行sftp -s /path/to/sftp-executable user@host.

就像 cpast 和一些评论者所说的那样,您应该使用适当的机制来限制访问。那是,

  • 使用ForceCommandsshd_config
  • 使用密码登录,并command="...".ssh/authorized_keys
  • 将用户的 shell 更改为限制用户可以执行的操作

笔记:

  • command="..." 仅适用于一个密钥,因此它不会限制用户使用密码或其他密钥进行 ssh 登录
  • 您可能还想限制端口转发等(端口转发、x11 转发、代理转发和 pty 分配是我听说过的)
    • AllowTcpForwarding 等在 sshd_config
    • no-port-forwarding 等在 .ssh/authorized_keys
  • 如果您有其他守护进程(如 FTP)在运行,您应该验证它们是否不允许用户进入(某些守护进程根据用户的 shell 做出此决定,因此如果您更改它,您可能需要重新检查)
  • 您可以将用户的 shell 更改为执行您想要的操作的脚本;它要么不带参数运行,要么像script -c 'command-the-user-wanted-to-run'
  • 双方ForceCommandcommand="..."通过用户的shell运行命令,所以如果用户的shell设置为如他们不这样做的工作。/bin/false或者/sbin/nologin

免责声明:无论如何我都不是这方面的专家,所以虽然我可以说这.profile件事不安全,但我不能保证我不知道的其他方法没有一些“问题”关于。据我所知,它们是安全的,但我不会是第一个在互联网上出错的人。

  • @chicks:另外,我刚刚意识到你提到了 cpast;cpast 答案中的方法不使用`.profile`,它使用`sshd_config`,应该是安全的。他只提到`.profile` 作为一种你不应该使用的方法。 (2认同)