下面我将提供一个详细、分步的指南,使用最常见和推荐的方法:通过 OpenSSH 服务器来实现,这种方法无需额外安装软件,配置简单,且与系统用户账户集成。

我们将完成以下步骤:
- 检查环境:确认系统已安装 OpenSSH 服务器。
- 创建 SFTP 专用用户:为了安全,我们不希望所有用户都能通过 SFTP 登录,因此创建一个或多个专用的 SFTP 用户。
- 配置 SSH 服务:修改 SSH 配置文件,限制用户的访问方式(只允许 SFTP,禁止 SSH 登录)。
- 设置目录权限:这是最关键的一步,确保用户只能访问其指定的目录,而不能“越狱”到系统其他地方。
- 启动/重启服务并测试:应用配置并验证 SFTP 服务器是否工作正常。
第一步:检查并安装 OpenSSH 服务器
大多数 Linux 发行版默认已安装 OpenSSH 服务器,如果没有,请安装它。
对于 Debian / Ubuntu 系统
# 更新软件包列表 sudo apt update # 安装 openssh-server sudo apt install openssh-server
对于 CentOS / RHEL / Rocky Linux / AlmaLinux 系统
# 安装 openssh-server sudo yum install openssh-server # 或者使用 dnf (新版本) sudo dnf install openssh-server
安装完成后,SSH 服务通常会自动启动,你可以检查其状态:
sudo systemctl status sshd # 或者 sudo systemctl status ssh
如果未运行,请启动它:

sudo systemctl start sshd # 并设置为开机自启 sudo systemctl enable sshd
第二步:创建 SFTP 专用用户
假设我们要创建一个名为 sftpuser 的用户,并为其设置一个主目录 /home/sftpuser/data。
-
创建用户和设置密码
# 创建用户,-m 选项会自动创建主目录 /home/sftpuser # -d /home/sftpuser/data 指定主目录为 /home/sftpuser/data sudo useradd -m -d /home/sftpuser/data -s /bin/false sftpuser # 为用户设置密码 sudo passwd sftpuser
-s /bin/false:非常重要!这会禁止该用户通过 SSH 登录系统(/bin/false是一个空壳,不提供交互式 shell),只允许进行 SFTP 文件传输。
-
(可选)创建多个用户 如果需要为多个用户或不同部门创建独立的 SFTP 空间,可以重复上述步骤,为每个用户创建不同的主目录。
第三步:配置 SSH 服务(核心步骤)
这是实现“沙盒”目录的关键,我们将通过修改 SSH 配置文件,为 sftpuser 用户指定一个特殊的“强制命令”(ForceCommand),使其登录后自动进入 SFTP 子系统,并且通过 ChrootDirectory 限制其根目录。

