介绍
SFTP(安全文件传输协议)是一个强大且安全的解决方案,用于通过网络传输文件。本教程将指导你理解 SFTP,解决“权限被拒绝(Permission Denied)”错误,以及在你的 Linux 系统上解决 SFTP 权限问题。你将学习如何设置 SFTP 服务器,创建具有适当权限的用户,并诊断文件传输期间发生的常见权限问题。
SFTP(安全文件传输协议)是一个强大且安全的解决方案,用于通过网络传输文件。本教程将指导你理解 SFTP,解决“权限被拒绝(Permission Denied)”错误,以及在你的 Linux 系统上解决 SFTP 权限问题。你将学习如何设置 SFTP 服务器,创建具有适当权限的用户,并诊断文件传输期间发生的常见权限问题。
SFTP(安全文件传输协议)提供了一种在系统之间安全传输文件的方法。与常规 FTP 不同,SFTP 在传输过程中对命令和数据进行加密,保护你的信息免受未经授权的访问。
在这一步中,我们将在 Ubuntu 系统上设置一个基本的 SFTP 服务器。
首先,让我们确保你的系统是最新的,并安装 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).
由于我们在 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 功能的用户:
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 传输:
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 权限问题之前,让我们先了解 Linux 文件权限系统及其如何影响 SFTP 操作。
在 Linux 中,每个文件和目录都有三种类型的权限:
这些权限被分配给三个用户类别:
让我们检查测试文件的当前权限:
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 测试的目录:
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 操作。
由于我们在本地环境中工作,我们可以使用 localhost 地址连接到我们的 SFTP 服务器。让我们使用我们之前创建的 sftpuser 进行连接:
sftp sftpuser@localhost
当提示输入密码时,输入你为 sftpuser 帐户设置的密码(例如,password123)。如果连接成功,你将看到类似以下的提示:
Connected to localhost.
sftp>
如果你遇到连接问题,可能是因为 SSH 服务在容器中没有正确运行。你可以尝试使用 exit 退出,并使用理论示例继续执行后续步骤。
让我们探索一些基本的 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> exit
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 -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 访问,让我们学习如何解决常见的权限被拒绝错误。
解决权限问题的最直接方法是调整文件和目录权限。让我们创建一个新的测试用例:
## 创建一个具有限制性权限的新测试文件
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)可以读取和写入文件,而组成员和其他人只能读取它。
另一种解决方案是将文件的所有权更改为匹配 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 可以读取和写入它。
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 用户:
访问控制列表(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 配置允许:
在最后一步中,我们将介绍一些管理 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 权限问题时,这些命令特别有用:
ls -la /path/to/file
groups username
id
## 在生产系统中,你将检查系统日志
## 对于我们的实验环境,我们可以模拟查看日志
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/filechmod o+r /path/to/file 或 setfacl -m u:sftpuser:r /path/to/fileSFTP 用户可以写入文件或目录吗?
sudo -u sftpuser touch /path/to/directory/test_filechmod o+w /path/to/directory/ 或 setfacl -m u:sftpuser:w /path/to/directory/让我们创建一个简单的测试脚本,用于检查 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 用户可以访问哪些目录和文件。这有助于你快速识别权限问题。
find 等工具来识别具有不适当权限的文件在本教程中,你已经学习了如何设置 SFTP 服务器,创建具有适当权限的用户,以及排除常见的权限被拒绝错误。你获得了以下方面的实践经验:
这些技能将帮助你在安全的环境中有效管理文件传输,同时最大限度地减少与权限相关的问题。请记住,适当的权限管理对于维护安全但功能齐全的 SFTP 服务器至关重要,需要在安全需求和用户访问需求之间取得平衡。