CentOS 8 上搭建SFTP服务
安装
在CentOS 8上搭建SFTP服务,可以通过OpenSSH来实现。以下是具体步骤:
1. 安装OpenSSH服务器
在CentOS 8中,通常已经安装了OpenSSH服务器。如果没有,可以通过以下命令安装:
sudo dnf install -y openssh-server
2. 启动并启用OpenSSH服务
确保OpenSSH服务正常运行,并设置为开机启动:
sudo systemctl start sshd
sudo systemctl enable sshd
可以通过以下命令检查服务状态:
sudo systemctl status sshd
3. 配置SFTP用户
为SFTP创建一个独立的用户,并指定一个目录作为用户的SFTP根目录。
创建用户组和目录
可以为SFTP用户创建一个专门的用户组和目录。例如创建一个/sftp
目录,并为所有SFTP用户设置该目录为根目录:
sudo mkdir -p /sftp
sudo groupadd sftpusers
创建SFTP用户
创建一个新用户,将其主目录指定为/sftp/[username]
,并将用户添加到SFTP
用户组中。例如:
sudo useradd -m -d /sftp/[username] -s /sbin/nologin -G sftpusers [username]
将[username]
替换为实际用户名。
为用户设置密码:
sudo passwd [username]
设置权限
设置/sftp
目录的权限,使其只能被root用户访问,并创建用户文件夹上传数据:
sudo chown root:root /sftp
sudo chmod 755 /sftp
sudo mkdir /sftp/[username]/uploads
sudo chown [username]:sftpusers /sftp/[username]/uploads
4. 配置OpenSSH以限制SFTP访问
编辑SSH配置文件 /etc/ssh/sshd_config
:
sudo vim /etc/ssh/sshd_config
在文件中添加以下内容以启用SFTP的chroot环境:
# 指定SFTP子系统
Subsystem sftp internal-sftp
# 配置SFTP用户组
Match Group sftpusers
ChrootDirectory /sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
ChrootDirectory /sftp/%u
:将用户限制在/sftp/[username]
目录中。ForceCommand internal-sftp
:强制用户使用SFTP而不是SSH shell。
5. 重启SSH服务
修改配置文件后,重启SSH服务以应用更改:
sudo systemctl restart sshd
6. 测试SFTP连接
可以使用SFTP客户端(如sftp
命令或WinSCP、FileZilla等)进行连接:
sftp [username]@[server_ip]
连接后,你应该只能访问指定的目录,无法浏览服务器上的其他文件。
注意事项
- 确保目录权限设置正确。
/sftp
目录必须由root
拥有,且权限为755
。 - 用户上传文件的目录,如
uploads
,需要将权限授予具体的SFTP用户,以确保其可以上传文件。
这样,你就成功在CentOS 8上配置了一个SFTP服务!
排查报错
重启ssh报错了:Job for sshd.service failed because the control process exited with error code. See “systemctl status sshd.service” and “journalctl -xe” for details.
sshd.service
重启失败的原因可能是SSH配置文件中的语法错误、不正确的权限设置,或其他配置问题。可以按照以下步骤排查问题:
1. 检查sshd
的状态
运行以下命令查看sshd
服务的状态,获取具体的错误信息:
sudo systemctl status sshd.service
状态信息会显示服务失败的原因或提示进一步排查的方向。
2. 查看日志
使用以下命令查看journalctl
日志中的详细信息,找到可能导致服务启动失败的具体原因:
sudo journalctl -xe
日志中通常会有更详细的错误信息,比如文件权限问题、配置参数错误等。
3. 检查SSH配置文件
SSH服务启动失败的常见原因是配置文件 /etc/ssh/sshd_config
中的错误。可以使用以下命令来检查该文件是否有语法问题:
sudo sshd -t
- 如果输出为空,说明配置文件语法无误。
- 如果有错误信息,SSH服务会指出出错的行数和错误类型。根据提示返回的行号修正配置文件。
4. 常见错误排查
以下是一些可能导致sshd
启动失败的常见原因及解决方法:
- 配置文件语法错误:检查
/etc/ssh/sshd_config
文件中的配置参数,确保格式正确。例如,参数和值之间需要空格。 - 权限问题:确保
/etc/ssh/
目录和sshd_config
文件的权限正确。通常建议权限设置如下:
sudo chmod 644 /etc/ssh/sshd_config
sudo chmod 700 /etc/ssh
- 端口被占用:如果修改了SSH监听的端口(如
Port 22
),请确认该端口没有被其他进程占用。可以用以下命令查看端口占用情况:
sudo lsof -i :<port-number>
如端口被占用,可以选择修改端口号,或停止占用端口的服务。
5. 重启sshd
服务
修改配置文件后,重新加载配置并尝试重启SSH服务:
sudo systemctl daemon-reload
sudo systemctl restart sshd
6. 测试
如果重启成功,可以通过以下命令检查SSH服务是否在运行:
sudo systemctl status sshd
如果服务成功启动,active (running)
表示SSH服务正在正常运行。
通过以上步骤,你应该能找到并解决sshd
服务启动失败的问题。如果问题依旧存在,可以提供具体的日志信息,我们可以进一步排查。
常见报错
系统中已经有了子系统的配置
例如:Subsystem sftp /usr/libexec/openssh/sftp-server
在配置SFTP时,Subsystem sftp /usr/libexec/openssh/sftp-server
是指定SFTP服务的默认配置路径。在某些Linux系统中(例如CentOS),该路径用于定义SFTP服务的执行文件,默认会加载SFTP功能。如果在配置SFTP时遇到问题,可以进行以下检查和调整:
1. 确认sshd_config
配置
确保在/etc/ssh/sshd_config
文件中只有一个Subsystem sftp
配置项。如果存在多个配置项,可能会导致冲突。通常只需保留以下内容:
Subsystem sftp /usr/libexec/openssh/sftp-server
2. 配置SFTP用户权限(可选)
如果需要将用户限制在特定目录中,可以使用以下方式指定SFTP用户组和访问限制:
Match Group sftpusers
ChrootDirectory /sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
其中:
ChrootDirectory /sftp/%u
:将用户限制在主目录/sftp/[username]
中。ForceCommand internal-sftp
:强制用户使用SFTP服务,而不是SSH shell。
3. 检查并重启SSH服务
保存配置后,检查配置文件的语法并重启SSH服务:
sudo sshd -t # 检查语法是否正确
sudo systemctl restart sshd
如果配置没有语法错误且服务成功重启,SFTP功能应该可以正常工作。
4. 测试SFTP连接
通过客户端(例如sftp
命令)连接服务器,验证SFTP是否可用:
sftp [username]@[server_ip]
这套配置应该能保证SFTP服务可用且具有一定的安全性。如有更多需求,可以继续根据用户组和权限配置进行精细化管理。
免密登陆失败
如果你的 sshd_config
中有以下配置:
PasswordAuthentication yes
ChallengeResponseAuthentication yes
这两个配置会允许密码认证和挑战响应认证(通常用于二次身份验证)。但是,PasswordAuthentication yes
可能与公钥认证冲突,因为 SSH 可能优先考虑密码认证或挑战响应认证,而忽略公钥认证。
解决方案:
- 禁用密码认证
为了强制使用公钥认证,你可以禁用密码认证。更改sshd_config
中的PasswordAuthentication
设置为no
,然后重启 SSH 服务。
编辑 sshd_config
:
sudo vi /etc/ssh/sshd_config
将以下行:
PasswordAuthentication yes
ChallengeResponseAuthentication yes
修改为:
PasswordAuthentication no
ChallengeResponseAuthentication no
这样就会禁用密码和挑战响应认证,强制使用公钥认证。
- 重启 SSH 服务
更改配置后,重启 SSH 服务以应用更改:
sudo systemctl restart sshd
检查其他配置项:
- **确保
**PubkeyAuthentication**
为 ****yes**
:确认在sshd_config
中启用了公钥认证。
PubkeyAuthentication yes
- 确保
**AuthorizedKeysFile**
设置正确:通常它应该是.ssh/authorized_keys
。
AuthorizedKeysFile .ssh/authorized_keys
测试公钥认证:
在客户端(比如 FileZilla 或命令行)尝试重新连接:
ssh -i ~/.ssh/id_rsa sftp0@[server_ip]
如果连接成功,说明公钥认证已经生效。
总结:
通过禁用密码认证和挑战响应认证,可以确保服务器只使用公钥认证,这会提高 SFTP 安全性并避免认证冲突。
client_loop: send disconnect: Broken pipe
client_loop: send disconnect: Broken pipe
错误通常发生在 SSH 会话中,表示连接已经被意外关闭。这可能是由于多个原因引起的,下面是一些常见的原因以及相应的解决方法:
1. 网络连接问题
- 这是最常见的原因之一,尤其是在网络不稳定的情况下,连接可能会断开。
- 解决方法: 确保网络连接稳定。你可以尝试通过其他网络(例如有线连接或不同的 Wi-Fi 网络)来确认是否是网络问题。
2. SSH 客户端超时
- 如果 SSH 客户端等待时间过长没有活动,连接可能会被自动断开。你可以通过增加客户端的保持活动设置来避免此问题。
- 解决方法: 编辑客户端配置文件
~/.ssh/config
,添加以下行来启用保持活动功能:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
这个设置会每 60 秒向服务器发送一个空闲包,如果服务器在 3 次尝试内没有响应,则断开连接。
3. SSH 服务器端超时
- 如果服务器端有设置连接超时,且客户端在该时间内没有任何活动,服务器会断开连接。
- 解决方法: 编辑 SSH 服务器端配置文件
/etc/ssh/sshd_config
,确保没有过短的超时设置:
ClientAliveInterval 60
ClientAliveCountMax 3
这会让服务器每 60 秒向客户端发送一个信号。如果服务器在 3 次尝试内没有收到响应,就断开连接。
修改后,重启 SSH 服务:
sudo systemctl restart sshd
4. 防火墙或网络设备问题
- 一些防火墙或路由器可能会关闭长时间未活动的连接。
- 解决方法: 检查防火墙设置(包括本地和远程的防火墙)是否有类似的连接超时设置。如果使用的是企业级防火墙或路由器,检查是否存在自动断开长时间闲置连接的规则。
5. 错误的 SSH 配置
- 如果 SSH 配置不正确,特别是公钥认证部分出现问题,也可能导致连接被强制关闭。
- 解决方法: 确保 SSH 配置文件没有错误。你可以通过以下命令检查
sshd
服务的状态,查看是否有任何错误信息:
sudo systemctl status sshd
如果出现错误,查看日志并修复配置。
6. 不正确的权限设置
- 如果
.ssh/authorized_keys
文件或其父目录的权限设置不正确,可能导致认证失败并最终断开连接。 - 解决方法: 确保
.ssh
目录和authorized_keys
文件的权限是正确的。执行以下命令:
sudo chmod 700 /home/sftp0/.ssh
sudo chmod 600 /home/sftp0/.ssh/authorized_keys
sudo chown -R sftp0:sftp0 /home/sftp0/.ssh
7. 检查服务器端日志
- 服务器端日志可能会提供更多关于连接断开的详细信息,特别是 SSH 服务的日志。
- 解决方法: 查看
/var/log/auth.log
或/var/log/secure
文件,了解更多信息:
sudo tail -f /var/log/auth.log
或者:
sudo tail -f /var/log/secure
这样你可以查看 SSH 服务是否由于某些错误或限制关闭了连接。
8. SSH 版本不兼容
- 如果客户端和服务器使用的 SSH 协议版本或加密算法不兼容,可能会导致连接问题。
- 解决方法: 确保客户端和服务器使用的 SSH 版本是兼容的,并且支持相同的加密算法。
总结
client_loop: send disconnect: Broken pipe
错误通常是因为 SSH 连接超时、网络问题或服务器端配置不当引起的。通过调整 SSH 客户端和服务器的超时设置、检查防火墙规则和权限设置,通常可以解决这个问题。如果问题仍然存在,查看日志可以帮助进一步诊断。
fatal: bad ownership or modes for chroot directory “/sftp/sftp0”
报错信息 fatal: bad ownership or modes for chroot directory "/sftp/sftp0"
表示 SSH 守护进程在尝试使用 chroot
环境时,发现指定的目录 /sftp/sftp0
的权限或所有者设置不符合安全要求。为了防止潜在的安全问题,SSH 要求 chroot
目录必须具有特定的权限。
解决方案
1. 确保 **chroot**
目录的所有者和权限正确
SSH 在使用 chroot
时要求指定的目录必须由 root
用户拥有,并且该目录的权限设置不能太宽松。确保 /sftp/sftp0
目录的所有者是 root
,且该目录的权限是 755。执行以下命令:
sudo chown root:root /sftp/sftp0
sudo chmod 755 /sftp/sftp0
2. 检查子目录权限
如果 sftp0
用户应该在该目录下有自己的子目录(比如 uploads
或其他),确保这些子目录的权限是适当的。具体来说,子目录可以由 sftp0
用户拥有,但不能直接为 sftp0
用户的父目录设置过宽松的权限。
假设你在 /sftp/sftp0
下创建了子目录:
sudo mkdir /sftp/sftp0/uploads
sudo chown sftp0:sftpusers /sftp/sftp0/uploads
sudo chmod 755 /sftp/sftp0/uploads
3. 确保没有额外的 **chroot**
子目录权限问题
如果你启用了 ChrootDirectory
配置项,必须确保父目录的权限符合 SSH 的要求:
ChrootDirectory
指定的目录(即/sftp/sftp0
)必须属于root
,并且不能有写权限给普通用户。- 用户应该在
chroot
目录内有自己的子目录(如uploads
)来进行操作,且该子目录可以赋予用户写权限。
4. 检查 SSH 配置
确保 SSH 配置文件 /etc/ssh/sshd_config
中的 ChrootDirectory
配置项没有问题。以下是正确配置的示例:
# 限制 sftp0 用户只能访问 /sftp/sftp0 目录
Match User sftp0
ChrootDirectory /sftp/sftp0
ForceCommand internal-sftp
AllowTcpForwarding no
5. 重新启动 SSH 服务
在做出上述更改后,重新启动 SSH 服务使配置生效:
sudo systemctl restart sshd
总结
bad ownership or modes for chroot directory
错误通常是由于 SSH 对于 chroot
目录的权限要求不满足。你需要确保 chroot
目录的所有者是 root
,并且权限设置为 755,且子目录的权限适合用户操作。通过以上操作,应该可以解决问题。
如果看到返回:This service allows sftp connections only.
说明登录已经成功了,该用sftp协议即可,例如: FileZilla
或 sftp
命令行工具
Q&A
Subsystem配置变了,ForceCommand配置是不是也要一起改变?
例如:ForceCommand /usr/libexec/openssh/sftp-server
是的,如果你改变了 SFTP 子系统的路径(例如,更改了 sftp-server
的位置),你可能需要更新 sshd_config
中的 ForceCommand
配置项。
1. **Subsystem**
** 与 **ForceCommand**
的关系**
**Subsystem**
:指定 SFTP 服务的可执行文件。在默认情况下,Subsystem sftp /usr/libexec/openssh/sftp-server
用于指定 SFTP 服务的路径。**ForceCommand**
:强制用户登录时只执行特定的命令,如果你设置了ForceCommand internal-sftp
,那么用户只能通过 SFTP 访问,不会有交互式 Shell。它确保了当用户连接 SSH 时,不会启动普通的 shell,而是启动 SFTP 会话。
2. 更新配置
如果你改变了 sftp-server
的路径,确实需要相应地更新 ForceCommand
和 Subsystem
配置项。如果你将 sftp-server
移到了新的路径,例如 /usr/local/bin/sftp-server
,你需要修改如下:
Subsystem sftp /usr/local/bin/sftp-server
ForceCommand /usr/local/bin/sftp-server
3. 配置建议
通常情况下,**ForceCommand internal-sftp**
会是更常见的配置,它将强制用户使用内置的 SFTP 服务,而不需要指定路径。这样,如果你没有特殊需求,不必再指定外部的 sftp-server
路径。例如:
Subsystem sftp /usr/libexec/openssh/sftp-server
ForceCommand internal-sftp
这意味着,无论 /usr/libexec/openssh/sftp-server
的位置在哪里,用户都会被强制使用 internal-sftp
模式连接 SSH,从而避免普通 shell 会话的启动,确保用户只能进行 SFTP 操作。