-
打开 SSH 配置文件
sudo nano /etc/ssh/sshd_config
-
添加或修改 SFTP 用户配置 在文件末尾添加以下内容。
Match User指令允许我们对特定用户应用不同的规则。# 为 sftpuser 用户配置 SFTP 访问 Match User sftpuser # 强制执行内部-sftp 子系统,禁止执行其他命令 ForceCommand internal-sftp # 将用户限制在其主目录中 ChrootDirectory /home/sftpuser # 允许使用密钥认证和密码认证 # PasswordAuthentication yes # PubkeyAuthentication yes # 重要:ChrootDirectory 需要目录及其所有父目录的权限正确 # 以下设置是为了让 chroot 正常工作 # ChrootDirectory 的目录本身不能被用户写入,但其子目录可以 # 所以我们需要在下面手动创建 data 目录并设置权限配置解释:
Match User sftpuser:这个块内的所有配置只对sftpuser用户生效。ForceCommand internal-sftp:强制用户登录后只能进入 SFTP 会话,无法执行ls,cd等 shell 命令,大大提高了安全性。ChrootDirectory /home/sftpuser:这是“牢笼”的起点,用户登录后, 目录就会指向/home/sftpuser,他们无法访问到这个目录以外的任何文件。
-
(可选)禁用密码登录(推荐) 为了更高的安全性,建议在全局禁用密码登录,只允许密钥对认证,找到以下行并确保它们被取消注释且设置为
no:# 在文件顶部找到这行 PasswordAuthentication no
在
Match User sftpuser块中,为了方便测试,你可以临时开启PasswordAuthentication yes,生产环境强烈建议使用密钥认证。 -
保存并关闭文件 (在 nano 中是
Ctrl+X, 然后按Y, 回车)。
第四步:设置目录权限(至关重要!)
ChrootDirectory 要求是 Linux 文件系统安全的一个特性,用户不能“chroot”到一个他们拥有写权限的目录中,我们需要精心设置目录结构。
-
创建用户数据目录 用户的主目录
/home/sftpuser需要归root所有,并且用户对其只有读和执行权限,而用户实际可以写入的子目录/home/sftpuser/data需要归sftpuser所有。# 1. 确保 sftpuser 用户存在 # sudo useradd -m -d /home/sftpuser/data -s /bin/false sftpuser # 2. 将 /home/sftpuser 目录的所有者改为 root sudo chown root:root /home/sftpuser # 3. 设置 /home/sftpuser 目录的权限为 755 (rwxr-xr-x) sudo chmod 755 /home/sftpuser # 4. 创建用户实际可以操作的 data 目录 sudo mkdir -p /home/sftpuser/data # 5. 将 data 目录的所有者改为 sftpuser sudo chown sftpuser:sftpuser /home/sftpuser/data # 6. 设置 data 目录的权限为 755 (rwxr-xr-x) # 用户需要 rx 权限进入目录,w 权限在其中创建文件 sudo chmod 755 /home/sftpuser/data
权限逻辑总结:
/home/sftpuser(root:root, 755): 用户可以进入 (x) 和查看内容 (r),但不能修改。/home/sftpuser/data(sftpuser:sftpuser, 755): 用户可以进入 (x)、查看 (r) 和写入 (w) 文件。
-
设置 SELinux(如果你的系统启用了 SELinux) 如果你的系统是 CentOS, RHEL, Fedora 等默认启用 SELinux 的发行版,上述权限设置还不够,你需要 SELinux 策略来允许
chroot。# 检查 SELinux 状态 sestatus # 如果是 Enforcing 模式,需要执行以下命令 # 这条命令会自动设置正确的 SELinux 上下文 semanage fcontext -a -t ssh_home_t "/home/sftpuser/data(/.*)?" restorecon -Rv /home/sftpuser/data
第五步:重启 SSH 服务并测试
-
重启 SSH 服务 让新的配置生效。
sudo systemctl restart sshd
-
测试 SFTP 登录 使用
sftp命令进行测试,请在你的另一台电脑上,或者使用sftpuser本身的账户进行测试。sftp sftpuser@<你的服务器IP地址>
sftp sftpuser@192.168.1.100
系统会提示你输入密码,登录成功后,你会看到
sftp>提示符。 -
验证沙盒环境 在
sftp>提示符下,执行以下命令来验证用户是否被限制在正确的目录中:sftp> pwd Remote working directory: /home/sftpuser sftp> ls data sftp> cd / sftp> ls sftp: Permission denied
你会看到,
pwd显示的根目录是/home/sftpuser,而尝试切换到系统根目录 会被拒绝,这证明了沙盒环境已经生效。你可以尝试在
data目录中上传和下载文件:sftp> cd data sftp> put /path/to/local_file.txt sftp> get remote_file.txt sftp> exit
常见问题与排错
-
chroot failed: could not chroot to directory /home/sftpuser:- 原因:几乎总是权限问题,请仔细检查第三步和第四步的目录权限设置。
ChrootDirectory本身(/home/sftpuser)必须不能被用户写入。 - 解决:确保
/home/sftpuser是root:root所有,权限是755。/home/sftpuser/data是sftpuser:sftpuser所有,权限是755。
- 原因:几乎总是权限问题,请仔细检查第三步和第四步的目录权限设置。
-
Received message too long错误:- 原因:用户的主目录路径或
ForceCommand过长,超过了 SSH 协议的限制。 - 解决:尽量缩短用户名和主目录的路径。
- 原因:用户的主目录路径或
-
Subsystem request failed错误:- 原因:
sshd_config文件中有语法错误。 - 解决:检查
/etc/ssh/sshd_config文件,确保没有拼写错误或格式问题,可以使用sudo sshd -t命令来测试配置文件语法是否正确。
- 原因:
-
用户无法登录,提示
Permission denied (publickey,password).:- 原因:
- 你在全局设置了
PasswordAuthentication no,但没有为该用户单独开启。 - 用户密码错误。
- SELinux 策略阻止了登录(如果已启用)。
- 你在全局设置了
- 解决:检查
sshd_config文件中的PasswordAuthentication设置,或者临时开启它进行测试。
- 原因:
通过以上步骤,你就成功搭建了一个安全、隔离的 SFTP 服务器。
