Skip to content

22.2 Pure-FTPd(基于 MySQL)

22.2.1 Pure-FTPd 不支持中文环境

Pure-FTPd 已移除 RFC 2640 支持,该 RFC 定义了 FTP 协议的国际化框架。在 Windows 系统中使用 FTP 命令行访问非英文字符文件时可能出现乱码。具体变更可参见 Pure-FTPd 1.0.48 版本发布公告。

启用 UTF-8 编码的示例如下:

powershell
ftp> quote opts utf8 on
504 Unknown command

在 FreeBSD 中使用命令行或 WinSCP 等客户端测试 Pure-FTPd 不会出现乱码问题。

22.2.2 安装 Pure-FTPd

使用 pkg 安装的 Pure-FTPd 不包含数据库支持,需通过 Ports 安装来启用 MySQL 集成。

sh
# cd /usr/ports/ftp/pure-ftpd
# make config

在配置过程中选择 MYSQL,其余选项保持默认值并确认。

配置 Port pure-ftpd

sh
# make install clean

22.2.3 配置文件

配置文件需先复制示例文件,再编辑实际配置。配置文件为:/usr/local/etc/pure-ftpd.conf

22.2.3.1 生成配置文件

复制示例配置文件为实际使用的配置文件:

sh
# cp /usr/local/etc/pure-ftpd.conf.sample /usr/local/etc/pure-ftpd.conf          # 复制 Pure-FTPd 配置示例文件为默认配置
# cp /usr/local/etc/pureftpd-mysql.conf.sample /usr/local/etc/pureftpd-mysql.conf   # 复制 Pure-FTPd MySQL 配置示例文件为默认配置

配置文件结构如下:

sh
/usr/local/etc/
├── pure-ftpd.conf.sample      # Pure-FTPd 配置示例文件
├── pure-ftpd.conf             # Pure-FTPd 主配置文件
├── pureftpd-mysql.conf.sample # Pure-FTPd MySQL 配置示例文件
└── pureftpd-mysql.conf        # Pure-FTPd MySQL 配置文件

22.2.3.2 MySQL 集成配置

编辑 /usr/local/etc/pure-ftpd.conf 文件,修改相关配置项以启用 MySQL 认证:

ini
# 兼容 IE 等非标准化的 FTP 客户端

BrokenClientsCompatibility yes

# 被动连接响应的端口范围。

PassivePortRange 30000 50000

# 允许认证用户登录的最小 UID。
# 例如,值为 100 会阻止所有 UID 小于 100 的用户登录。
# 如果希望 root 能够登录,请使用 0。

MinUID 2000

# 仅允许认证用户进行 FXP 传输。

AllowUserFXP yes

# 如果不注释此项,日志中将找不到 ftp 用户的提示信息

# AntiWarez                    yes

# 用户主目录不存在时,自动创建

CreateHomeDir yes

# MySQL 配置文件(参见 README.MySQL)

MySQLConfigFile /usr/local/etc/pureftpd-mysql.conf

22.2.4 配置 MySQL

本节以 MySQL 8.x 为例。

请参照其他相关章节安装配置 MySQL 8.x。

22.2.4.1 创建数据库

创建 Pure-FTPd 使用的数据库和用户表:

sql
CREATE DATABASE pureftpd;   -- 创建数据库 pureftpd
USE pureftpd;                -- 选择使用 pureftpd 数据库

