> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/di-34-zhang-wen-jian-chuan-shu-xie-yi-ftp/di-34.4-jie-vsftpd.md).

# 34.4 vsftpd

vsftpd（Very Secure FTP Daemon，即“非常安全的 FTP 守护进程”）以安全性为首要设计目标，在 Linux 系统中应用较为广泛。经测试表明，Windows 环境下的 FTP 客户端访问不会产生乱码。

## 安装 vsftpd

通过 pkg 安装：

```sh
# pkg install vsftpd-ssl pam_pwdfile
```

安装包说明：

| 名称           | 说明                                                      |
| ------------ | ------------------------------------------------------- |
| vsftpd-ssl   | 带 SSL 支持的 vsftpd 包                                      |
| pam\_pwdfile | 一个 PAM 模块，允许使用独立于系统账户的密码文件（类似 **/etc/passwd** 格式）验证用户身份 |

> **技巧**
>
> 在 FreeBSD 系统中，**/etc/passwd** 文件仅作兼容之用，实际认证使用的是相应的数据库文件。

通过 Ports 安装：

```sh
# cd /usr/ports/ftp/vsftpd/ && make install clean
# cd /usr/ports/security/pam_pwdfile/ && make install clean
```

观察安装输出：

```sh
[2/2] Installing vsftpd-ssl-3.0.5_2...
===> Creating groups
Using existing group 'ftp'
===> Creating users
Creating user 'ftp' with uid '14'
===> Creating homedir(s)
[2/2] Extracting vsftpd-ssl-3.0.5_2: 100%
```

vsftpd 会创建用户 `ftp`，查看用户 ftp 的 UID、GID 及所属组信息：

```sh
# id ftp
uid=14(ftp) gid=14(ftp) groups=14(ftp)
```

## 创建虚拟用户

新增系统用户：

```sh
# adduser
Username: ftptest
Full name:
Uid (Leave empty for default):
Login group [ftptest]: ftp # 注意此处
Login group is ftp. Invite ftptest into other groups? []:
Login class [default]:
Shell (sh csh tcsh nologin) [sh]: nologin # 注意此处
Home directory [/home/ftptest]:
Home directory permissions (Leave empty for default):
Enable ZFS encryption? (yes/no) [no]:
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password: # 注意此处，设置密码为 z
Enter password again:
Lock out the account after creation? [no]:
Username    : ftptest
Password    : *****
Full Name   :
Uid         : 1003
ZFS dataset : zroot/home/ftptest
Class       :
Groups      : ftp
Home        : /home/ftptest
Home Mode   :
Shell       : /usr/sbin/nologin
Locked      : no
OK? (yes/no) [yes]:
adduser: INFO: Successfully created ZFS dataset (zroot/home/ftptest).
adduser: INFO: Successfully added (ftptest) to the user database.
Add another user? (yes/no) [no]:
Goodbye!
```

已创建以下信息：

| 项目  | 值         |
| --- | --------- |
| 用户名 | `ftptest` |
| 密码  | `z`       |
| 组   | `ftp`     |

## 配置 pam\_pwdfile

创建 PAM 配置文件 **/etc/pam.d/vsftpd**：

```ini
auth required /usr/local/lib/pam_pwdfile.so pwdfile /usr/local/etc/vsftpd_login.db   # 使用 PAM 模块 pwdfile 做用户认证
account required /usr/lib/pam_permit.so                                           # 使用 PAM 模块 permit 做账户验证
```

创建密码数据库：

```sh
# echo "ftptest:$(openssl passwd -6)" >> /usr/local/etc/vsftpd_login.db
Password: # 输入密码 z
Verifying - Password: # 重复输入密码 z
```

以上命令向 vsftpd 登录数据库添加了用户 `ftptest` 并设置密码 `z`（仅供测试用，该密码并不安全！）。

后续添加新用户：

```sh
# echo "新用户名:$(openssl passwd -6)" >> /usr/local/etc/vsftpd_login.db
Password: # 输入新用户密码
Verifying - Password: # 重复输入新用户密码
```

其中，`-6`：强制使用基于 SHA-512 的 Crypt 哈希算法。

## vsftpd 配置文件

vsftpd 的主配置文件位于 **/usr/local/etc/vsftpd.conf**，可直接修改；同时提供了备用模板文件 **/usr/local/etc/vsftpd.conf.sample**。

将 **/usr/local/etc/vsftpd.conf** 文件配置修改为如下内容：

