我一直在寻找这个问题的可行答案,大多数答案都包含为什么不这样做的建议。然而,以下是场景以及这样做的必要性:
我有一个控制台应用程序,在每个用户的 .profile 中,都有一个应用程序的启动命令,在启动命令之后,有一个“退出”命令,用于将用户从系统中注销。我只希望他们能够通过它提供的界面访问这个控制台应用程序。启动后,应用程序会向用户显示可通过应用程序访问的客户端列表,每个客户端都有自己的数据目录。用户只能访问他们需要访问的客户端。
现在问题是:如果我授予用户 SSH 访问权限,他们也将能够使用 SFTP 客户端登录,这将使他们能够直接访问应用程序的数据目录,这是非常不可取的,因为这也将使他们能够访问他们不应该访问的数据目录。
当使用 telnet/FTP 组合时,这是一件非常简单的事情,但是现在我想让用户从互联网上的任何地方进行访问,我还没有找到一种方法将他们排除在 SFTP 之外,同时仍然允许他们访问可以运行应用程序的 shell。
答案1
编辑:
如果不明显的话,以下答案并非安全的防止任何有服务器 shell 访问权限的人使用 SFTP 的方法。这只是一个解释如何从外部可见性禁用它的答案。有关用户级安全性的讨论,请参阅 @cpast 和 @Aleksi Torhamo 的答案。如果您关注的是安全性,那么这个答案不合适。如果简单的服务可见性是您的重点,那么这就是您的答案。
我们现在继续原来的答案:
在 sshd_config 中注释掉 sftp 支持(当然还要重新启动sshd
):
#Subsystem sftp /usr/lib/openssh/sftp-server
答案2
正如其他人提到的,禁用sftp
远远不够 - 具有不受限制ssh
访问权限的用户可以查看其帐户有权查看的任何文件,可以修改他们有权修改的任何内容,并且可以轻松地将他们可以读取的任何内容下载到自己的机器上。阻止他们这样做的唯一方法是实际限制他们的访问权限。依靠限制.profile
用户也不是理想的选择,因为这不是它的用途(编辑:正如 Aleksi 在他的回答中提到的,绕过它实际上很简单.profile
;关于的事情.profile
是它是为了方便,而不是安全,所以它不是为了限制用户。使用为安全而设计的东西,比如下面的东西,来提供安全性)。
有两种基本方法可以做到这一点:您可以通过文件权限限制它们,或者强制它们仅执行您的控制台应用程序。第二种方法更好:将应限制使用控制台应用程序的用户分配给一个组(例如customers
);然后在中sshd_config
添加以下几行:
Match Group customers
ForceCommand /path/to/app
这样做的目的是让该组中用户的所有连接都打开控制台应用程序;他们无法启动任何其他东西,包括sftp
服务器工具。这也会阻止他们做任何事情别的与系统不同.profile
,它使用 SSH 服务器本身执行此操作(.profile
在 shell 上限制它们,ForceCommand
还阻止执行不涉及启动 shell 的其他操作)。与 不同的是.profile
,这是设计作为一种安全措施;它是专门为抵御恶意用户逃避它而设计的。
(可能更差的)替代方案将涉及创建一个新用户来运行控制台应用程序。然后,您将数据目录限制为该用户,设置该用户拥有的控制台应用程序,并u+s
在程序上设置。这是setuid
关键;这意味着运行控制台程序的人在程序所有者的权限下这样做。这样,用户自己就无法访问目录,他们只能通过程序获取目录。但是,您可能应该只使用ForceCommand
,因为这会限制全部访问“只运行这个程序”。
答案3
不要尝试这样做,.profile
因为它根本不提供任何安全性并且没有任何限制!
你在 中输入什么并不重要.profile
,因为你可以通过在 ssh 命令行上给出一个运行命令来绕过它,就像这样:ssh user@host command
。你仍然可以通过执行 来获得正常的 shell 访问权限ssh -t user@host bash
。
禁用 sftp 子系统(如另一个答案中提到的)根本没有帮助。子系统本质上只是命令的别名,您仍然可以通过执行以下操作正常使用 sftp sftp -s /path/to/sftp-executable user@host
。
正如 cpast 和一些评论者所说,你应该使用适当的机制来限制访问。也就是说,
- 用于
ForceCommand
sshd_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'
ForceCommand
和都command="..."
通过用户的 shell 运行命令,因此如果用户的 shell 设置为例如,它们就不起作用。/bin/false
或/sbin/nologin
免责声明:我绝不是这方面的专家,因此,尽管我可以说这.profile
东西不安全,但我不能保证其他方法不会出现我不知道的“陷阱”。据我所知,它们是安全的,但我并不是第一个在互联网上犯错的人。
答案4
可以全局和按用户/组启用 SSH 并禁用 SFTP。
我个人需要这个,因为我想通过 SSH 授予对某些 git 存储库的访问权限,并且我喜欢禁用不需要的系统。在这种情况下,不需要 SFTP。
全球
您可以通过几种方式为所有用户禁用 SFTP。
缺失的子系统
SSH 使用的 SFTP 守护进程可以通过Subsystem
关键字进行配置。摘自sshd_config(5)
手册:
Subsystem
Configures an external subsystem (e.g. file transfer daemon).
Arguments should be a subsystem name and a command (with optional
arguments) to execute upon subsystem request.
The command sftp-server(8) implements the “sftp” file transfer
subsystem.
Alternately the name “internal-sftp” implements an in-process
“sftp” server. This may simplify configurations using
ChrootDirectory to force a different filesystem root on clients.
By default no subsystems are defined.
最后一行表明不为“sftp”定义任何子系统就足够了。
虚假的谎言
您还可以通过将 SSH 使用的 SFTP 守护程序设置为不可用来禁用 SFTP。例如,将“sftp”子系统配置为/bin/false
:
Subsystem sftp /bin/false
当有人尝试通过 SFTP 登录时,SSH 守护程序会尝试生成“sftp 守护程序” /bin/false
。该/bin/false
程序只做一件事,即返回错误代码。SFTP 连接尝试实际上被拒绝。
每个用户/组
还可以根据每个用户、组或其他几个标准禁用 SFTP。
如果您希望用户获得常规 shell 提示符,则此方法不起作用。这也没有意义,因为如果你有 shell 访问权限,你就可以规避大多数东西。 仅当您只想授予特定程序访问权限时它才会起作用。
匹配
要匹配一组用户,您可以使用关键字配置 SSH Match
。摘自sshd_config(5)
手册:
Match
...
The arguments to Match are one or more criteria-pattern pairs or the
single token All which matches all criteria. The available criteria
are User, Group, Host, LocalAddress, LocalPort, and Address. The
match patterns may consist of single entries or comma-separated
lists and may use the wildcard and negation operators described in
the PATTERNS section of ssh_config(5).
...
举几个例子:
Match User eva
匹配“eva”用户Match User stephen,maria
匹配“stephen”和“maria”用户Match Group wheel,adams,simpsons
匹配“wheel”、“adams”、“simpsons”组
如果您需要更多信息,手册里有很多内容sshd_config(5)
。
强制命令
通常,当您通过 SSH 连接时,您会获得用户的登录 shell,但可以配置 SSH 以强制执行某个命令。该命令对于任何 SSH 连接(包括 SFTP)都是强制的,因此您可以选择强制执行您想要的命令。
强制命令可以用ForceCommand
关键字配置。手册中写道
sshd_config(5)
:
ForceCommand
Forces the execution of the command specified by ForceCommand,
ignoring any command supplied by the client and ~/.ssh/rc if
present. The command is invoked by using the user's login shell
with the -c option. This applies to shell, command, or subsystem
execution. It is most useful inside a Match block. The command
originally supplied by the client is available in the
SSH_ORIGINAL_COMMAND environment variable. Specifying a command of
“internal-sftp” will force the use of an in-process sftp server that
requires no support files when used with ChrootDirectory. The
default is “none”.
因此,你可以使用 强制执行你想要的约束命令ForceCommand <your command>
。例如:
Match User kim
ForceCommand echo 'successful login man, congrats'
例子
在我授予 git 访问权限的情况下,我只需要用户有权访问git-shell
。这是为我的 git 用户禁用 SFTP 的部分,以及一些安全选项:
Match Group git
# have to do this instead of setting the login shell to `git-shell`,
# to disable SFTP
ForceCommand /usr/bin/git-shell -c "$SSH_ORIGINAL_COMMAND"
# disable stuff we don't need
AllowAgentForwarding no
AllowTcpForwarding no
AllowStreamLocalForwarding no
PermitOpen none
PermitTunnel no
PermitTTY no
X11Forwarding no