DROP TABLE IF EXISTS `users`;  -- 如果存在 users 表则删除
CREATE TABLE `users` (
   `User` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,  -- 用户名,主键
   `Password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,  -- 密码
   `Uid` int(11) NOT NULL DEFAULT -1 COMMENT '用户 ID',  -- 用户 ID
   `Gid` int(11) NOT NULL DEFAULT -1 COMMENT '用户组 ID',  -- 用户组 ID
   `Dir` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,  -- 用户目录
   `quotafiles` int(11) NULL DEFAULT 500,  -- 文件数量配额
   `quotasize` int(11) NULL DEFAULT 30,  -- 存储空间配额
   `ulbandwidth` int(11) NULL DEFAULT 80,  -- 上传带宽限制
   `dlbandwidth` int(11) NULL DEFAULT 80,  -- 下载带宽限制
   `ipaddress` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '*',  -- 限制 IP 地址
   `comment` varchar(255) NULL DEFAULT NULL,  -- 备注
   `status` tinyint(4) NULL DEFAULT 1,  -- 用户状态
   `ulratio` int(11) NULL DEFAULT 1,  -- 上传比例
   `dlratio` int(11) NULL DEFAULT 1,  -- 下载比例
   PRIMARY KEY (`User`) USING BTREE  -- 设置主键为 User
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=Dynamic;  -- 表引擎和字符集配置

22.2.4.2 创建数据库登录用户及设置密码

创建用于连接数据库的 Pure-FTPd 专用用户:

sql
-- 请将 'your_secure_password' 替换为强密码
CREATE USER 'pftp'@'localhost' IDENTIFIED BY 'your_secure_password';   -- 创建 MySQL 用户 pftp,允许从本地主机连接
GRANT SELECT, INSERT, UPDATE, DELETE ON pureftpd.* TO 'pftp'@'localhost';   -- 授予 pftp 用户对 pureftpd 数据库的增删改查权限
FLUSH PRIVILEGES;   -- 刷新权限,使配置立即生效

测试数据库连接:

sh
# mysql -u pftp -p -h localhost pureftpd

22.2.4.3 配置文件

/usr/local/etc/pureftpd-mysql.conf 文件完整示例:

ini
##############################################
#                                            #
# 示例 Pure-FTPd 的 MySQL 配置文件。         #
# 详细说明请参阅 README.MySQL。              #
#                                            #
##############################################

# MYSQLServer 数据库服务器地址
MYSQLServer     127.0.0.1

# MYSQLServer 数据库服务器端口
MYSQLPort       3306

# 可选:如果数据库服务器运行在本机,指定 mysql.sock 的路径。
MYSQLSocket     /tmp/mysql.sock

# 数据库用户名
MYSQLUser       pftp

# 数据库密码
MYSQLPassword   <你的数据库密码>

# 数据库名
MYSQLDatabase   pureftpd

# 密码加密方式(此处为明文)
# 有效值包括:“cleartext”(明文)、“argon2”、“scrypt”、“crypt” 和 “any”
MYSQLCrypt      cleartext

# 以下设置中的字符串部分在运行时会被替换:
#
# \L 会被替换为尝试认证的用户名。
# \I 会被替换为用户连接到的 IP 地址。
# \P 会被替换为用户连接到的端口号。
# \R 会被替换为用户来源的 IP 地址。
# \D 会被替换为远程 IP 地址的长整数形式。
#
# 使用这些替换字符串可以执行非常复杂的查询,特别适用于虚拟主机设置。

# 用于获取密码的 SQL 查询语句
MYSQLGetPW      SELECT Password FROM users WHERE User='\L'

# 用于获取系统用户名或 UID 的 SQL 查询语句
MYSQLGetUID     SELECT Uid FROM users WHERE User='\L'

# 默认 UID - 设置后将覆盖 MYSQLGetUID 的查询结果
MYSQLDefaultUID 2000

# 用于获取系统用户组名或 GID 的 SQL 查询语句
MYSQLGetGID     SELECT Gid FROM users WHERE User='\L'

# 默认 GID - 设置后将覆盖 MYSQLGetGID 的查询结果
MYSQLDefaultGID 2000

# 用于获取用户主目录的 SQL 查询语句
MYSQLGetDir     SELECT Dir FROM users WHERE User='\L'

# 可选:用于获取最大文件数的查询(虚拟配额支持需开启)
MySQLGetQTAFS  SELECT QuotaFiles FROM users WHERE User='\L'

# 可选:用于获取最大磁盘使用量(单位为 MB,需要虚拟配额支持)
MySQLGetQTASZ  SELECT QuotaSize FROM users WHERE User='\L'

# 可选:上传/下载比率,服务器需支持比率功能
MySQLGetRatioUL SELECT ULRatio FROM users WHERE User='\L'
MySQLGetRatioDL SELECT DLRatio FROM users WHERE User='\L'

# 可选:带宽限制,单位为 KB/s,服务器需支持带宽限制功能
MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User='\L'
MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User='\L'

# 启用 ~ 路径扩展。切勿盲目启用,除非满足以下条件:
# 1) 明确了解其作用。
# 2) 实际用户与虚拟用户一致。
# MySQLForceTildeExpansion 1

# 如果使用事务型存储引擎,可以启用 SQL 事务以避免竞态条件。
# 如果使用传统的 MyISAM 引擎,请保持此项注释。
# MySQLTransactions On

22.2.4.4 添加 FTP 组和用户

警告

使用数据库后,pure-pw 命令将不再生效。

创建系统用户和组,供虚拟 FTP 用户继承权限:

sh
# pw groupadd ftpgroup -g 2000   # 创建用户组 ftpgroup,GID 为 2000
# pw useradd ftpuser -u 2001 -g 2000 -s /sbin/nologin -w no -d /home/pureftp -c "VirtualUser Pure-FTPd" -m   # 创建虚拟 FTP 用户 ftpuser,UID 2001,主目录 /home/pureftp,不允许登录系统,自动创建主目录

添加 FTP 登录用户,需手动写入 MySQL 数据库。以下示例创建用户 test,密码为 test2

sql
USE pureftpd;   -- 选择 pureftpd 数据库
INSERT INTO `users` (`User`, `Password`, `Uid`, `Gid`, `Dir`, `quotafiles`, `quotasize`, `ulbandwidth`, `dlbandwidth`, `ipaddress`, `comment`, `status`, `ulratio`, `dlratio`)
VALUES ('test', 'test2', 2001, 2000, '/home/pureftp/www', 500, 30, 80, 80, '*', NULL, 1, 1, 1);   -- 向 users 表中插入一个测试用户记录

注意

写入表中的 UidGid 必须与此前通过 pw useradd 创建的用户保持一致。

技巧

其设计思路是:数据库中的虚拟用户继承 pw useradd 所创建用户的权限及 UID/GID,并通过数据库中的用户信息进行 FTP 文件操作。

实际操作示例:

sql
root@localhost [(none)]> show databases;	-- 显示当前 MySQL 服务器上的所有数据库列表
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| pureftpd           |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
root@localhost [pureftpd]> USE pureftpd;   -- 选择 pureftpd 数据库作为当前操作的数据库
Database changed
root@localhost [pureftpd]> INSERT INTO `users` (`User`, `Password`, `Uid`, `Gid`, `Dir`, `quotafiles`, `quotasize`, `ulbandwidth`, `dlbandwidth`, `ipaddress`, `comment`, `status`, `ulratio`, `dlratio`)
    -> VALUES ('test', 'test2', 2001, 2000, '/home/pureftp/www', 500, 30, 80, 80, '*', NULL, 1,1, 1);
Query OK, 1 row affected (0.01 sec)
root@localhost [pureftpd]> select * from users;   -- 查询 users 表中的所有记录
+------+----------+------+------+-------------------+------------+-----------+-------------+-------------+-----------+---------+--------+---------+---------+
| User | Password | Uid  | Gid  | Dir               | quotafiles | quotasize | ulbandwidth | dlbandwidth | ipaddress | comment | status | ulratio | dlratio |
+------+----------+------+------+-------------------+------------+-----------+-------------+-------------+-----------+---------+--------+---------+---------+
| test | test2    | 2001 | 2000 | /home/pureftp/www |        500 |        30 |          80 |    80 | *         |    NULL |      1 |       1 |       1 |
+------+----------+------+------+-------------------+------------+-----------+-------------+-------------+-----------+---------+--------+---------+---------+
1 row in set (0.01 sec)

配置 FTP 目录:

sh
# mkdir -p /home/pureftp/www                   # 创建 FTP 用户的主目录及子目录
# chown -R ftpuser:ftpgroup /home/pureftp     # 设置目录所有者为 ftpuser,所属组为 ftpgroup
# chmod -R 775 /home/pureftp                  # 设置目录权限为 775,允许同组用户读写

结构概览:

sh
/home/
└── pureftp/
    └── www/ # FTP 用户的主目录

22.2.4.5 参考文献

22.2.5 服务操作

配置完成后,启动并管理 Pure-FTPd 服务:

sh
# service pure-ftpd enable    # 设置 Pure-FTPd 服务开机启动
# service pure-ftpd start     # 启动 Pure-FTPd 服务
# service pure-ftpd stop      # 停止 Pure-FTPd 服务
# service pure-ftpd restart   # 重启 Pure-FTPd 服务

22.2.6 参考文献

22.2.7 故障排除与未竟事宜

  • Pure-FTPd 日志文件位于 /var/log/messages