```ini
# /usr/local/etc/vsftpd.conf 示例配置文件
#
# 默认编译设置相当保守。此示例文件略微放宽了一些设置，使 FTP 守护进程更实用。
# 参阅 vsftpd.conf.5 可获取所有默认编译设置。
#
# 请注意：此示例文件不是 vsftpd 选项的详尽列表。
# 请阅读 vsftpd.conf.5 手册页，以全面了解 vsftpd 的功能。
#
# 禁止匿名 FTP 访问
anonymous_enable=NO
#
# 允许本地用户登录
local_enable=YES
#
# 启用 FTP 写操作
write_enable=YES
#
# 本地用户的默认 umask 值为 077。如果需要，可以将其更改为 022，
# 以满足用户需求。（大多数其他 FTP 服务的默认 umask 值）
# local_umask=022
#
# 取消注释以允许匿名 FTP 用户上传文件。仅当启用了上面的全局写入功能时，才会生效。
# 此外，还需要为 FTP 用户创建一个可写的目录。
# anon_upload_enable=YES
#
# 如果希望匿名 FTP 用户能够创建新目录，取消注释此项。
# anon_mkdir_write_enable=YES
#
# 启用目录消息 - 在远程用户进入某个目录时，给出相关的消息。
dirmessage_enable=YES
#
# 启用上传/下载日志记录。
xferlog_enable=YES
#
# 确保 PORT 传输连接来自端口 20 (ftp-data)。
connect_from_port_20=YES

local_root=/home/ftp
anon_root=/home/ftp
#
# 如果需要，可以安排上传的匿名文件由不同的用户拥有。注意！不建议将上传文件归属于 "root" 用户！
# chown_uploads=YES
# chown_username=whoever
#
# 可覆盖日志文件的存放位置。默认路径如下。
# xferlog_file=/var/log/vsftpd.log
#
# 如果需要，可使用标准 ftpd xferlog 格式的日志文件。
# 注意，在这种情况下，默认的日志文件位置为 /var/log/xferlog。
# xferlog_std_format=YES
#
# 空闲会话超时时间（秒）
idle_session_timeout=1800
#
# 数据连接超时时间（秒）
data_connection_timeout=1200
#
# 建议在系统上定义一个唯一的用户，供 FTP 服务器使用，作为完全隔离且没有特权的用户。
# nopriv_user=ftpsecure
#
# 启用此选项，服务器将识别异步 ABOR 请求。由于代码较为复杂，安全性方面不推荐启用此项。
# 如果不启用，某些旧的 FTP 客户端可能会遇到问题。
# async_abor_enable=YES
#
# 在默认情况下，服务器会假装允许 ASCII 模式，但实际上会忽略该请求。
# 打开以下选项，服务器将在 ASCII 模式下对文件进行 ASCII 格式的修改。
# 注意：在某些 FTP 服务器中，ASCII 支持允许通过 "SIZE /big/file" 命令在 ASCII 模式下发起拒绝服务攻击（DoS）。vsftpd 已经预测到此攻击并始终保持安全，报告的是原始文件的大小。
# ASCII 格式修改是该协议的一项糟糕特性。
# ascii_upload_enable=YES
# ascii_download_enable=YES
#
# 自定义登录横幅信息
ftpd_banner=Welcome to blah FTP service.
#
# 可指定一个禁止匿名邮件的地址列表文件，有助于防范某些 DoS 攻击
# deny_email_enable=YES
# (默认值如下)
# banned_email_file=/etc/vsftpd.banned_emails
#
# 指定需要 chroot 的用户列表。若 chroot_local_user 为 YES，则该列表变为无需 chroot 的用户列表
# (警告！chroot 可能非常危险。如果使用 chroot，请确保用户对 chroot 目录的顶级目录没有写权限)
# chroot_local_user=NO 即 chroot_list_file 文件中用户将会被限制在 local_root 指定的目录中
chroot_local_user=NO
chroot_list_enable=YES
# (默认值如下)
chroot_list_file=/usr/local/etc/vsftpd.chroot_list
allow_writeable_chroot=YES
#
# 启用 ls 的递归选项 "-R"。默认禁用，以防大站点产生过高 I/O 负载
# ls_recurse_enable=YES
#
# 当启用 "listen" 指令时，vsftpd 以独立模式运行，并监听 IPv4 套接字。此指令不能与 listen_ipv6 指令同时使用。
listen=YES
#
# 此指令启用监听 IPv6 套接字。如果要同时监听 IPv4 和 IPv6 套接字，则必须使用两个不同的配置文件运行两个 vsftpd 实例。
# 确保其中一个 listen 选项被注释掉！！
# listen_ipv6=YES

# 安全的 chroot Jail 目录路径，该目录必须为空且不可被 FTP 用户写入
secure_chroot_dir=/usr/local/share/vsftpd/empty

# 后台运行时的 PID 文件路径，默认不创建 PID 文件
# pid_file=/var/run/vsftpd.pid

background=YES

# 使用本地时间
use_localtime=YES
```

官网文档参见 [VSFTPD.CONF](https://security.appspot.com/vsftpd/vsftpd_conf.html)，中文翻译可参考金步国的 [vsftpd.conf 中文版](https://www.jinbuguo.com/vsftpd/vsftpd.conf.html)。

## `vsftpd.chroot_list` 文件

创建并编辑 **/usr/local/etc/vsftpd.chroot\_list** 文件，将用户 `ftptest` 加入其中。

## 创建路径

创建 FTP 目录并设置权限：

```sh
# mkdir -p /home/ftp              # 创建 FTP 用户的主目录
# chown -R ftp:ftp /home/ftp     # 设置目录所有者和所属组为 ftp
# chmod -R 775 /home/ftp         # 设置目录权限为 775，允许同组用户读写
```

## 服务管理

配置完成后，启动并管理 vsftpd 服务：

```sh
# service vsftpd enable    # 设置 vsftpd 服务开机启动
# service vsftpd start     # 启动 vsftpd 服务
# service vsftpd stop      # 停止 vsftpd 服务
# service vsftpd restart   # 重启 vsftpd 服务
```

使用用户名 `ftptest`，密码 `z` 登录 FTP。

vsftpd 日志文件位于 **/var/log/vsftpd.log**。

## 参考文献

angeloma. How to set up vsftpd on FreeBSD 12?\[EB/OL]. (2020-02-13)\[2026-03-25]. <https://www.osradar.com/how-to-set-up-vsftpd-on-freebsd-12/>. 介绍在 FreeBSD 上安装配置 vsftpd 服务的步骤。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/di-34-zhang-wen-jian-chuan-shu-xie-yi-ftp/di-34.4-jie-vsftpd.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
