本章最后一节,装一个专门用来传文件的服务器(FTP)。 但本节最重要的那句结论不是命令,而是:在 2026 年,你要传文件,多半根本不需要装 FTP——上一章 3-6 学的 SFTP 已经够用,而且安全得多。先理解这个「为什么」,再学怎么装。
3-6 讲的是「怎么把文件送过去」(SFTP、scp、Samba 五条路);本节讲的是「怎么专门架一个传文件的服务器出来」——方向相反:前者是「你去拿」,后者是「它开个门等着别人来存取」。
从本章脉络看:5-1 装接待、5-2 装厨师、5-3 装档案室,5-4 是给这台服务器开一个「后门货梯」,专门用来搬文件。
读完你会有个更重要的收获:知道什么时候「不该用这项技术」。
一、先把三个词分清楚(最容易混的地方)
这三样名字很像,但完全不是一回事:
| 名字 | 全称 | 走哪个端口 | 加密吗 | 一句话 |
|---|---|---|---|---|
| FTP | File Transfer Protocol | 21 | 不加密 | 最老的文件传输协议,账号密码和文件内容全程明文裸奔 |
| FTPS | FTP over SSL/TLS | 21(可另配) | 加密 | 给 FTP 套了层 SSL,但客户端支持不一、配置麻烦 |
| SFTP | SSH File Transfer Protocol | 22 | 加密 | 名字像 FTP,其实完全是另一套东西——它是跑在 SSH 上的 |
SFTP 不是「安全的 FTP」,而是 SSH 的一个功能。 你不是「装了 FTP 再把安全打开」——SFTP 靠的是你早就装好的 SSH 服务(第二章开机时开的那一项),什么软件都不用装。 这就是为什么 3-6 把 SFTP 列为「首推」:它复用你已有的加密通道,零额外安装、零额外端口、零额外漏洞。
再看一个现成的信号:
你或许记得以前能在浏览器地址栏输 ftp://... 直接看文件列表。
现在不行了——主流浏览器(Chrome 88 起、Firefox 90 起)已经彻底移除 FTP 支持。
一个协议被浏览器整个删掉,说明它在安全上已经不达标了。这是「这项技术正在退场」最直白的证据。
那本节为什么还要学? 两个理由:
- 对接老设备:某些老设备、老软硬件系统只会说 FTP,你得配合它;
- 看懂运维现场:
vsftpd在实际工作中仍会碰到,认识它、知道它的坑在哪,比假装它不存在更有用。
二、FTP 最反直觉的一点:它要开两个连接
学 FTP 绕不过这个设计,它也是 FTP 出错率最高的原因:
① 控制连接:端口 21 —— 全程都在,用来「说话」(我登录、我要 ls、我要取 xxx)
② 数据连接:另一个端口 —— 每次传文件时才临时建立,传完就关
把 FTP 想成打电话叫外卖:电话(21 端口)一直通着用来沟通;但外卖不通过电话送——它得另走一条路(数据连接)送到你家门口。 问题来了:如果那条「送货的路」没提前说好走哪,楼下的门卫(防火墙/路由器)就会把它拦住。
于是就有两种模式:
| 模式 | 谁发起数据连接 | 现状 |
|---|---|---|
| 主动模式(Active) | 服务器回头连客户端 | 客户端有防火墙时基本行不通,几乎淘汰 |
| 被动模式(Passive) | 客户端连服务器 | 实际全靠它,FTP 教程里出问题多半在这 |
被动模式的关键:服务器要告诉客户端「你来连我的这个端口」。如果这个端口是随机挑的,防火墙根本不知道要放哪些端口——所以:
必须在配置里把被动模式的端口范围「框定」下来(比如 40000~40100),然后只放行这一段。
不设的话现象很典型:能连上、能登录,但一 ls 就卡住、或者传文件一直超时。九成的「FTP 连上了但用不了」都是这个原因。
三、装 vsftpd
vsftpd = Very Secure FTP Daemon(名字里就写着「非常安全」,是 Linux 上最常用的 FTP 服务软件)。
sudo apt update
sudo apt install vsftpd -y
systemctl status vsftpd --no-pager
期望看到 Active: active (running)。
先备份配置(好习惯,改坏了能退回来):
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
ls -l /etc/vsftpd.conf*
四、改配置:/etc/vsftpd.conf 六个关键项
sudo nano /etc/vsftpd.conf
这个文件里绝大多数行前面都有 #(表示不生效)。你要做的是:找到对应行,去掉前面的 #,把值改成下面这样。
| 配置项 | 设成 | 作用 | 不改的后果 |
|---|---|---|---|
anonymous_enable |
NO |
禁止匿名登录 | 任何人都能进,这是后门 |
local_enable |
YES |
允许系统用户登录 | 谁都登录不了 |
write_enable |
YES |
允许上传/删除 | 只能下载不能上传(很多人卡在这) |
local_umask |
022 |
上传文件的默认权限 | 上传的文件别人读不到 |
chroot_local_user |
YES |
把用户锁在自己的家目录 | 登录后能翻遍整个系统 |
allow_writeable_chroot |
YES |
允许被锁的目录可写 | 新版 vsftpd 会直接拒绝登录(报 500) |
allow_writeable_chroot=YES 在老教程里常常没有——因为老版 vsftpd 不检查这个。
新版出于安全考虑,如果被 chroot 的目录是可写的就直接拒绝登录,你会看到莫名其妙的 500 OOPS: vsftpd: refusing to run with writable root inside chroot()。
照着加了就好——这是本节最典型的「老教程缺一行」的坑。
然后追加被动模式的端口范围(文件末尾加上这三行):
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100
如果要从外网连(本课不推荐),还得加 pasv_address=你的公网IP——否则服务器会告诉客户端一个内网地址,客户端当然连不上。
局域网内用不到这一行。
保存(Ctrl + O → 回车 → Ctrl + X),重启服务:
sudo systemctl restart vsftpd
systemctl status vsftpd --no-pager | head -5
五、建一个专用 FTP 用户(别用主账号)
和上一节数据库那条铁律同一个道理:FTP 用户一旦泄露,不该能祸及你的主账号。
# ① 建一个新用户(会问你设密码,其他信息可以一路回车跳过)
sudo adduser ftpuser
# ② 给他一个专门放文件的目录
sudo mkdir -p /home/ftpuser/files
# ③ 目录的主人改成他
sudo chown -R ftpuser:ftpuser /home/ftpuser/files
因为上面设了 chroot_local_user=YES,用户登录后看到的世界以他的家目录为根。
所以「上传的文件放在 files/ 子目录」这种做法,能让共享内容和他自己的私人配置文件(.bashrc 之类)隔开——既整洁也更安全。
登录凭据就是:用户名 ftpuser + 你刚设的密码。
六、验收:本机先测,再从 Windows 测
第一步,在树莓派上自测(不用管网络,先证明服务本身没问题):
ftp localhost
按提示输入用户名 ftpuser 和密码,然后:
ftp> ls ← 应该能列出目录
ftp> bye ← 退出
看到 ls 能列出内容,就说明 vsftpd 本身工作正常。
第二步,从 Windows 上测(用图形客户端最直观):
- 打开 FileZilla(3-6 装过的那个),协议选 FTP,主机填树莓派 IP,端口
21,填用户名密码,点「快速连接」; - 期望:右侧能看到
/files目录,能往里拖文件。
排障对照表(FTP 的错基本就这几类):
| 现象 | 大概率原因 |
|---|---|
| 能连上、能登录,但一列目录就卡住/超时 | 被动模式端口没设,或防火墙没放行那一段(本节第二大坑) |
530 Login incorrect |
用户名或密码错;或该用户被系统禁止登录 |
500 OOPS: refusing to run with writable root |
缺 allow_writeable_chroot=YES |
上传时报 550 Permission denied |
忘了 write_enable=YES,或目录权限不对 |
| 上传成功但文件权限怪 | local_umask 设置问题 |
| 本机能用、Windows 连不上 | IP 写错、不在同一网段、或路由器隔离了设备 |
七、动手 Demo:从 Windows 传一个文件上去
目标:把一个文件从 Windows 送到树莓派的 FTP 目录,再从树莓派这边确认它真的到了。
# ① 树莓派这边:先记下当前目录内容,作为「传之前」的对照
ls -l /home/ftpuser/files
② 在 Windows 上用 FileZilla 连上(协议 FTP、端口 21)
③ 把任意一个文件拖到右侧的 files 目录里
# ④ 树莓派这边:再看一次目录
ls -l /home/ftpuser/files
验收(三条都做到):
ls输出里出现了你刚拖上来的那个文件;- 文件的主人写着
ftpuser(说明确实是通过 FTP 用户写上来的); - 反过来试一次下载:从 FileZilla 里把文件拖回桌面,能打开。
再看一眼日志(出问题时全靠它):
sudo tail -f /var/log/vsftpd.log
# 若日志没内容,试着看系统日志:
sudo journalctl -u vsftpd -n 30 --no-pager
读结果:
- 上传成功但树莓派这边
ls看不到 → 看 FileZilla 里显示的是不是/files目录(可能传到家目录去了); - 传输中途卡死 → 回到被动模式端口那条(第七节表格第一行);
- 完全连不上 →
systemctl status vsftpd先确认服务活着。
八、30 秒实验:对比一下「明文」与「加密」
这是本节最有说服力的实验——亲眼看见 FTP 的密码在网络上裸奔。
# ① 树莓派上抓一下 FTP 的登录过程(Ctrl+C 结束)
sudo tcpdump -i any port 21 -A -c 20
② 同时在 Windows 上用 FileZilla 登录一次
期望:在 tcpdump 的输出里,能直接看到 USER ftpuser 和 PASS 你的密码 这两行明文。
接着换 SFTP 做同样的事:
sudo tcpdump -i any port 22 -A -c 20
② 在 FileZilla 里改用 SFTP(协议选 SFTP、端口 22)登录一次
期望:输出全是一串看不懂的乱码——因为它是加密的。
同一个网络里,有人在抓包就能拿到你 FTP 的账号密码。 所以:能用 SFTP 就用 SFTP,FTP 只在「对方设备只支持 FTP」时才用,且绝不要在公网上用。
九、可选:给 FTP 套一层加密(FTPS)
如果确实必须用 FTP、又在意安全,可以让它走 TLS(这就变成了 FTPS):
# ① 生成一张自签证书
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/vsftpd.key \
-out /etc/ssl/private/vsftpd.pem
在 vsftpd.conf 里补上:
ssl_enable=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.key
force_local_data_ssl=YES
force_local_logins_ssl=YES
sudo systemctl restart vsftpd
说实话:配置比 SFTP 麻烦得多,安全性却不如 SFTP(SFTP 是现成的、成熟的、走标准 SSH 的)。 本节列出来,是为了让你在「必须用 FTP」时不至于只能裸奔——但首选永远是 SFTP。
十、安全红线(本节必读)
- 绝不要把 21 端口暴露到公网。FTP 是明文协议,暴露就等于把用户名密码贴在门外;如果一定要外网传文件,用 SFTP over SSH 或 VPN,这是 3-6 那条红线的延续;
- 绝不使用
anonymous_enable=YES(匿名访问)。这是历史上最经典的服务器后门,本课一律NO; - 绝不给 FTP 用户系统管理权限。它只该在自己家目录里搬文件——不要把它加进
sudo组(4-3 讲过usermod -aG的风险)。
关于防火墙:Raspberry Pi OS 默认没有安装 UFW、也没有启用防火墙,所以本课不需要额外放行端口。
但你要知道如果将来开了防火墙,要放行的是这三样:
# 仅在你自己装了防火墙(如 ufw)时才需要
sudo ufw allow 21/tcp # 控制连接
sudo ufw allow 20/tcp # 主动模式的数据连接(老式)
sudo ufw allow 40000:40100/tcp # 被动模式的数据连接(关键)
中间那行被动端口的范围,必须和 vsftpd.conf 里写的一致——两边对不上,症状就是上面说的「连得上、用不了」。
十一、常见误区
- 「SFTP 是 FTP 的加密版」——错。两者原理完全不同:FTP 是独立协议(21 端口),SFTP 是 SSH 的一个功能(22 端口)。装 FTP 并不会让你得到 SFTP。
- 「现在传文件都得装 FTP 服务器」——反了。首选 SFTP(零额外安装、加密、复用 SSH)。FTP 只在对接只支持 FTP 的老设备时才用。
- 「能登录就说明配好了」——不一定。FTP 的典型故障是登录正常、一列目录就卡死(被动模式端口没框定)。验收必须做到「能 ls、能上传」才算完。
- 「
write_enable默认是开的」——默认是关的(注释状态)。这就是很多人「能下载不能上传」的原因。 - 「用主账号登录 FTP 更方便」——不安全。主账号通常能
sudo,一旦 FTP 密码泄露等于交出机器。永远用专用账号。 - 「顺手在路由器上转个 21 端口,出差也能用」——这是本节最危险的操作。明文协议暴露公网,等于公开你的密码。
/etc/init.d/vsftpd restart—— 老式服务管理,现在是sudo systemctl restart vsftpd;- 缺
allow_writeable_chroot=YES—— 老教程大多没有这一行,新版 vsftpd 会因此拒绝登录(报 500 OOPS); - 浏览器
ftp://直接看文件 —— 浏览器已彻底移除 FTP 支持,这条路没有了; - 不设被动模式端口范围 —— 老教程常跳过,而这恰恰是现在最常出问题的地方(因为现在路由器与防火墙默认都拦)。
自测三问(点开对答案)
1. SFTP 和 FTP 是什么关系?(**没有关系**。FTP 是独立的明文协议,走 21 端口;SFTP 是 **SSH 的一个功能**,走 22 端口、默认加密。名字像只是历史原因) 2. 「能登录 FTP,但一列目录就卡住」最可能是什么原因?(**被动模式没有设定端口范围**(或防火墙没放行那一段)。FTP 的数据连接要另开端口,服务器随便挑一个就会被拦) 3. 本课的立场是什么——要用 FTP 传文件吗?(**优先用 SFTP**,因为加密、零额外安装、复用已有 SSH。**FTP 只在对接只支持 FTP 的老设备时才用,且绝不暴露公网**)- ☑ 第五章 完结 —— 教材这一章已读完四节:装上 Apache 让树莓派成为一台 Web 服务器、接上 PHP 让它会「现算」、接上 MariaDB 数据库让它能「记东西」、最后架起 FTP 服务(并想清它为什么多半不必装)——LAMP 这套后台,你已经在自己的板子上跑通了
- ☑ 第六章 开发 Python 程序 —— 已完结:Python 列表与字符串(开始给这块板子写代码:认清 Python、学会在树莓派上写与跑程序、掌握变量与运算符、让程序会判断会循环、用函数与模块整理代码并装库、最后能处理列表与字符串)
相关笔记
- 安装设置 MySQL 数据库系统 —— 上一节:本节「专用账号」的思路与数据库那条铁律同源
- 架设 Web 服务器 —— 本章起点:服务器是角色不是硬件
- 认识 Python 语言 —— 下一章起点:换一门语言,开始自己写程序
- Python 列表与字符串 —— 下一章小结:处理"一串一串"的数据(传感器读数就靠它)
- 在 Windows 和树莓派之间交换文件 —— SFTP 早就学过了:本节那句「优先 SFTP」的出处
- 网络连接与蓝牙装置 —— 「绝不把端口转发到公网」这条红线的原文
- Linux 的用户与文件权限指令 —— 建专用用户、改目录属主用的就是这里
- 🍓 树莓派 · 索引 —— 全课路线图