资讯详情

资讯详情

CentOS 7 上 vsftpd 虚拟用户配置与被动模式实战指南

1. 为什么还要在 CentOS 7 上折腾 vsftpd先把话说在前头现在新项目基本都上容器和对象存储了但你去翻翻那些跑了五六年以上的老机房十台机器里至少有三四台还在用 FTP 传文件。尤其是制造业、医疗、广电这类行业的内网环境业务系统跟外部单位对接对方甩过来一句“你们开个 FTP 账号给我”你就得老老实实把服务搭起来。CentOS 7 虽然已经进入维护末期但存量部署量摆在那里很多生产环境短期内根本动不了所以这套东西该会还得会。vsftpd 这个软件全称是 Very Secure FTP Daemon名字里就带着“安全”两个字。它轻量、稳定、权限模型清晰配置项虽然多但逻辑自洽跑起来之后基本不用怎么管。我见过一台跑了四年没重启过的 vsftpd中间传了几十万个文件日志干干净净。这篇文章就是把我这些年反复搭建、踩坑、调优的经验整理出来从零开始把一台 CentOS 7 配成一个能用的 FTP 服务器重点讲清楚每个配置项背后的意图以及那些文档里不会写的坑。适合谁看如果你手头正好有一台 CentOS 7 的机器需要给同事或者外部合作方开个文件传输通道又不想花太多时间研究那这篇可以直接抄作业。如果你只是想了解一下 FTP 服务的基本原理里面关于权限模型和被动模式的部分也值得一读。我会尽量用大白话把原理讲透同时给出可以直接复制粘贴的命令和配置。2. 动手之前的整体设计思路2.1 先想清楚你要哪种 FTP 模式很多人一上来就装软件装完发现这也不对那也不对根本原因是没想清楚自己要什么。FTP 服务有三种典型的用户模型选错了后面全是麻烦。第一种是匿名用户模式任何人不需要账号密码就能登录只能下载不能上传或者只能上传到一个临时目录。这种模式现在基本没人用了安全风险太大除非是纯粹的内部测试环境否则不建议开。第二种是系统用户模式直接用 Linux 系统里已有的账号登录 FTP。这种模式的好处是账号管理跟系统打通你不需要额外维护一套密码体系。但坏处也很明显FTP 登录会读取系统账号信息如果某个系统账号密码太弱等于给服务器开了一个额外的入口。而且系统用户登录后默认会进入自己的家目录权限控制需要额外配置。第三种是虚拟用户模式这是生产环境最推荐的方式。虚拟用户跟系统账号完全隔离账号密码存在独立的数据库文件里每个虚拟用户映射到一个统一的系统账号上通过目录权限来区分不同用户的访问范围。这样即使 FTP 账号泄露攻击者也拿不到系统层面的任何东西。我个人的建议是如果只是临时用几天系统用户模式最快如果是长期跑的生产服务直接上虚拟用户模式前期多花二十分钟配置后面省心几年。2.2 主动模式与被动模式的取舍FTP 协议最让人头疼的地方就是它用了两个连接一个控制连接默认 21 端口用来发命令一个数据连接用来传文件。数据连接怎么建立就分出了主动和被动两种模式。主动模式下客户端告诉服务端“我监听在某个端口你来连我”。问题在于客户端通常都在防火墙或者 NAT 后面服务端主动去连往往连不上。被动模式反过来服务端开一个随机端口等客户端来连对客户端友好但服务端需要开放一个端口范围。现在实际部署中被动模式是唯一可行的选择因为客户端环境你控制不了。你需要做的是在 vsftpd 配置里指定一个端口范围然后在防火墙里把这个范围放开。端口范围选多少一般 20 个端口够用了比如 30000 到 30020。如果并发传输需求大可以开到 50 个。端口范围太小会导致高峰期连接排队太大又增加安全暴露面这个平衡要根据实际业务量来定。2.3 目录结构与权限规划在动手之前先在纸上画一下目录结构。我通常的做法是建一个统一的 FTP 根目录比如/data/ftp下面按用户或者业务线分目录。每个虚拟用户映射到同一个系统账号比如叫ftpuser这个账号不需要登录系统只用来跑 FTP 服务。权限方面核心原则是最小可用。上传目录给写权限下载目录只给读权限需要删除重命名的目录单独配置。vsftpd 的权限控制分两层一层是文件系统层面的 Linux 权限一层是 vsftpd 配置里的功能开关。两层都要管住缺一不可。还有一个容易被忽略的点SELinux。CentOS 7 默认开启 SELinux它会拦截 FTP 对非标准目录的访问。很多人配置完发现能登录但列不出目录八成就是 SELinux 在作怪。后面我会专门讲怎么处理。3. 从零开始的完整搭建流程3.1 安装前的环境检查与准备拿到一台 CentOS 7 机器先别急着装软件花两分钟做几个检查。第一确认系统版本和内核版本。命令是cat /etc/redhat-release和uname -r。CentOS 7 的最终版本是 7.9如果你的是更早的版本建议先做一次系统更新但要注意更新可能会影响现有业务生产环境要谨慎。第二检查 21 端口有没有被占用。命令是ss -tlnp | grep :21。如果已经有其他 FTP 服务在跑要么停掉它要么换端口。我遇到过一台机器上同时装了 vsftpd 和 proftpd两个服务抢 21 端口折腾了半天才发现。第三确认防火墙状态。CentOS 7 默认用 firewalld命令是systemctl status firewalld。如果防火墙开着后面配置完必须放行端口否则客户端连不上。有些人图省事直接systemctl stop firewalld并且systemctl disable firewalld这在纯内网环境可以接受但只要机器有公网 IP就绝对不要这么干。第四检查 SELinux 状态。命令是getenforce返回 Enforcing 就是开启状态。后面配置完如果遇到权限问题先来这里看看。环境检查做完开始安装。安装命令很简单yum install -y vsftpd安装完成后先别启动因为默认配置有很多不适合生产的地方。我们先备份原始配置文件cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak这个备份习惯一定要养成。我见过太多人改配置改崩了又没有备份最后只能重装。3.2 核心配置文件逐项拆解vsftpd 的主配置文件是/etc/vsftpd/vsftpd.conf里面每一行都是参数值的格式。下面我按功能分组把生产环境常用的配置项逐个讲清楚。基础连接类配置# 监听 IPv4 地址如果服务器只有 IPv4 就保持 YES listenYES # 关闭 IPv6 监听避免一些环境下出现奇怪问题 listen_ipv6NO # 允许匿名登录生产环境必须关掉 anonymous_enableNO # 允许本地系统用户登录虚拟用户模式下这个也要开 local_enableYES # 允许写操作上传文件必须开 write_enableYES # 本地用户的默认权限掩码022 表示上传的文件权限是 644 local_umask022这里重点说local_umask。umask 是权限掩码022 意味着新创建的文件权限是 666 减去 022 等于 644目录是 777 减去 022 等于 755。如果你希望同组用户也能写可以设成 002这样文件权限是 664目录是 775。但要注意FTP 上传的文件默认不会带执行权限这是合理的避免有人上传恶意脚本直接执行。目录与权限控制类配置# 限制本地用户只能在自己的家目录里活动 chroot_local_userYES # 允许 chroot 列表里的用户例外这个列表文件默认是空的 chroot_list_enableYES chroot_list_file/etc/vsftpd/chroot_list # 允许 chroot 目录可写CentOS 7 上必须加这个否则登录报错 allow_writeable_chrootYESchroot_local_userYES这个配置非常关键。它把用户锁在自己的家目录里用户看不到也进不去系统其他目录。但这里有个坑如果用户的家目录本身有写权限vsftpd 会拒绝登录报“500 OOPS: vsftpd: refusing to run with writable root inside chroot()”。解决办法就是加allow_writeable_chrootYES。这个配置在较新版本的 vsftpd 里才有CentOS 7 自带的版本是支持的。被动模式配置# 开启被动模式 pasv_enableYES # 被动模式使用的端口范围 pasv_min_port30000 pasv_max_port30020 # 被动模式下返回给客户端的 IP 地址如果服务器有公网 IP 就填公网 IP pasv_address你的公网IPpasv_address这个配置很多人会漏掉。如果你的服务器在 NAT 后面客户端连上来之后服务端返回的是内网 IP客户端拿着内网 IP 去连数据端口当然连不上。这时候必须显式指定公网 IP。如果服务器直接有公网 IP可以不填vsftpd 会自动获取。日志与超时配置# 开启传输日志 xferlog_enableYES xferlog_file/var/log/vsftpd.log xferlog_std_formatYES # 连接超时时间秒 connect_timeout60 # 空闲超时时间秒 idle_session_timeout300 # 数据连接超时时间秒 data_connection_timeout120超时时间要根据实际网络情况调整。如果客户端网络质量差超时设太短会导致大文件传到一半断掉。我一般把data_connection_timeout设成 300 秒给足缓冲。3.3 虚拟用户的完整配置方案虚拟用户模式是重点我一步步来。第一步创建虚拟用户数据库文件。先建一个纯文本文件奇数行是用户名偶数行是密码vim /etc/vsftpd/virtusers.txt内容示例upload_user Upload2024 download_user Download2024然后把这个文本文件转成数据库文件db_load -T -t hash -f /etc/vsftpd/virtusers.txt /etc/vsftpd/virtusers.db chmod 600 /etc/vsftpd/virtusers.db转完之后把原始文本文件删掉或者移到安全的地方不然密码明文放在那里等于没加密。第二步创建虚拟用户映射的系统账号。这个账号不需要密码也不需要登录系统useradd -d /data/ftp -s /sbin/nologin ftpuser注意-s /sbin/nologin表示这个账号不能登录系统 shell只能用来跑服务。第三步配置 PAM 认证。编辑/etc/pam.d/vsftpd把里面原有的内容注释掉加上这两行auth required pam_userdb.so db/etc/vsftpd/virtusers account required pam_userdb.so db/etc/vsftpd/virtusers这里有个细节db后面跟的路径不要加.db后缀pam_userdb 会自动补上。第四步配置每个虚拟用户的独立权限。vsftpd 支持为每个虚拟用户单独配置权限配置文件放在/etc/vsftpd/vuser_conf/目录下文件名就是用户名。比如给upload_user建一个配置文件vim /etc/vsftpd/vuser_conf/upload_user内容local_root/data/ftp/upload write_enableYES anon_upload_enableYES anon_mkdir_write_enableYES anon_other_write_enableYES给download_user的配置local_root/data/ftp/download write_enableNO anon_upload_enableNO anon_mkdir_write_enableNO anon_other_write_enableNO注意这里的anon_前缀参数在虚拟用户模式下虚拟用户被当作匿名用户处理所以上传相关的开关都是anon_开头的。第五步在主配置文件里启用虚拟用户。在/etc/vsftpd/vsftpd.conf末尾加上# 启用虚拟用户 guest_enableYES # 虚拟用户映射的系统账号 guest_usernameftpuser # 虚拟用户独立配置文件目录 user_config_dir/etc/vsftpd/vuser_conf # 虚拟用户的家目录权限 virtual_use_local_privsNOvirtual_use_local_privsNO表示虚拟用户使用匿名用户的权限模型这样才能让anon_开头的配置生效。如果设成 YES虚拟用户就拥有本地用户的权限配置方式会不一样。3.4 防火墙与 SELinux 的配套设置配置写完了服务能不能跑起来防火墙和 SELinux 说了算。防火墙放行firewall-cmd --permanent --add-port21/tcp firewall-cmd --permanent --add-port30000-30020/tcp firewall-cmd --reload第一行放行控制端口第二行放行被动模式的数据端口范围。范围要跟配置文件里的pasv_min_port和pasv_max_port一致。SELinux 处理如果你不想关 SELinux可以用以下命令放行 FTP 相关权限setsebool -P ftp_home_dir on setsebool -P allow_ftpd_full_access onftp_home_dir允许 FTP 访问用户家目录allow_ftpd_full_access给 FTP 更完整的文件访问权限。这两个命令执行后是永久生效的重启也不会丢。如果执行完还是有问题可以临时把 SELinux 设成宽容模式测试setenforce 0如果设成宽容模式后正常了说明就是 SELinux 的问题再回头仔细排查具体是哪个策略拦住了。生产环境不建议长期关闭 SELinux但排查阶段可以临时用一下。4. 启动服务与验证测试4.1 启动服务并检查状态配置全部改完之后启动服务systemctl start vsftpd systemctl enable vsftpd第一行启动第二行设置开机自启。然后检查状态systemctl status vsftpd看到active (running)就说明服务起来了。如果启动失败用journalctl -u vsftpd -n 50看最近 50 行日志通常能直接定位到问题。4.2 用命令行客户端做完整测试测试环节我建议用命令行 FTP 客户端因为图形化工具会隐藏很多细节。在另一台机器上执行ftp 你的服务器IP输入用户名密码登录成功后依次测试以下操作ls列出目录确认能看到文件put 本地文件上传文件确认上传成功get 远程文件下载文件确认下载成功mkdir 测试目录创建目录确认权限正确delete 文件删除文件确认删除权限每个操作都成功说明基本功能没问题。如果某个操作失败看返回的错误码对照后面的排查表处理。4.3 被动模式连通性验证被动模式最容易出问题单独验证一下。在 FTP 命令行里执行passive切换到被动模式然后执行ls。如果卡住不动说明数据端口没通。排查思路先在服务端用ss -tlnp | grep vsftpd看被动端口有没有在监听。然后在客户端用telnet 服务器IP 30000测试端口连通性。如果 telnet 不通检查防火墙规则和pasv_address配置。还有一个隐蔽的坑如果服务器有多张网卡vsftpd 可能监听在错误的网卡上。可以在配置文件里加listen_address指定IP来强制绑定。5. 常见问题与排查技巧实录5.1 登录类问题速查错误现象可能原因解决方法530 Login incorrect密码错误或 PAM 配置问题检查 virtusers.db 是否生成正确PAM 文件路径是否对500 OOPS: cannot change directory家目录不存在或权限不对确认 local_root 目录存在且 ftpuser 有访问权限500 OOPS: vsftpd: refusing to run with writable rootchroot 目录可写加 allow_writeable_chrootYES421 Service not available服务未启动或端口被占检查服务状态和端口占用5.2 传输类问题排查上传文件时报550 Permission denied先检查三个地方文件系统权限、vsftpd 配置里的write_enable、以及虚拟用户配置文件里的anon_upload_enable。三个都对了才能上传。下载大文件传到一半断掉通常是超时设置太短。把data_connection_timeout和idle_session_timeout都调大同时检查网络中间有没有设备会切断长连接。被动模式列目录卡住九成是端口没放行或者pasv_address没配。按前面说的方法逐步排查。5.3 几个我踩过的坑第一个坑chroot_list_enableYES和chroot_local_userYES同时开启时chroot_list文件里的用户反而不会被 chroot。这个逻辑跟直觉相反很多人配反了。记住chroot_local_userYES表示所有本地用户都被限制chroot_list里的是例外也就是不被限制的用户。第二个坑虚拟用户的密码如果包含特殊字符在db_load转换时可能出问题。建议密码里只用字母、数字和、#这类常见符号避免用引号和反斜杠。第三个坑CentOS 7 的 vsftpd 默认没有开启pasv_promiscuous在某些 NAT 环境下需要开启这个选项才能正常传输。但这个选项会降低安全性只在确认需要时开启。第四个坑日志文件/var/log/vsftpd.log默认可能不存在需要手动创建并给权限touch /var/log/vsftpd.log chown root:root /var/log/vsftpd.log chmod 644 /var/log/vsftpd.log不然日志写不进去出了问题你连线索都没有。6. 安全加固与日常维护建议6.1 必做的几项安全设置FTP 协议本身是明文传输账号密码在网络上裸奔。如果条件允许尽量上 FTPS 或者 SFTP。但如果只能用 FTP以下加固措施必须做禁止匿名登录anonymous_enableNO限制用户只能访问自己的目录chroot_local_userYES设置登录失败次数限制可以用fail2ban配合 vsftpd 日志实现定期更换虚拟用户密码尤其是给外部单位用的账号把banner设置成一个不暴露系统信息的欢迎语6.2 日志监控与容量规划/var/log/vsftpd.log会记录每次传输的文件名、大小、方向。定期分析这个日志可以发现异常传输行为。比如某个账号突然在凌晨大量下载文件可能就是账号被盗了。磁盘容量要提前规划。FTP 服务器最容易出的问题就是磁盘写满。建议单独挂一块数据盘给 FTP 用并且设置监控告警使用率超过 80% 就通知。6.3 备份与迁移注意事项虚拟用户数据库文件virtusers.db和用户配置文件目录vuser_conf是核心资产一定要纳入备份。迁移到新服务器时把这两个东西拷过去再改一下 IP 相关的配置就能直接用。迁移时注意pasv_address要改成新服务器的 IP防火墙规则要重新放行SELinux 的布尔值要重新设置。这几步漏了任何一步服务都跑不起来。我个人在实际操作中的体会是vsftpd 的配置看起来项多但真正影响功能的就是那么十来个关键项。把chroot、pasv、虚拟用户映射这三块吃透剩下的都是锦上添花。遇到问题先看日志日志里找不到线索就查防火墙和 SELinux这两个地方能解决八成以上的疑难杂症。最后再分享一个小技巧配置改完后不要急着重启服务先用vsftpd /etc/vsftpd/vsftpd.conf在前台跑一下有语法错误会直接报出来比看系统日志快得多。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →