🍓 第五章 使用树莓派架设服务器
📄 一句话概括

本章最后一节,装一个专门用来传文件的服务器(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 下架了

你或许记得以前能在浏览器地址栏输 ftp://... 直接看文件列表。 现在不行了——主流浏览器(Chrome 88 起、Firefox 90 起)已经彻底移除 FTP 支持。 一个协议被浏览器整个删掉,说明它在安全上已经不达标了。这是「这项技术正在退场」最直白的证据。

那本节为什么还要学? 两个理由:

  1. 对接老设备:某些老设备、老软硬件系统只会说 FTP,你得配合它;
  2. 看懂运维现场:vsftpd 在实际工作中仍会碰到,认识它、知道它的坑在哪,比假装它不存在更有用。

二、FTP 最反直觉的一点:它要开两个连接

学 FTP 绕不过这个设计,它也是 FTP 出错率最高的原因:

① 控制连接:端口 21 —— 全程都在,用来「说话」(我登录、我要 ls、我要取 xxx)
② 数据连接:另一个端口 —— 每次传文件时才临时建立,传完就关
💡 打个比方

把 FTP 想成打电话叫外卖:电话(21 端口)一直通着用来沟通;但外卖不通过电话送——它得另走一条路(数据连接)送到你家门口。 问题来了:如果那条「送货的路」没提前说好走哪,楼下的门卫(防火墙/路由器)就会把它拦住。

于是就有两种模式:

模式 谁发起数据连接 现状
主动模式(Active) 服务器回头连客户端 客户端有防火墙时基本行不通,几乎淘汰
被动模式(Passive) 客户端连服务器 实际全靠它,FTP 教程里出问题多半在这

被动模式的关键:服务器要告诉客户端「你来连我的这个端口」。如果这个端口是随机挑的,防火墙根本不知道要放哪些端口——所以:

🚨 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
📝 为什么是 `/home/ftpuser/files`

因为上面设了 chroot_local_user=YES,用户登录后看到的世界以他的家目录为根。 所以「上传的文件放在 files/ 子目录」这种做法,能让共享内容和他自己的私人配置文件(.bashrc 之类)隔开——既整洁也更安全。

登录凭据就是:用户名 ftpuser + 你刚设的密码。

六、验收:本机先测,再从 Windows 测

第一步,在树莓派上自测(不用管网络,先证明服务本身没问题):

ftp localhost

按提示输入用户名 ftpuser 和密码,然后:

ftp> ls          ← 应该能列出目录
ftp> bye         ← 退出

看到 ls 能列出内容,就说明 vsftpd 本身工作正常。

第二步,从 Windows 上测(用图形客户端最直观):

排障对照表(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

验收(三条都做到):

  1. ls 输出里出现了你刚拖上来的那个文件;
  2. 文件的主人写着 ftpuser(说明确实是通过 FTP 用户写上来的);
  3. 反过来试一次下载:从 FileZilla 里把文件拖回桌面,能打开。

再看一眼日志(出问题时全靠它):

sudo tail -f /var/log/vsftpd.log
# 若日志没内容,试着看系统日志:
sudo journalctl -u vsftpd -n 30 --no-pager

读结果:

八、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。

十、安全红线(本节必读)

🚨 三条红线
  1. 绝不要把 21 端口暴露到公网。FTP 是明文协议,暴露就等于把用户名密码贴在门外;如果一定要外网传文件,用 SFTP over SSH 或 VPN,这是 3-6 那条红线的延续;
  2. 绝不使用 anonymous_enable=YES(匿名访问)。这是历史上最经典的服务器后门,本课一律 NO;
  3. 绝不给 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 里写的一致——两边对不上,症状就是上面说的「连得上、用不了」。

十一、常见误区

  1. 「SFTP 是 FTP 的加密版」——错。两者原理完全不同:FTP 是独立协议(21 端口),SFTP 是 SSH 的一个功能(22 端口)。装 FTP 并不会让你得到 SFTP。
  2. 「现在传文件都得装 FTP 服务器」——反了。首选 SFTP(零额外安装、加密、复用 SSH)。FTP 只在对接只支持 FTP 的老设备时才用。
  3. 「能登录就说明配好了」——不一定。FTP 的典型故障是登录正常、一列目录就卡死(被动模式端口没框定)。验收必须做到「能 ls、能上传」才算完。
  4. 「write_enable 默认是开的」——默认是关的(注释状态)。这就是很多人「能下载不能上传」的原因。
  5. 「用主账号登录 FTP 更方便」——不安全。主账号通常能 sudo,一旦 FTP 密码泄露等于交出机器。永远用专用账号。
  6. 「顺手在路由器上转个 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 的老设备时才用,且绝不暴露公网**)

相关笔记