我为这个问题find了一个可行的答案,其中大部分答案都包含了为什么不这样做的build议。 但是,这是情况,什么使得它是必要的:
我有一个控制台应用程序,并且在每个用户的.profile中,都有一个用于应用程序的启动命令,并且在启动它的命令之后,有一个“退出”命令,将它们从系统中注销。 我只希望他们能够通过它提供的接口访问这个控制台应用程序。 启动时,应用程序向用户显示可以通过应用程序访问的客户端列表,每个客户端都有自己的数据目录。 用户只能访问他们需要访问的客户端。
现在问题是:如果我给用户SSH访问,他们也将能够使用SFTP客户端login,这将使他们能够直接访问应用程序的数据目录,这是非常不可取的,因为这也会给他们访问他们不应该访问的数据目录。
当使用telnet / FTP组合时,这是一件很简单的事情,但是现在我想让用户能够从互联网上的任何地方访问,我一直无法find一种方法来closures他们的SFTP,而仍然允许他们访问他们可以运行应用程序的shell。
如果不是很明显,下面的答案不能作为防止任何人通过shell访问服务器来使用SFTP的安全方法。 这只是一个解释如何禁用外部可见性的答案。 有关用户级别安全性的讨论,请参阅@cpast和@Aleksi Torhamo的答案。 如果安全是你的重点,这个答案是不正确的。 如果简单的服务visibiliy是你的重点,那么这是你的答案。
我们现在继续原来的答案:
在sshd_config中注释掉sftp支持(当然还有重启sshd
):
#Subsystem sftp /usr/lib/openssh/sftp-server
正如其他人所说的那样,禁用sftp
并不是任何地方都足够接近 – 具有不受限制ssh
访问权的用户可以查看其帐户有权查看的任何文件,可以修改他们有权修改的任何内容,并且可以轻松地下载任何可以读取的内容自己的机器。 阻止他们这样做的唯一方法是实际限制他们的访问。 依赖.profile
来限制用户也是不理想的,因为这不是它的用途(编辑:正如Aleksi在他的回答中提到的那样,绕过.profile
事实上是微不足道的;关于.profile
的事情是为了方便,而不是安全性,所以它并不是要限制用户的使用,而是使用为了安全而devise的东西,比如下面的东西来提供安全性)。
有两种基本的方法可以做到这一点:你可以通过文件权限来限制他们,或强制他们只执行你的控制台应用程序。 第二种方法更好:将应该被限制到控制台应用程序的用户分配给一个组(例如customers
); 然后在sshd_config
中添加以下几行:
Match Group customers ForceCommand /path/to/app
这样做是为了让该组中的用户的所有连接打开控制台应用程序; 他们不能启动其他任何东西,包括sftp
服务器工具。 这也阻止了他们对系统做任何事情 ,和.profile
不同的是,它使用SSH服务器本身( .profile
在shell中限制了它们, ForceCommand
也阻止了其他不涉及启动shell的事情)。 也不像.profile
,它被devise成一个安全的东西; 它是专门阻止恶意用户逃避它。
(可能较差)替代scheme将涉及创build一个新用户来运行控制台应用程序。 然后,您将数据目录限制为该用户,设置该用户拥有的控制台应用程序,并在程序上设置u+s
。 这是setuid
位; 这意味着运行控制台程序的人可以使用程序所有者的权限。 这样,用户本身不能访问目录,只能通过程序获取。 但是,您应该只是使用ForceCommand
,因为这限制了所有访问“只运行这个程序”。
不要试图用.profile
来做这件事,因为它不提供任何安全性,并且完全没有限制!
放在.profile
中并不重要,因为您可以通过简单地在ssh命令行上运行一个命令来绕过它,如下所示: ssh user@host command
。 您仍然可以通过执行ssh -t user@host bash
来获得正常的shell访问权限。
像另一个答案中提到的那样禁用sftp子系统根本没有任何帮助。 子系统实质上只是命令的别名,通过执行sftp -s /path/to/sftp-executable user@host
,您仍然可以正常使用sftp。
和cpast一样,一些评论者说过,你应该使用适当的机制来限制访问。 那是,
sshd_config
使用ForceCommand
.ssh/authorized_keys
使用无密码login和command="..."
笔记:
command="..."
仅适用于一个密钥,因此它不会限制用户使用密码或其他密钥的sshlogin AllowTcpForwarding
等在sshd_config
no-port-forwarding
等.ssh/authorized_keys
script -c 'command-the-user-wanted-to-run'
ForceCommand
和command="..."
都通过用户的shell运行命令,所以如果用户的shell设置为eg,那么它们不起作用。 /bin/false
或/sbin/nologin
免责声明:我不是这方面的专家,所以虽然我可以说这个.profile
东西是不安全的,但是我不能保证和其他的方法没有什么关系,不了解。 据我所知,他们是安全的,但我不会成为互联网上第一个犯错的人。
可以启用SSH并禁用全局和每个用户/组的SFTP。
我个人需要这个,因为我想通过SSH访问一些git仓库,我喜欢禁用不需要的系统。 在这种情况下,SFTP是不需要的。
您可以通过几种方法禁用所有用户的SFTP。
SSH使用的SFTP守护进程可以通过Subsystem
关键字进行configuration。 从sshd_config(5)
手册:
Subsystem Configures an external subsystem (eg 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”子系统configuration为/bin/false
:
Subsystem sftp /bin/false
当某些东西试图通过SFTPlogin时,SSH守护进程会尝试产生“sftp守护进程” /bin/false
。 /bin/false
程序只做一件事,那就是返回一个错误代码。 SFTP连接尝试被有效拒绝。
也可以禁用每个用户,组或其他几个标准的SFTP。
如果你想让你的用户得到一个正常的shell提示符,这是行不通的。 这也不是有意义的,因为如果你有shell的话,你可以绕过大部分的东西。 只有当你只想访问一个特定的程序时,它才会起作用。
要匹配一组用户,您可以使用Match
关键字configurationSSH。 从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
匹配“轮”,“亚当斯”,“辛普森”组 如果您想了解更多信息,请参见sshd_config(5)
手册中的负载。
通常,当你通过SSH连接时,你会得到用户的loginshell,但是SSH可以被configuration为强制执行某个命令。 该命令被强制用于任何SSH连接,包括SFTP,因此您可以select强制执行所需的命令。
强制命令可以使用ForceCommand
关键字进行configuration。 从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