介绍
SFTP(安全文件传输协议)是一个强大且安全的解决方案,用于通过网络传输文件。本教程将指导你理解 SFTP,解决“权限被拒绝(Permission Denied)”错误,以及在你的 Linux 系统上解决 SFTP 权限问题。你将学习如何设置 SFTP 服务器,创建具有适当权限的用户,并诊断文件传输期间发生的常见权限问题。
在 Ubuntu 上设置 SFTP 服务器
SFTP(安全文件传输协议)提供了一种在系统之间安全传输文件的方法。与常规 FTP 不同,SFTP 在传输过程中对命令和数据进行加密,保护你的信息免受未经授权的访问。
在这一步中,我们将在 Ubuntu 系统上设置一个基本的 SFTP 服务器。
安装 OpenSSH 服务器
首先,让我们确保你的系统是最新的,并安装 OpenSSH 服务器,它包括 SFTP 功能:
sudo apt update
sudo apt install -y openssh-server
运行这些命令后,你应该看到类似如下的输出:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
openssh-server is already the newest version (1:8.9p1-3ubuntu0.1).
验证 SSH 服务状态
由于我们在 Docker 容器中,标准的 systemctl 命令将不起作用。让我们使用进程状态命令检查 SSH 服务是否正在运行:
ps aux | grep sshd
你应该看到输出表明 sshd 正在运行:
root 1234 0.0 0.1 12016 5604 ? Ss 10:20 0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
为 SFTP 创建一个测试用户
让我们创建一个专门用于测试 SFTP 功能的用户:
sudo adduser sftpuser
当提示时,输入一个简单的密码,例如 password123,你可以按 Enter 键跳过额外的用户信息字段。你应该看到类似如下的输出:
Adding user `sftpuser' ...
Adding new group `sftpuser' (1001) ...
Adding new user `sftpuser' (1001) with group `sftpuser' ...
Creating home directory `/home/sftpuser' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
为 SFTP 传输创建测试文件
现在,让我们在我们的主目录中创建一些测试文件,我们将使用它们进行 SFTP 传输:
cd ~/project
echo "This is a test file for SFTP transfers" > testfile.txt
echo "This file has different permissions" > restrictedfile.txt
让我们验证文件是否已正确创建:
ls -l testfile.txt restrictedfile.txt
你应该看到类似如下的输出:
-rw-rw-r-- 1 labex labex 37 Sep 28 10:30 restrictedfile.txt
-rw-rw-r-- 1 labex labex 38 Sep 28 10:30 testfile.txt
默认情况下,这两个文件对所有者和组具有读写权限,对其他人具有只读权限。我们将在接下来的步骤中尝试更改这些权限。
理解文件权限及其对 SFTP 的影响
在我们探索 SFTP 权限问题之前,让我们先了解 Linux 文件权限系统及其如何影响 SFTP 操作。
Linux 文件权限基础
在 Linux 中,每个文件和目录都有三种类型的权限:
- 读取(r):允许查看文件内容或列出目录内容
- 写入(w):允许修改文件或在目录中创建/删除文件
- 执行(x):允许执行文件或访问目录
这些权限被分配给三个用户类别:
- 所有者:创建文件的用户
- 组:分配给文件的组
- 其他人:其他所有人
查看当前权限
让我们检查测试文件的当前权限:
ls -l ~/project/testfile.txt ~/project/restrictedfile.txt
你将看到类似如下的输出:
-rw-rw-r-- 1 labex labex 38 Sep 28 10:30 /home/labex/project/testfile.txt
-rw-rw-r-- 1 labex labex 37 Sep 28 10:30 /home/labex/project/restrictedfile.txt
权限字符串 -rw-rw-r-- 可以分解为:
- 第一个字符
-表示一个常规文件(对于目录将是d) - 接下来三个字符
rw-显示所有者权限(读取、写入、无执行) - 接下来三个字符
rw-显示组权限(读取、写入、无执行) - 最后三个字符
r--显示其他人的权限(仅读取)
修改文件权限
让我们修改文件的权限,以创建可能导致 SFTP 中出现“权限被拒绝”错误的场景:
## 使 testfile.txt 可供所有人读取,但仅供所有者写入
chmod 644 ~/project/testfile.txt
## 使 restrictedfile.txt 仅供所有者访问
chmod 600 ~/project/restrictedfile.txt
现在,让我们验证更改:
ls -l ~/project/testfile.txt ~/project/restrictedfile.txt
你应该看到更新后的权限:
-rw-r--r-- 1 labex labex 38 Sep 28 10:30 /home/labex/project/testfile.txt
-rw------- 1 labex labex 37 Sep 28 10:30 /home/labex/project/restrictedfile.txt
设置用于 SFTP 测试的目录
让我们创建一个专门用于 SFTP 测试的目录:
mkdir -p ~/project/sftp_test
echo "This file is in the SFTP test directory" > ~/project/sftp_test/test_file.txt
chmod 755 ~/project/sftp_test
现在,让我们创建一个具有受限权限的目录:
mkdir -p ~/project/restricted_sftp
echo "This file is in the restricted directory" > ~/project/restricted_sftp/restricted_file.txt
chmod 700 ~/project/restricted_sftp
让我们验证目录权限:
ls -ld ~/project/sftp_test ~/project/restricted_sftp
你应该看到:
drwxr-xr-x 2 labex labex 4096 Sep 28 10:35 /home/labex/project/sftp_test
drwx------ 2 labex labex 4096 Sep 28 10:35 /home/labex/project/restricted_sftp
sftp_test 目录可以被任何人访问,而 restricted_sftp 目录只能被所有者(labex 用户)访问。
体验和诊断 SFTP 权限被拒绝错误
在这一步中,我们将连接到我们的 SFTP 服务器,并亲身体验权限被拒绝错误。这将帮助我们理解权限设置如何影响 SFTP 操作。
本地连接到 SFTP 服务器
由于我们在本地环境中工作,我们可以使用 localhost 地址连接到我们的 SFTP 服务器。让我们使用我们之前创建的 sftpuser 进行连接:
sftp sftpuser@localhost
当提示输入密码时,输入你为 sftpuser 帐户设置的密码(例如,password123)。如果连接成功,你将看到类似以下的提示:
Connected to localhost.
sftp>
如果你遇到连接问题,可能是因为 SSH 服务在容器中没有正确运行。你可以尝试使用 exit 退出,并使用理论示例继续执行后续步骤。
基本 SFTP 命令
让我们探索一些基本的 SFTP 命令:
- 查看远程服务器上的当前目录:
sftp> pwd
Remote working directory: /home/sftpuser
- 列出当前目录中的文件:
sftp> ls
- 导航到不同的目录:
sftp> cd /tmp
sftp> pwd
Remote working directory: /tmp
- 返回你的主目录:
sftp> cd
sftp> pwd
Remote working directory: /home/sftpuser
尝试访问具有不同权限的文件
现在,让我们尝试从 SFTP 会话访问我们的测试文件:
- 尝试从我们的项目目录获取一个文件:
sftp> get /home/labex/project/testfile.txt
Fetching /home/labex/project/testfile.txt to testfile.txt
Permission denied
你将注意到一个“权限被拒绝”错误。这是因为 sftpuser 没有权限访问 labex 用户主目录中的文件。
退出 SFTP 会话
让我们退出 SFTP 会话以继续:
sftp> exit
理解权限被拒绝错误
SFTP 中出现“权限被拒绝”错误有几个常见原因:
- 文件权限:用户没有对文件的读/写访问权限
- 目录权限:用户无法访问包含文件的目录
- 所有权问题:文件/目录属于不同的用户或组
- 路径遍历限制:SFTP 配置可能将用户限制在某些目录中
让我们使我们的一个测试文件可供我们的 SFTP 用户访问:
## 创建一个可以被其他人访问的目录
mkdir -p /tmp/shared
echo "This is a shared file for SFTP testing" > /tmp/shared/shared_file.txt
chmod 777 /tmp/shared
chmod 666 /tmp/shared/shared_file.txt
现在,重新连接到 SFTP 并尝试访问此文件:
sftp sftpuser@localhost
连接后,尝试:
sftp> get /tmp/shared/shared_file.txt
Fetching /tmp/shared/shared_file.txt to shared_file.txt
/tmp/shared/shared_file.txt 100% 36 1.0KB/s 00:00
这应该有效,因为我们已经向所有人授予了对目录和文件的读/写权限。
再次退出 SFTP 会话:
sftp> exit
使用调试模式的 SFTP
为了获得更多关于权限错误的信息,你可以在调试模式下使用 SFTP:
sftp -v sftpuser@localhost
详细输出将向你显示有关连接和发生的任何错误的详细信息:
debug1: Sending subsystem: sftp
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2412, received 2876 bytes, in 0.1 seconds
Bytes per second: sent 30074.7, received 35857.2
debug1: Exit status 0
解决 SFTP 权限被拒绝错误
现在我们了解了权限如何影响 SFTP 访问,让我们学习如何解决常见的权限被拒绝错误。
解决方案 1:调整文件和目录权限
解决权限问题的最直接方法是调整文件和目录权限。让我们创建一个新的测试用例:
## 创建一个具有限制性权限的新测试文件
echo "This file has restricted permissions" > ~/project/restricted_access.txt
chmod 600 ~/project/restricted_access.txt
检查当前权限:
ls -l ~/project/restricted_access.txt
输出:
-rw------- 1 labex labex 35 Sep 28 11:05 /home/labex/project/restricted_access.txt
现在,让我们通过更改其权限使该文件可供其他人访问:
chmod 644 ~/project/restricted_access.txt
ls -l ~/project/restricted_access.txt
输出:
-rw-r--r-- 1 labex labex 35 Sep 28 11:05 /home/labex/project/restricted_access.txt
使用这些权限(644),文件所有者(labex)可以读取和写入文件,而组成员和其他人只能读取它。
解决方案 2:更改文件所有权
另一种解决方案是将文件的所有权更改为匹配 SFTP 用户。让我们创建另一个测试文件:
echo "This file will be owned by sftpuser" > ~/project/ownership_test.txt
现在,让我们将所有权更改为我们的 SFTP 用户:
sudo chown sftpuser:sftpuser ~/project/ownership_test.txt
ls -l ~/project/ownership_test.txt
输出:
-rw-rw-r-- 1 sftpuser sftpuser 36 Sep 28 11:10 /home/labex/project/ownership_test.txt
现在,该文件由 sftpuser 拥有,sftpuser 可以读取和写入它。
解决方案 3:创建共享目录
SFTP 文件共享的一个常见解决方案是创建一个具有适当权限的目录,多个用户可以访问该目录:
## 创建一个具有适当权限的新共享目录
mkdir -p /tmp/sftp_shared
sudo chown labex:labex /tmp/sftp_shared
chmod 755 /tmp/sftp_shared
## 创建一个可供所有人写入的用于上传的子目录
mkdir -p /tmp/sftp_shared/uploads
chmod 777 /tmp/sftp_shared/uploads
## 在共享目录中创建一个示例文件
echo "This file is in the shared SFTP directory" > /tmp/sftp_shared/sample.txt
chmod 644 /tmp/sftp_shared/sample.txt
让我们验证我们的设置:
ls -la /tmp/sftp_shared/
输出:
total 12
drwxr-xr-x 3 labex labex 4096 Sep 28 11:15 .
drwxrwxrwt 4 root root 4096 Sep 28 11:15 ..
-rw-r--r-- 1 labex labex 39 Sep 28 11:15 sample.txt
drwxrwxrwx 2 labex labex 4096 Sep 28 11:15 uploads
通过此设置:
- 主目录可供所有人读取和执行,但仅可供所有者写入
- 上传子目录可供所有人写入(适用于 SFTP 上传)
- sample.txt 文件可供所有人读取,但仅可供所有者写入
此配置允许 SFTP 用户:
- 导航到共享目录
- 读取示例文件
- 将文件上传到上传目录
解决方案 4:使用 ACL 实现更精细的控制
访问控制列表(ACL,Access Control Lists)提供了更详细的权限管理。让我们安装必要的软件包并使用 ACL:
sudo apt install -y acl
现在,让我们创建一个文件并使用 ACL 设置特定的权限:
echo "This file uses ACLs for permissions" > ~/project/acl_test.txt
## 设置基本权限
chmod 640 ~/project/acl_test.txt
## 添加 sftpuser 的 ACL 权限
sudo setfacl -m u:sftpuser:r ~/project/acl_test.txt
## 查看 ACL 设置
getfacl ~/project/acl_test.txt
输出:
## file: /home/labex/project/acl_test.txt
## owner: labex
## group: labex
user::rw-
user:sftpuser:r--
group::r--
mask::r--
other::---
此 ACL 配置允许:
- 文件所有者(labex)读取和写入
- sftpuser 读取文件
- 组读取文件
- 其他人无权访问
SFTP 权限管理最佳实践
在最后一步中,我们将介绍一些管理 SFTP 权限和有效排除权限问题的最佳实践。
创建一个专用的 SFTP 用户组
为 SFTP 用户创建一个专用组是一个好习惯:
sudo groupadd sftp_users
sudo usermod -a -G sftp_users sftpuser
验证用户是否已添加到组中:
groups sftpuser
输出:
sftpuser : sftpuser sftp_users
设置一个组管理的目录
现在,让我们创建一个由 sftp_users 组管理的目录:
## 为 SFTP 组创建一个新目录
sudo mkdir -p /tmp/sftp_group_shared
sudo chown labex:sftp_users /tmp/sftp_group_shared
sudo chmod 770 /tmp/sftp_group_shared
## 设置 SGID 位以确保新文件继承该组
sudo chmod g+s /tmp/sftp_group_shared
## 在此目录中创建一个测试文件
echo "This file is in the SFTP group directory" > /tmp/sftp_group_shared/group_file.txt
让我们验证权限:
ls -la /tmp/sftp_group_shared/
输出:
total 12
drwxrws--- 2 labex sftp_users 4096 Sep 28 11:25 .
drwxrwxrwt 5 root root 4096 Sep 28 11:25 ..
-rw-rw-r-- 1 labex sftp_users 42 Sep 28 11:25 group_file.txt
组权限中的 s 表示设置了 SGID 位,这意味着在此目录中创建的新文件将继承 sftp_users 组。
SFTP 权限的常见故障排除命令
在排除 SFTP 权限问题时,这些命令特别有用:
- 检查文件权限:
ls -la /path/to/file
- 检查用户组:
groups username
- 检查当前用户和组 ID:
id
- 查看 SFTP 服务器日志:
## 在生产系统中,你将检查系统日志
## 对于我们的实验环境,我们可以模拟查看日志
grep "sshd" /var/log/auth.log | tail
- 从命令行测试文件访问:
sudo -u sftpuser cat /path/to/file
权限被拒绝错误决策树
当你遇到 SFTP 中的权限被拒绝错误时,请遵循此决策树:
SFTP 用户可以访问父目录吗?
- 使用以下命令检查:
sudo -u sftpuser ls -la /path/to/directory/ - 使用以下命令修复:
chmod o+x /path/to/directory/
- 使用以下命令检查:
SFTP 用户可以读取文件吗?
- 使用以下命令检查:
sudo -u sftpuser cat /path/to/file - 使用以下命令修复:
chmod o+r /path/to/file或setfacl -m u:sftpuser:r /path/to/file
- 使用以下命令检查:
SFTP 用户可以写入文件或目录吗?
- 使用以下命令检查:
sudo -u sftpuser touch /path/to/directory/test_file - 使用以下命令修复:
chmod o+w /path/to/directory/或setfacl -m u:sftpuser:w /path/to/directory/
- 使用以下命令检查:
创建一个用于 SFTP 权限的测试脚本
让我们创建一个简单的测试脚本,用于检查 SFTP 用户是否可以访问特定的文件和目录:
cat > ~/project/check_sftp_permissions.sh << 'EOF'
#!/bin/bash
USER="sftpuser"
echo "Testing SFTP permissions for user: $USER"
echo "-------------------------------------------"
## Test directories
for DIR in /tmp/shared /tmp/sftp_shared /tmp/sftp_group_shared /home/labex/project; do
echo -n "Can $USER access $DIR? "
if sudo -u $USER ls -la $DIR &>/dev/null; then
echo "YES"
else
echo "NO"
fi
done
## Test files
for FILE in /tmp/shared/shared_file.txt /tmp/sftp_shared/sample.txt /home/labex/project/testfile.txt; do
echo -n "Can $USER read $FILE? "
if sudo -u $USER cat $FILE &>/dev/null; then
echo "YES"
else
echo "NO"
fi
done
echo "-------------------------------------------"
echo "Testing complete!"
EOF
chmod +x ~/project/check_sftp_permissions.sh
现在运行测试脚本:
sudo ~/project/check_sftp_permissions.sh
你应该看到输出,指示 SFTP 用户可以访问哪些目录和文件。这有助于你快速识别权限问题。
管理 SFTP 权限的最终提示
- 使用最小权限原则:仅授予必要的最低权限
- 定期审核权限:使用
find等工具来识别具有不适当权限的文件 - 记录你的权限结构:跟踪哪些用户和组有权访问哪些目录
- 考虑使用 SFTP chroot jail(chroot 监狱):对于生产环境,将用户限制在特定目录中
- 从用户的角度进行测试:始终通过以实际 SFTP 用户的身份进行测试来验证权限
总结
在本教程中,你已经学习了如何设置 SFTP 服务器,创建具有适当权限的用户,以及排除常见的权限被拒绝错误。你获得了以下方面的实践经验:
- 在 Ubuntu 上安装和配置 SFTP 服务器
- 了解 Linux 文件权限及其对 SFTP 访问的影响
- 体验和诊断权限被拒绝错误
- 实施各种解决方案来解决权限问题
- 应用 SFTP 权限管理的最佳实践
这些技能将帮助你在安全的环境中有效管理文件传输,同时最大限度地减少与权限相关的问题。请记住,适当的权限管理对于维护安全但功能齐全的 SFTP 服务器至关重要,需要在安全需求和用户访问需求之间取得平衡。



