vsftpd 500 OOPS: vsftpd: refusing to run with writable root 的 chroot 配置

3次阅读

vsftpd chroot后报500错误是因2.3.5+版本强制限制可写根目录,修复需设家目录为755且属主为用户、SElinux上下文正确,或改用子目录上传;allow_writeable_chroot=YES仅测试环境可用。

vsftpd 500 OOPS: vsftpd: refusing to run with writable root 的 chroot 配置

vsftpd chroot 后报 500 OOPS: vsftpd: refusing to run with writable root

这是 vsftpd 2.3.5+ 版本强制引入的安全限制:启用 chroot_local_user=YESchroot_list_enable=YES 时,若用户根目录(home)权限为可写(即属主有 w 权),服务直接拒绝登录并抛出该错误。

根本原因不是配置写错,而是 vsftpd 认为“可写的 chroot 根目录”存在被恶意提权的风险(比如通过软链接逃逸)。它不关心你实际有没有放危险文件,只做权限位判断。

  • 检查方式:ls -ld /home/username —— 若输出中包含 drwxr-xr-x 或更宽松(如 drwxrwxr-x),就触发拒绝
  • 最简修复:把用户家目录权限改为 755(属主可读写执行,组和其他仅读执行),但注意——这会禁止用户上传文件到家目录顶层
  • 真正可用的方案是:保留家目录 755,再在内部建一个可写子目录(如 upload),用 local_root 或 FTP 客户端默认进入该子目录

为什么设成 755 还不行?常见权限误判点

很多人改完 chmod 755 /home/username 仍报错,问题往往出在「谁是属主」和「SELinux 上下文」:

  • 属主必须是该 FTP 用户本身(chown username:username /home/username),不能是 root 或其他用户
  • 若系统启用了 SELinux(常见于 centos/RHEL),需确认目录上下文是否允许 FTP 访问:ls -Z /home/username,正常应含 public_content_tftp_home_t;否则运行 restorecon -Rv /home/username
  • chroot_local_user=YES 是全局开关,一旦开启,所有本地用户都受约束;如只想限制部分用户,请改用 chroot_list_enable=YES + chroot_list_file=/etc/vsftpd/chroot_list,并在列表中只写需限制的用户名

allow_writeable_chroot=YES 能不能直接关掉限制?

可以,但不推荐。这个配置项在 vsftpd 3.0.0+ 才支持,作用就是绕过可写根目录检查。但它只是“关报警”,没解决底层风险。

  • 仅建议用于开发或内网测试环境,生产环境禁用
  • 启用后仍需确保用户家目录不被其他用户写入(即权限不能是 777 或属组可写且组成员不可信)
  • 某些发行版(如 debian 12)默认编译时未启用该选项,即使写了也会被忽略 —— 查看日志:grep "allow_writeable_chroot" /var/log/vsftpd.log,若提示 unrecognized option 就说明不支持

chroot 成功后无法上传:路径、权限与配置联动关系

chroot 解决了登录问题,但上传失败往往是多个环节断开导致的,重点查三处:

  • write_enable=YES 必须开启,否则所有写操作(STOR、MKD 等)直接被拒
  • 目标上传路径(比如 /home/user/upload)需满足:属主是该用户、权限至少 755(若需创建子目录则需 x)、SELinux 上下文正确
  • 如果用了 user_sub_tokenlocal_root,确认路径拼接无误 —— 例如 local_root=/home/$USER/public_html,而实际目录是 /home/username/html,就会因路径不存在导致 550 错误

chroot 的坑不在配置行数,而在权限、属主、SELinux、路径四者必须同时对齐。少一个,FTP 就会静默失败或报看似无关的错误。

text=ZqhQzanResources