局域网里要传几十个G的素材很多人第一反应是丢网盘或者挂共享盘我这些年经手过不少类似的需求最后绕一圈回来的还是 FTP。上个月帮一个做视频剪辑的工作室收拾他们的素材归档系统老板一开始执意要换成在线协作盘我问他高峰期一天要过多少量他说四五个 T单个工程文件动辄几十个 G。这种场景下Linux 上搭一台 FTP 服务器依然是最省心、最便宜、最不挑客户端的选择。本文就把我在 Linux 上搭建 FTP 服务器的完整过程拆开讲清楚从方案选型、账号规划、vsftpd 配置、虚拟用户、被动模式端口放行一直到线上常见的故障排查尽量让只要你手上有台服务器就能照着落地。不管你是刚接触 Linux 的运维新人还是被临时抓来管一台文件服务器的开发这篇内容都能直接参考。1. 动手之前先把需求和方案想明白1.1 FTP 到底适合谁什么场景不该用它我见过太多人上来就yum install vsftpd配置改到一半发现方向就不对。搭 FTP 之前先问自己三个问题谁来连、从哪连、传什么。如果用户都在同一个内网只是要在几台机器和一台存储之间倒文件那 FTP 几乎是零成本方案客户端随便挑FileZilla、WinSCP、甚至系统自带资源管理器都能连。如果用户分散在公网各处需要频繁上传下载那 FTP 也能用但你得把被动模式的端口范围和地址映射处理干净否则一半人会连不上。如果只是偶尔传个几兆的文档坦白说聊天工具或者对象存储更适合没必要专门养一台服务。真正的分水岭在于是否需要长期、批量、大文件的双向传输。FTP 协议本身很老明文传账号密码这是它被诟病的核心点但它的优势也很硬客户端生态极其成熟断点续传、多线程、目录树浏览这些能力在客户端侧早就打磨了二十多年服务端资源占用又低一台 1 核 2G 的小机器扛几百兆带宽没问题。所以我的判断标准很简单——内网批量传文件选 FTP公网传敏感数据优先考虑 SFTP 或 FTPS临时小文件别折腾 FTP。还有个容易被忽略的点FTP 是双连接协议。控制连接走 21 端口数据连接另开一个端口主动模式是服务器回头连客户端被动模式是客户端连服务器的一个高位端口。这个机制是所有后续配置麻烦的根源理解它比背配置项重要得多。1.2 服务端软件怎么选vsftpd、ProFTPD 还是 Pure-FTPdLinux 上主流的 FTP 服务端就三个我这些年基本只用 vsftpd理由后面说但把三者的差异摆出来你自己判断。软件优势短板适合场景vsftpd轻量、稳定、发行版原生支持、文档多虚拟用户配置略绕、功能相对基础绝大多数中小规模场景ProFTPD配置语法像 Apache、模块化强配置复杂度高、历史上出过安全问题需要复杂权限和模块扩展Pure-FTPd虚拟用户原生支持好、默认配置较安全社区资料相对少纯虚拟用户、多租户我推荐 vsftpd 的核心原因是它的默认安全做得比较到位匿名访问默认关闭、chroot 可以一键开启、配合 PAM 能做虚拟用户、几乎每个发行版的仓库里都有现成包。ProFTPD 的配置文件可读性确实好但对新手来说参数太多反而容易配错。Pure-FTPd 在虚拟用户这块体验最顺如果你一上来就确定要用数据库或者纯虚拟账号体系它值得考虑。需要提醒的是网上大量老教程还在教关闭 SELinux、关防火墙这是典型的为了解决一个问题引入十个问题。正确的做法是配置 SELinux 布尔值和防火墙规则这部分我在第 5 章会详细写。2. 搭建前的环境准备与账号规划2.1 系统环境确认与软件安装第一步永远是确认环境别急着装。先看发行版和内核版本因为不同发行版的配置文件路径、SELinux 默认策略都不一样。cat /etc/os-release uname -r getenforce systemctl status firewalld 2/dev/null || ufw statusgetenforce输出 Enforcing 说明 SELinux 开着后面配目录权限时必须同步处理输出 Disabled 或者 Permissive 就省事一些。防火墙那块CentOS 系看 firewalldUbuntu 系看 ufw两者规则写法完全不同别照搬错教程。安装本身很简单# CentOS / RHEL / Rocky sudo yum install -y vsftpd # Debian / Ubuntu sudo apt update sudo apt install -y vsftpd装完先别启动因为这个阶段启动意义不大配置还没改。这里有个经验安装后先执行rpm -ql vsftpd或者dpkg -L vsftpd把包里的文件列表看一眼你能立刻搞清楚配置文件在哪、PAM 配置在哪、默认的 FTP 根目录在哪。CentOS 系的配置文件是/etc/vsftpd/vsftpd.confUbuntu 是/etc/vsftpd.confPAM 文件都是/etc/pam.d/vsftpd。这个动作花三十秒能省掉后面半小时的翻找。注意不要用网上那种一键脚本装 FTP。我见过不少脚本为了兼容直接setenforce 0并把防火墙整个关掉服务器等于裸奔在公网上风险极大。2.2 端口与网络拓扑的前置梳理在改任何配置之前把这几件事画在纸上服务器 IP、控制端口、被动模式端口范围、客户端从哪来、中间有没有 NAT 或负载设备。这几项没想清楚后面配出来的服务一定时好时坏。控制端口默认 21一般不改。数据端口才是重点。如果你只用主动模式PORT服务器会用 20 端口回连客户端但客户端在 NAT 后面时基本连不通所以现实中几乎都走被动模式PASV需要你在服务端指定一段端口范围比如 30000 到 31000然后把这些端口在防火墙和安全组里全放行。端口范围开多大这取决于并发连接数。每个被动模式的数据传输会占用范围内一个端口理论并发数就是端口数量。1000 个端口听起来很多但如果你的客户端用多线程下载一个用户可能同时占 5 到 10 个连接那 1000 个端口实际只够一百来个并发用户。我的经验是内部使用开 500 个足够对外服务的按峰值并发数乘以 10 来预留。另外范围别开太大一来防火墙规则臃肿二来安全审计时不好看。如果服务器在云上或者经过 NAT 设备还要考虑pasv_address这个参数。很多人忽略它结果在云服务器上配好了内网测试通过外网用户报可以登录但列不出目录就是这个参数没填公网 IP 导致的。2.3 账号模型系统用户、匿名还是虚拟用户这一步是整篇内容里最关键的决策直接决定后面配置的复杂度和安全性。三种模型各有明确的适用边界。系统用户模式最直观直接拿 Linux 上的账号登录 FTP。优点是配起来快五个参数就能跑起来。缺点是每个 FTP 用户都得在系统里存在用户多了账号管理会失控而且系统账号密码泄露等于机器被人摸到门口。适合内部小团队、账号数量在十个以内的场景。匿名模式就是所有人都能连通常配成只读用来做公开下载站。现在这个时代开放匿名 FTP 越来越少如果确实需要务必只读加上限速别开写权限否则很快会变成别人的文件中转站。虚拟用户模式是我在正式环境里最推荐的。账号只存在于 FTP 自己的数据库里和系统账号完全隔离一个系统账号ftpuser可以对应几十个虚拟用户每个虚拟用户可以有自己的根目录和权限。配起来比前两种麻烦一些但一旦跑通管理体验是质的提升——加一个用户就是改一行文本然后重建一次数据库不用碰系统用户。判断标准很清晰内部五六个人随手传文件系统用户够了对外提供文件服务或者用户超过二十个直接上虚拟用户别犹豫。3. vsftpd 基础配置先跑通最小可用服务3.1 配置文件骨架与参数逐条拆解不管最后用哪种账号模式最小可用的骨架是相通的。先备份原始配置文件这个习惯必须养成。sudo cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak然后写一份基础配置我把每个参数的作用和我的取值理由都标出来# 禁止匿名访问绝大多数场景都应该关掉 anonymous_enableNO # 允许系统用户登录 local_enableYES # 开启写权限没有它上传会报 550 write_enableYES # 本地用户上传文件的默认权限掩码022 表示文件 644、目录 755 local_umask022 # 开启每条目录的提示消息功能可选 dirmessage_enableYES # 记录传输日志 xferlog_enableYES # 数据连接使用 20 端口仅主动模式 connect_from_port_20YES # 所有本地用户登录后都被限制在自己的家目录 chroot_local_userYES # 允许被 chroot 的目录具备写权限不然后面上传会报错 allow_writeable_chrootYES # 被动模式 pasv_enableYES pasv_min_port30000 pasv_max_port31000 # 监听 IPv4 listenYES listen_ipv6NO # PAM 认证模块名和 /etc/pam.d/ 下的文件名对应 pam_service_namevsftpd这里逐条说几个新手最容易踩的。local_umask决定了上传文件的默认权限设成 077 会导致同组用户读不了文件设成 000 又过于宽松022 是最稳的中间值。chroot_local_user和allow_writeable_chroot是一对只开前者不开后者用户一上传就会收到500 OOPS: vsftpd: refusing to run with writable root inside chroot()这个报错几乎每个新手都会遇到一次。关于chroot_local_user还有个反直觉的点它限制的是用户登录后能看到多大范围不是文件权限。也就是说用户被关在/home/ftpuser里但他依然可能通过软链接跑到外面。如果你的场景对隔离要求高还要额外加allow_writeable_chroot之外的限制或者干脆用虚拟用户配合独立的目录树。配置写完先做语法检查其实 vsftpd 不做严格语法校验但错误参数会导致启动失败所以看日志更靠谱sudo systemctl start vsftpd sudo systemctl status vsftpd sudo journalctl -u vsftpd -n 50启动失败九成是参数拼写错误或者端口被占用日志里会明确告诉你是哪一行。3.2 本地用户模式的目录权限设计系统用户模式下典型做法是创建专用账号把他的家目录作为 FTP 根目录。sudo useradd -d /data/ftp/u_zhangsan -s /sbin/nologin u_zhangsan sudo passwd u_zhangsan sudo mkdir -p /data/ftp/u_zhangsan/upload sudo chown -R u_zhangsan:u_zhangsan /data/ftp/u_zhangsan sudo chmod -R 755 /data/ftp/u_zhangsan几个细节值得掰开说。-s /sbin/nologin是必须的否则这个账号还能 SSH 登录等于开了个后门FTP 服务本身不需要交互式 shell。目录权限设置成 755 而不是 777很多人图省事直接 777结果是同目录下任何用户都能删别人的文件而且allow_writeable_chroot对这种全局可写的目录会更敏感。如果你希望多个用户共享一个上传目录正确做法是建一个用户组把目录组权限设成这个组再用 setgid 让新建文件继承组sudo groupadd ftpshare sudo usermod -aG ftpshare u_zhangsan sudo chgrp ftpshare /data/ftp/share sudo chmod 2775 /data/ftp/share2775里最前面那个 2 就是 setgid 位作用是目录里新建的文件自动继承父目录的组这样多用户协作时权限不会乱。这个技巧在处理团队共享素材库时特别有用我给它单独拎出来就是因为踩过坑不加 setgidA 用户建的文件属组是 A 自己B 用户第二天就写不进去。3.3 SELinux 与 chroot 的典型报错处理前两节提到 SELinux这里专门讲怎么处理。当你目录权限、配置都对客户端却报550 Failed to change directory或者登录后直接500 OOPS十有八九是 SELinux 在拦。先看审计日志确认是不是它sudo ausearch -m avc -ts recent | grep ftp如果确实有拒绝记录正确做法是打布尔值而不是关 SELinuxsudo setsebool -P ftpd_full_accesson sudo setsebool -P ftp_home_diron-P表示持久化重启后依然生效。ftpd_full_access允许 FTP 读写用户家目录下的内容ftp_home_dir是更细粒度的家目录访问开关。有些发行版里第二个布尔值已经合并了执行时如果提示不存在就跳过。还有一种情况是目录放在了非标准位置比如/data/ftp这种目录的 SELinux 上下文可能不对需要手动打标签sudo semanage fcontext -a -t public_content_rw_t /data/ftp(/.*)? sudo restorecon -Rv /data/ftp这套组合拳下来SELinux 相关的报错基本能清干净。我个人的原则是永远先尝试配置策略实在搞不定再考虑把服务放到 Permissive 模式并且在问题解决后立刻切回 Enforcing绝不能长期 Disabled。4. 虚拟用户方案账号与系统彻底解耦4.1 PAM 认证模块与账号库生成虚拟用户的核心思路是FTP 账号存在一个独立的文本数据库里认证走 PAM 的pam_userdb模块所有虚拟用户最终映射到同一个系统账号上去读写磁盘。这样加账号不碰系统权限又有统一出口。第一步建立明文账号文件格式是一行用户名一行密码交替sudo vim /etc/vsftpd/virtusers内容形如alice AlicePass_2024 bob BobPass_2024第二步用db_load把它编译成 Berkeley DB 格式vsftpd 只认这个格式sudo db_load -T -t hash -f /etc/vsftpd/virtusers /etc/vsftpd/virtusers.db sudo chmod 600 /etc/vsftpd/virtusers.db sudo chmod 600 /etc/vsftpd/virtusers权限设 600 是硬性要求这个文件里是明文密码任何其他用户可读都是安全事故。生成后建议把明文文件删掉或者挪到只有 root 能碰的地方只保留.db文件。第三步改 PAM 配置编辑/etc/pam.d/vsftpd把原有内容注释掉写入auth required pam_userdb.so db/etc/vsftpd/virtusers account required pam_userdb.so db/etc/vsftpd/virtusers注意这里写的是数据库的路径去掉扩展名。第四步在主配置里开启虚拟用户模式guest_enableYES guest_usernameftpuser virtual_use_local_privsYES user_config_dir/etc/vsftpd/virtusers_confguest_username是那个承载所有磁盘操作的系统账号需要提前建好-s /sbin/nologin同样不能少。virtual_use_local_privsYES让虚拟用户拥有和本地用户一样的权限行为写权限开启后会按local_umask规则落地不加这个参数的话写权限控制会比较别扭。提示每次修改virtusers明文文件后都必须重新执行一次db_load命令否则新账号不生效。这是虚拟用户方案里最容易忘的一步我自己也忘过不止一次排查半天才发现数据库没重建。4.2 独立权限文件与每用户根目录虚拟用户方案真正好用的地方是每个用户可以有一份独立配置。在user_config_dir指向的目录下用用户名作为文件名建配置sudo mkdir -p /etc/vsftpd/virtusers_conf sudo vim /etc/vsftpd/virtusers_conf/alice内容可以这样写local_root/data/ftp/alice write_enableYES local_umask022 anon_world_readable_onlyNO download_enableYES这样 alice 登录后就被关进/data/ftp/alice而 bob 的配置里可以把local_root指向另一个目录甚至把write_enableNO做成只读账号。如果某个用户没建独立配置文件就会走主配置的默认值所以通常的做法是给每个账号都建一份把权限意图写明确。目录准备这块和系统用户模式类似但属主统一是guest_username指定的那个账号sudo mkdir -p /data/ftp/alice/upload sudo chown -R ftpuser:ftpuser /data/ftp/alice sudo chmod -R 755 /data/ftp/alice有些资料会建议给只读用户设local_root后加个只读挂载或者 ACL我的经验是更简单的做法建两个目录一个readonly一个upload只读用户的配置里只暴露readonly这个路径写用户暴露根目录然后配合local_umask控制。与其堆一堆看不到的权限规则不如用目录结构把权限表达清楚这样半年后回来接手的人也能看懂。5. 被动模式落地端口计算与防火墙放行5.1 主动模式为什么在公网几乎必挂先把两种模式的区别讲透这是后面所有端口问题的根。主动模式下客户端发起控制连接后告诉服务器我用某个端口等你然后服务器从自己的 20 端口反向去连客户端那个端口。问题在于客户端几乎都在 NAT 后面服务器回连的地址是私网地址路由器根本不知道怎么转发于是连接超时。企业防火墙也普遍禁止外部主动发起的连接。所以主动模式现在只在纯内网、两端都没有 NAT 的极少数场景下还能用。被动模式反过来客户端发起控制连接后服务器告诉客户端我在某个高位端口等你来连客户端主动去连这个端口。因为连接方向是客户端到服务器穿透 NAT 和防火墙都容易得多。代价就是服务器必须提前指定一段固定的端口范围并保证这段端口从公网可达。5.2 端口范围的计算与防火墙放行实操端口范围怎么定前面提过按峰值并发预留这里给出具体的计算过程。假设你预计同时在线 50 人每人平均开 4 个数据连接浏览器式列目录经常一次开好几个那需要 200 个端口再留一倍余量就是 400 个取整到 30000 到 30400。范围别超过几千个否则防火墙规则管理和连接追踪表都会吃力。服务端配置里写上范围前面已经给出pasv_enableYES pasv_min_port30000 pasv_max_port30400然后是防火墙firewalld 和 ufw 写法不同# firewalld sudo firewall-cmd --permanent --add-port21/tcp sudo firewall-cmd --permanent --add-port30000-30400/tcp sudo firewall-cmd --reload sudo firewall-cmd --list-ports # ufw sudo ufw allow 21/tcp sudo ufw allow 30000:30400/tcp sudo ufw reload sudo ufw status numbered云服务器还有一层安全组很多人配置都对但就是连不上最后发现是控制台里安全组没放行。这层的规则和系统防火墙是叠加关系不是二选一两边都要开。Windows 服务器同理图形界面的入站规则里要同时放行 21 和被动端口段只开 21 的结果就是能登录但列不出目录这个现象特别有迷惑性。5.3 NAT 与云环境的额外配置服务器本身在私网、通过 NAT 出公网的情况必须显式告诉客户端用哪个地址来连数据端口pasv_address203.0.113.10 pasv_addr_resolveNOpasv_address填公网出口 IP。如果不写这个参数服务器会把自己内网网卡的地址发给客户端客户端连过去自然失败。这个坑在云主机新构架里尤其常见因为很多云的弹性 IP 是挂在网关上的机器内部根本看不到。还有一种情况是服务器有多张网卡或者多个 IP可以额外用pasv_address配合pasv_addr_resolve指定域名让客户端解析后连接。如果环境更复杂比如前面还有负载设备那就得确认负载设备本身支持 FTP 协议的端口跳转否则纯四层转发是做不了的因为数据连接是客户端根据服务端返回的地址新建的。注意测试被动模式建议从真正的外部网络测别只在内网用 127.0.0.1 测。内网测试永远通过外网测试才有意义。用ftp命令行客户端加passive和debug开关能看到完整交互过程比图形客户端报个模糊错误有用得多。6. 故障排查速查表从连不上到传不动6.1 连接建立阶段的典型故障连接建立阶段的问题最好定位因为现象和原因基本一一对应。现象大概率原因排查动作客户端一直卡在正在连接21 端口未放行或服务没启动ss -tlnp | grep 21、防火墙和安全组检查能登录但列目录卡住后超时被动端口段未放行或pasv_address没配放行端口段、补公网 IP登录后报 530账号密码错或被拒绝列表拦截检查userlist相关配置报 421 服务不可用连接数超过max_clients限制调大并发或查日志确认来源我特别想说的是能登录但列不出目录这个现象。新手往往会怀疑是权限问题其实八成是被动模式的数据连接没通。区分方法很简单命令行客户端执行passive切换模式后再试如果主动模式能列出但被动不行问题就在端口放行或者地址映射上和文件权限一点关系没有。搞清楚这个逻辑能省下大量翻权限的时间。6.2 登录与权限阶段的典型故障登录进去之后的操作失败多数和权限配置、chroot 或 SELinux 相关。500 OOPS: vsftpd: refusing to run with writable root inside chroot()前面提过加allow_writeable_chrootYES即可但更稳妥的做法是让用户根目录本身不可写把可写目录放到子目录里。550 Permission denied在切换目录时出现通常是目录的属主或模式不对。检查一遍ls -ld输出的属主、属组和权限位重点看那个目录有没有执行位x没有 x 权限连cd都进不去这个细节很多人会忽略看到 755 就觉得没问题但如果某个中间层级目录是 644依然进不去。553 Could not create file出现在上传时一般指向磁盘写权限或 SELinux。先看目录属主是不是guest_username对应的账号再看ausearch有没有拒绝记录。501 Syntax error in parameters or arguments这个报错信息本身说的是命令参数格式不对实际触发原因比较杂客户端发送了服务端不支持的命令、文件名里带了服务端不接受的字符、或者某些老旧客户端协商参数时用了服务端没开的能力。排查思路是先换一个客户端试试如果换了就好那是客户端兼容问题一般升级客户端或者关掉它的某些扩展选项就能解决如果换客户端依旧就看服务端日志里那条命令具体是什么再对照配置里相关功能的开关。6.3 传输阶段的丢包、断流与中文乱码传大文件传到一半断开先排除网络再看三个参数# 数据连接空闲超时单位秒大文件慢速传输可以适当调大 data_connection_timeout300 # 空闲会话超时 idle_session_timeout600 # 单个 IP 的最大连接数 max_per_ip10max_per_ip设太小会让多线程客户端频繁被拒设太大又容易被人当成下载加速器滥用10 到 20 是比较务实的值。中文乱码是另一个高频问题典型现象是 Windows 上传的中文文件名在 Linux 上变成问号或者 Linux 上的中文文件用某些客户端下载后名字乱掉。根因是字符集不一致vsftpd 默认按 UTF-8 处理文件名而一些老客户端默认用本地编码比如 GBK去解析。解决方向有两个优先在客户端侧处理FileZilla 的站点管理器里把字符集设成强制 UTF-8WinSCP 里把文件名编码设成 UTF-8。服务端侧某些版本支持utf8_filesystemYES但并不是所有发行版的包都带这个参数加了不生效反而会启动失败所以改之前先确认版本支持。提示中文乱码往往是上传端和下载端两侧编码不同造成的排查时两边都要看。单纯在服务端调整大概率解决不了客户端设置的优先级更高。7. 上线之后限速、审计与日常运维7.1 速率与并发控制的实际取值服务能跑起来只是开始不加约束的 FTP 很容易把带宽吃干净。几个关键参数# 本地用户最大传输速率单位字节/秒512000 约等于 4Mbps local_max_rate512000 # 全局最大客户端数 max_clients100 # 每个 IP 的最大连接数 max_per_ip20 # 最大并发数据传输数 max_per_ip20local_max_rate的单位容易搞错它填的是字节每秒不是比特每秒。想限到 8Mbps需要填 10485761024×1024。这个换算我在第一次配限速时就栽过当时填了 8000结果速度限制到了 8KB/s用户投诉传一个文件要半天排查一圈才发现是把比特和字节混了。限速要按业务分层。面向公网开放下载的服务建议给单用户限速避免一个人拖垮整条线内网协作的可以放开毕竟带宽是自己的。如果需要对不同用户设不同速率虚拟用户方案下可以在每个用户的独立配置文件里单独写local_max_rate非常灵活。7.2 日志与监控该怎么看vsftpd 的日志分两份传输日志和系统日志。传输日志默认在/var/log/xferlog或者配置xferlog_file指定的位置记录每个文件的传输时间、方向、大小、用户名做审计和用量统计就靠它。系统日志走 syslog用journalctl -u vsftpd看。一份日志记录长这样Mon Sep 9 10:23:41 2024 1 10.0.0.15 1024 /data/ftp/alice/a.zip b _ i r alice ftp 0 *字段依次是时间、传输耗时、客户端 IP、文件大小、文件名、传输类型、动作标志、方向、访问模式、用户名、服务名、认证方式、认证用户、完成状态。最后那个*表示成功如果是i就代表传输中断。用 awk 按用户名聚合一下就能算出每个账号的流量awk {sum[$14]$8} END {for (u in sum) print u, sum[u]/1024/1024 MB} /var/log/xferlog监控方面如果你的环境已经有监控系统重点盯三个指标21 端口的存活探测、并发连接数、异常登录频次。异常登录频次特别值得关注FTP 账号被暴力破解是常态日志里短时间内大量 530 就是信号。配合max_per_ip和强密码策略能挡掉绝大部分脚本小子。7.3 备份、迁移与安全底线最后说说长期运维。FTP 服务器的配置文件不多但清单要固定/etc/vsftpd.conf或/etc/vsftpd/整个目录、PAM 配置文件、虚拟用户数据库、以及每个用户的根目录数据。配置和数据要分开备份配置用版本管理或者配置管理工具存起来数据用常规的增量备份方案。迁移到新机器时我一般按这个顺序新机器装好同版本 vsftpd把配置目录整个拷过去重建虚拟用户数据库注意 db_load 生成的库在不同 Berkeley DB 版本间可能有兼容问题稳妥做法是拷明文重新生成再同步数据目录并保持属主一致最后切流量。整个过程里最容易出错的是数据目录的属主和 SELinux 上下文拷完之后一定要执行一次restorecon -Rv重新打标签。安全底线就三条账号密码必须强复杂度、不要用匿名写权限、定期清理不再使用的账号。虚拟用户方案里清理账号就是改明文文件、重建数据库、删掉对应的独立配置文件比系统用户方案干净得多。另外记得给服务器本身做好系统更新vsftpd 历史上出过几个影响不小的漏洞及时打补丁比任何花哨配置都管用。这套流程我在不同的项目里反复跑过最深的感受是FTP 服务的成败几乎不在服务端配置本身而在端口规划和账号模型这两个前置决策上。这两件事想清楚后面的配置就是填空想不清楚配出来的东西一定会在某个时刻以能登录但列不出目录的形式让你加班。