如何在 Ubuntu 16.04 上启用无 Shell 访问的 SFTP
介绍
FTP(文件传输协议),尽管现代 FTP 客户端广泛支持它。
默认情况下,SFTP 可用,无需在所有启用 SSH 访问的服务器上进行额外配置。它安全且易于使用,但有一个缺点:在标准配置中,SSH 服务器向所有在系统上拥有帐户的用户授予文件传输访问权限和终端 shell 访问权限。
在某些情况下,您可能希望只允许某些用户进行文件传输而不允许 SSH 访问。在本教程中,我们将设置 SSH 守护程序以将 SFTP 访问限制为一个目录,并且不允许每个用户进行 SSH 访问。
先决条件
要学习本教程,您需要:
- 使用此初始服务器设置教程设置的一台 Ubuntu 16.04 服务器,包括 sudo 非根用户和防火墙。
第 1 步 — 创建新用户
首先,创建一个新用户,该用户将仅被授予对服务器的文件传输访问权限。在这里,我们使用用户名 sammyfiles,但您可以使用任何您喜欢的用户名。
- sudo adduser sammyfiles
系统将提示您为帐户创建密码,然后是有关用户的一些信息。用户信息是可选的,因此您可以按 ENTER
将这些字段留空。
您现在已经创建了一个新用户,该用户将被授予访问受限目录的权限。在下一步中,我们将创建文件传输目录并设置必要的权限。
第 2 步 — 创建文件传输目录
为了限制SFTP访问一个目录,我们首先要确保该目录符合SSH服务器的权限要求,这是非常有讲究的。
具体来说,文件系统树中的目录本身和它上面的所有目录必须由 root 拥有并且不能被任何其他人写入。因此,不可能简单地限制对用户主目录的访问,因为主目录归用户所有,而不是 root。
注意:某些版本的 OpenSSH 对目录结构和所有权没有如此严格的要求,但大多数现代 Linux 发行版(包括 Ubuntu 16.04)都有。
有多种方法可以解决此所有权问题。在本教程中,我们将创建并使用 /var/sftp/uploads
作为目标上传目录。 /var/sftp
将归 root 所有,其他用户不可写;子目录 /var/sftp/uploads
将归 sammyfiles 所有,这样用户就可以向其中上传文件。
首先,创建目录。
- sudo mkdir -p /var/sftp/uploads
将 /var/sftp
的所有者设置为 root。
- sudo chown root:root /var/sftp
授予root对同一目录的写权限,而给其他用户只有读和执行权限。
- sudo chmod 755 /var/sftp
将 uploads
目录的所有权更改为 sammyfiles。
- sudo chown sammyfiles:sammyfiles /var/sftp/uploads
现在目录结构已经到位,我们可以配置 SSH 服务器本身。
第 3 步 — 限制对一个目录的访问
在此步骤中,我们将修改 SSH 服务器配置以禁止终端访问 sammyfiles 但允许文件传输访问。
使用 nano
或您喜欢的文本编辑器打开 SSH 服务器配置文件。
- sudo nano /etc/ssh/sshd_config
滚动到文件的最底部并附加以下配置片段:
. . .
Match User sammyfiles
ForceCommand internal-sftp
PasswordAuthentication yes
ChrootDirectory /var/sftp
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
然后保存并关闭文件。
以下是每个指令的作用:
Match User
告诉 SSH 服务器仅将以下命令应用于指定的用户。在这里,我们指定 sammyfiles。ForceCommand internal-sftp
强制 SSH 服务器在登录时运行 SFTP 服务器,不允许 shell 访问。PasswordAuthentication yes
允许对此用户进行密码验证。ChrootDirectory /var/sftp/
确保不允许用户访问/var/sftp
目录之外的任何内容。您可以在此 chroot 教程中了解有关 chroot 的更多信息。AllowAgentForwarding 否
,AllowTcpForwarding 否
。X11Forwarding no
为该用户禁用端口转发、隧道和 X11 转发。
这组命令以 Match User
开头,也可以为不同的用户复制和重复。确保相应地修改 Match User
行中的用户名。
注意:您可以省略 PasswordAuthentication yes
行,而是设置 SSH 密钥访问以提高安全性。按照 SSH Essentials: Working with SSH Servers, Clients, and Keys 教程的 Copying your Public SSH Key 部分进行操作。确保在禁用用户的 shell 访问之前执行此操作。
在下一步中,我们将通过密码访问在本地通过 SSH 测试配置,但如果您设置了 SSH 密钥,则需要使用用户的密钥对访问计算机。
要应用配置更改,请重新启动服务。
- sudo systemctl restart sshd
您现在已将 SSH 服务器配置为限制对 sammyfiles 文件传输的访问。最后一步是测试配置以确保其按预期工作。
第 4 步 — 验证配置
让我们确保我们的新 sammyfiles 用户只能传输文件。
使用正常的 shell 访问以 sammyfiles 身份登录服务器应该不再可能了。让我们试试看:
- ssh sammyfiles@localhost
在返回到原始提示之前,您会看到以下消息:
Error messageThis service allows sftp connections only.
Connection to localhost closed.
这意味着 sammyfiles 无法再使用 SSH 访问服务器 shell。
接下来我们来验证一下用户是否可以成功访问SFTP进行文件传输。
- sftp sammyfiles@localhost
此命令不会显示错误消息,而是会显示带有交互式提示的成功登录消息。
SFTP promptConnected to localhost.
sftp>
您可以在提示中使用 ls
列出目录内容:
- ls
这将显示在上一步中创建的 uploads
目录,并返回到 sftp>
提示符。
SFTP file list outputuploads
要验证用户确实被限制在这个目录下,不能访问它上面的任何目录,你可以尝试将目录更改到它上面的目录。
- cd ..
该命令不会报错,但像以前一样列出目录内容将显示没有任何变化,证明用户无法切换到父目录。
您现在已验证受限配置是否按预期工作。新创建的 sammyfiles 用户只能使用 SFTP 协议访问服务器进行文件传输,无法访问完整的 shell。
结论
您已限制用户只能通过 SFTP 访问服务器上的单个目录,而没有完整的 shell 访问权限。虽然本教程为简洁起见仅使用一个目录和一个用户,但您可以将此示例扩展到多个用户和多个目录。
SSH 服务器允许更复杂的配置方案,包括一次限制对组或多个用户的访问或限制对某些 IP 地址的访问。您可以在 SSH 故障排除系列中找到其他配置选项的示例和可能指令的解释。