如何在Ubuntu20.04上启用没有Shell访问的SFTP

来自菜鸟教程
跳转至:导航、​搜索

介绍

SFTP 代表 SSH File Transfer Protocol,是一种安全的文件传输方式机器之间使用加密的 SSH 连接。 虽然名称相似,但这是与 FTP 不同的协议(File Transfer Protocol),但 SFTP 得到广泛支持由现代 FTP 客户端。

默认情况下,SFTP 可用,无需在所有启用了 SSH 访问的服务器上进行额外配置。 尽管 SFTP 安全且使用起来相当简单,但 SFTP 的一个缺点是,在标准配置中,SSH 服务器向所有在系统上拥有帐户的用户授予文件传输访问权限和终端 shell 访问权限。 在许多情况下,对用户权限进行精细控制会更安全。 例如,您可能希望允许某些用户仅执行文件传输,但阻止他们通过 SSH 获得对服务器的终端访问权限。

在本教程中,您将设置 SSH 守护程序以限制对一个目录的 SFTP 访问,不允许每个用户进行 SSH 访问。

先决条件

要学习本教程,您需要访问 Ubuntu 20.04 服务器。 此服务器应该有一个具有 sudo 权限的非 root 用户,并且启用了防火墙。 如需有关设置的帮助,请遵循我们的 Ubuntu 20.04 初始服务器设置指南。

第 1 步 — 创建新用户

首先,创建一个新用户,该用户将仅被授予对服务器的文件传输访问权限。 在这里,我们使用用户名 sammyfiles,但您可以使用任何您喜欢的用户名:

sudo adduser sammyfiles

系统将提示您为该帐户创建密码,然后是有关用户的一些信息。 用户信息是可选的,因此您可以按 ENTER 将这些字段留空。

您现在已经创建了一个新用户,该用户将被授予访问受限目录的权限。 在下一步中,您将创建文件传输目录并设置必要的权限。

第 2 步 — 创建文件传输目录

为了限制 SFTP 访问一个目录,首先必须确保该目录符合 SSH 服务器的权限要求,这是非常特殊的。

具体来说,文件系统树中的目录本身和它之前的所有目录必须由 root 拥有,并且不能被其他任何人写入。 因此,不可能限制对用户主目录的访问,因为主目录归用户所有,而不是 root

注意: 有些版本的 OpenSSH 对目录结构和所有权没有这么严格的要求,但大多数现代 Linux 发行版(包括 Ubuntu 20.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

滚动到文件的最底部并添加以下配置片段:

/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 目录之外的任何内容。
  • AllowAgentForwarding noAllowTcpForwarding noX11Forwarding no 分别禁用端口转发、隧道和 X11 转发。 添加这些指令的目的是进一步限制该用户对服务器的访问。

这组命令以 Match User 开头,也可以为不同的用户复制和重复。 确保相应地修改 Match User 行中的用户名。

注意:您可以省略 PasswordAuthentication yes 行并设置 SSH 密钥访问以提高安全性。 按照 SSH 基础:使用 SSH 服务器、客户端和密钥 教程的 复制您的公共 SSH 密钥 部分来执行此操作。 确保在禁用用户的 shell 访问之前执行此操作。

在下一步中,我们将通过在本地使用密码访问 SSH 来测试配置,但如果您设置了 SSH 密钥,则需要使用用户的密钥对访问计算机。


添加这些行后,保存并关闭文件。 如果您使用的是 nano,您可以按 CTRL + X,然后按 Y,然后按 ENTER 来执行此操作。

要应用配置更改,请重新启动服务:

sudo systemctl restart sshd

您现在已将 SSH 服务器配置为仅限制 sammyfiles 对文件传输的访问。 最后一步是测试配置以确保它按预期工作。

第 4 步 — 验证配置

让我们确保我们的新 sammyfiles 用户只能传输文件。 如前所述,SFTP 用于在机器之间传输文件。 您可以通过测试本地计算机和服务器之间的传输来验证这是否有效。

首先,尝试以您在步骤 1 中创建的用户身份登录您的服务器。 由于您添加到 SSH 配置文件中的设置,这是不可能的:

ssh sammyfiles@your_server_ip

在返回原始提示之前,您将收到以下消息:

OutputThis service allows sftp connections only.
Connection to your_server_ip closed.

这意味着 sammyfiles 不能再使用 SSH 访问服务器 shell。

接下来,验证用户是否可以成功访问 SFTP 进行文件传输:

sftp sammyfiles@your_server_ip

此命令将生成带有交互式提示的成功登录消息,而不是错误消息:

OutputConnected to your_server_ip
sftp>

您可以在提示符中使用 ls 列出目录内容:

ls

这将显示在上一步中创建的 uploads 目录,并返回到 sftp> 提示符:

Outputuploads

要验证用户确实被限制在这个目录并且不能访问它之前的任何目录,您可以尝试将目录更改为上一个:

cd ..

该命令不会报错,但会像以前一样列出目录内容,没有变化,证明用户无法切换到父目录。

您现在已验证受限配置是否按预期工作。 新创建的 sammyfiles 用户只能使用 SFTP 协议访问服务器进行文件传输,无法访问完整的 shell。

结论

您已将用户限制为只能通过 SFTP 访问服务器上的单个目录,而没有完全的 shell 访问权限。 虽然本教程为简洁起见仅使用一个目录和一个用户,但您可以将此示例扩展到多个用户和多个目录。

SSH 服务器允许更复杂的配置方案,包括一次限制对组或多个用户的访问,甚至限制对某些 IP 地址的访问。 您可以在 OpenSSH Cookbook 中找到其他配置选项的示例和可能指令的解释。 如果您在使用 SSH 时遇到任何问题,可以使用此 SSH 疑难解答系列 进行调试和修复。