第二十八章 DragonFlyBSD
第一节 FTP 服务器
FTP 意为文件传输协议。使用 FTP 服务搭建服务器可以快速传输文件。

pure-ftpd(以 MySQL 支持为例)

对于 RFC 2640 的支持已经被移除,所以 Windows 下的非英文的文件上传至 FTP 会乱码,见 https://www.pureftpd.org/project/pure-ftpd/news/ 无法解决,同时不建议把 Windows 的系统编码改为 UTF8 ,会造成更多乱码的发生,比如 zip 文件。
注意:本示例以 mysql 5.x 为例。

安装

由于 pkg 包不带有数据库支持功能,所以需要通过 ports 来安装该软件:
1
# /usr/ports/ftp/pure-ftpd
2
# make config-recursive
Copied!
选中 mysql,其余保持默认选项回车即可:
1
# make install clean
Copied!
注意:关于 mysql 的基本设置请看 第十七章
请自行安装 mysql,理论上兼容 mysql 5.x、8.x

配置 /usr/local/etc/pure-ftpd.conf 文件

生成配置文件:

1
# cp /usr/local/etc/pure-ftpd.conf.sample /usr/local/etc/pure-ftpd.conf
2
# cp /usr/local/etc/pureftpd-mysql.conf.sample /usr/local/etc/pureftpd-mysql.conf
Copied!

编辑配置文件并增加 mysql 的支持:

1
#兼容 ie 等非正规化的 ftp 客户端
2
3
BrokenClientsCompatibility yes
4
5
# 被动连接响应的端口范围。
6
PassivePortRange 30000 50000
7
8
# 认证用户允许登陆的最小组 ID(UID) 。
9
MinUID 2000
10
11
# 仅允许认证用户进行 FXP 传输。
12
AllowUserFXP yes
13
14
# 用户主目录不存在的话,自动创建。
15
CreateHomeDir yes
16
17
# MySQL configuration file (see README.MySQL)
18
19
MySQLConfigFile /usr/local/etc/pureftpd-mysql.conf
Copied!

配置 mysql

创建数据库

1
create database pureftp;
2
use pureftp;
3
DROP TABLE IF EXISTS `users`;
4
CREATE TABLE `users` (
5
`User` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
6
`Password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
7
`Uid` int(11) NOT NULL DEFAULT -1 COMMENT '用户ID',
8
`Gid` int(11) NOT NULL DEFAULT -1 COMMENT '用户组ID',
9
`Dir` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
10
`quotafiles` int(255) NULL DEFAULT 500,
11
`quotasize` int(255) NULL DEFAULT 30,
12
`ulbandwidth` int(255) NULL DEFAULT 80,
13
`dlbandwidth` int(255) NULL DEFAULT 80,
14
`ipaddress` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT'*',
15
`comment` int(255) NULL DEFAULT NULL,
16
`status` tinyint(4) NULL DEFAULT 1,
17
`ulratio` int(255) NULL DEFAULT 1,
18
`dlratio` int(255) NULL DEFAULT 1,
19
PRIMARY KEY (`User`) USING BTREE
20
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
21
INSERT INTO `users` VALUES ('demo', 'demo&2022*', 2002, 2000, '/home/www/demo', 500, 30, 80, 80, '*', NULL, NULL, 1, 1);
Copied!

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

1
grant select,insert,update,delete on pureftp.* to [email protected] identified by "Ab123456&";
Copied!

配置 /usr/local/etc/pureftpd-mysql.conf

1
##############################################
2
# #
3
# Sample Pure-FTPd Mysql configuration file. #
4
# See README.MySQL for explanations. #
5
# #
6
##############################################
7
8
9
# Optional : MySQL server name or IP. Don't define this for unix sockets.
10
11
# MYSQLServer 127.0.0.1
12
MYSQLServer localhost
13
14
15
# Optional : MySQL port. Don't define this if a local unix socket is used.
16
17
MYSQLPort 3306
18
19
20
# Optional : define the location of mysql.sock if the server runs on this host.
21
22
MYSQLSocket /var/run/mysqld/mysqld.sock
23
24
25
# Mandatory : user to bind the server as.
26
27
MYSQLUser pftp
28
29
30
# Mandatory : user password. You must have a password.
31
32
MYSQLPassword Ab123456&
33
34
35
# Mandatory : database to open.
36
37
MYSQLDatabase pureftpd
38
39
40
# Mandatory : how passwords are stored
41
# Valid values are : "cleartext", "argon2", "scrypt", "crypt", "sha1", "md5",password" and "any"
42
43
# ("password" = MySQL password() function, which is sha1(sha1(password)))
44
45
#MYSQLCrypt scrypt
46
MYSQLCrypt cleartext
47
48
49
# In the following directives, parts of the strings are replaced at
50
# run-time before performing queries :
51
#
52
# \L is replaced by the login of the user trying to authenticate.
53
# \I is replaced by the IP address the user connected to.
54
# \P is replaced by the port number the user connected to.
55
# \R is replaced by the IP address the user connected from.
56
# \D is replaced by the remote IP address, as a long decimal number.
57
#
58
# Very complex queries can be performed using these substitution strings,
59
# especially for virtual hosting.
60
61
# Query to execute in order to fetch the password
62
63
MYSQLGetPW SELECT Password FROM users WHERE User='\L'
64
65
66
# Query to execute in order to fetch the system user name or uid
67
MYSQLGetUID SELECT Uid FROM users WHERE User='\L'
68
69
70
# Optional : default UID - if set this overrides MYSQLGetUID
71
72
MYSQLDefaultUID 2000
73
74
75
# Query to execute in order to fetch the system user group or gid
76
77
MYSQLGetGID SELECT Gid FROM users WHERE User='\L'
78
79
80
# Optional : default GID - if set this overrides MYSQLGetGID
81
82
MYSQLDefaultGID 2000
83
84
85
# Query to execute in order to fetch the home directory
86
87
MYSQLGetDir SELECT Dir FROM users WHERE User='\L'
88
89
90
# Optional : query to get the maximal number of files
91
# Pure-FTPd must have been compiled with virtual quotas support.
92
93
# MySQLGetQTAFS SELECT QuotaFiles FROM users WHERE User='\L'
94
95
96
# Optional : query to get the maximal disk usage (virtual quotas)
97
# The number should be in Megabytes.
98
# Pure-FTPd must have been compiled with virtual quotas support.
99
100
# MySQLGetQTASZ SELECT QuotaSize FROM users WHERE User='\L'
101
102
103
# Optional : ratios. The server has to be compiled with ratio support.
104
105
# MySQLGetRatioUL SELECT ULRatio FROM users WHERE User='\L'
106
# MySQLGetRatioDL SELECT DLRatio FROM users WHERE User='\L'
107
108
109
# Optional : bandwidth throttling.
110
# The server has to be compiled with throttling support.
111
# Values are in KB/s .
112
113
# MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User='\L'
114
# MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User='\L'
115
116
117
# Enable ~ expansion. NEVER ENABLE THIS BLINDLY UNLESS :
118
# 1) You know what you are doing.
119
# 2) Real and virtual users match.
120
121
# MySQLForceTildeExpansion 1
122
123
124
# If you're using a transactionnal storage engine, you can enable SQL
125
# transactions to avoid races. Leave this commented if you are using the
126
# traditional MyIsam engine.
127
128
# MySQLTransactions On
Copied!

添加 ftp 组和用户

1
# pw groupadd ftpgroup -g 2000
2
# pw useradd ftpuser -u 2001 -g 2000
Copied!
1
# pw useradd ftpuser -u 2001 -g 2000 -s /sbin/nologin -w no -d /home/vftp -c "VirtualUser Pure-FTPd" -m
Copied!

配置 FTP 目录

1
# mkdir /home/www/pureftp
2
# chown -R ftpuser /home/www/
3
# chgrp -R ftpgroup /home/www/
Copied!

服务操作

1
# sysrc pureftpd_enable="YES"
2
# service pure-ftpd start #启动服务器
3
# service pure-ftpd stop #停止服务
4
# service pure-ftpd restart #重启服务
Copied!

proftpd(以 mysql 支持为例)

安装 proftpd(以 mysql 支持为例)

1
# pkg install proftpd proftpd-mod_sql_mysql
Copied!

编辑配置文件 /usr/local/etc/proftpd.conf

1
# cat /usr/local/etc/proftpd.conf
2
ServerName "Test Ftp Server"
3
ServerType standalone
4
DefaultServer on
5
ServerIdent on "FTP Server ready"
6
DeferWelcome off
7
Port 21
8
Umask 022
9
TimeoutLogin 300
10
TimeoutIdle 36000
11
TimeoutNoTransfer 36000
12
TimeoutStalled 36000
13
TimeoutSession 0
14
User proftpd
15
Group proftpd
16
MaxInstances 100
17
MaxClientsPerHost 100
18
AllowRetrieveRestart on
19
AllowStoreRestart on
20
AllowOverwrite on
21
AllowOverride off
22
RootLogin off
23
IdentLookups off
24
UseReverseDNS off
25
DenyFilter \*.*/
26
TimesGMT off
27
DefaultRoot ~
28
#RLimitCPU 1200 1200
29
RLimitMemory 256M 256M
30
RLimitOpenFiles 1024 1024
31
PassivePorts 50000 60000
32
LogFormat default "%h %l %u %t \"%r\" %s %b"
33
LogFormat auth "%v [%P] %h %t \"%r\" %s"
34
LogFormat write "%h %l %u %t \"%r\" %s %b"
35
SystemLog /var/log/proftpd/proftpd.log
36
TransferLog /var/log/proftpd/xfer.log
37
ExtendedLog /var/log/proftpd/access.log WRITE,READ write
38
ExtendedLog /var/log/proftpd/auth.log AUTH auth
39
LoadModule mod_sql.c
40
LoadModule mod_sql_mysql.c
41
<Global>
42
SQLConnectInfo [email protected] proftpd proftpd_password
43
SQLAuthTypes Crypt
44
SQLUserInfo users username password uid gid homedir NULL
45
SQLDefaultGID 2000
46
SQLDefaultUID 2000
47
RequireValidShell off
48
SQLAuthenticate users*
49
SQLLogFile /var/log/proftpd.log
50
SQLNamedQuery getcount SELECT "count, username from users where username='%u'"
51
SQLNamedQuery updatecount UPDATE "count=count+1 WHERE username='%u'" users
52
SQLShowInfo PASS "230" "You've logged on %{getcount} times, %u"
53
SQLLog PASS updatecount
54
SQLLog DELE,RETR,STOR, log_work
55
SQLNamedQuery log_work FREEFORM "\
56
INSERT INTO worklog (\
57
user_name,\
58
file_and_path,\
59
bytes,\
60
send_time,\
61
client_ip,\
62
client_name,\
63
client_command) \
64
VALUES('%u','%f','%b','%T','%a','%h','%m')"
65
</Global>
Copied!
我们在设置中指定服务器将在主动模式下在端口 21 上工作,在被动模式下在 50000-60000 范围内工作.这些端口应该在防火墙中打开。 对于 PF,这是通过以下规则完成的:
1
pass in quick on $ext_if proto tcp from any to $ext_if port { 21, 50000:60000 }
Copied!

创建用户

出于安全目的,我们将以非 root 用户身份运行 Proftpd。 因此,我们将创建此用户:
1
# adduser
2
Username: proftpd
3
Full name: FTP User
4
Uid (Leave empty for default):
5
Login group [proftpd]:
6
Login group is proftpd. Invite proftpd into other groups? []:
7
Login class [default]:
8
Shell (sh csh tcsh bash nologin) [sh]: nologin
9
Home directory [/home/proftpd]:
10
Home directory permissions (Leave empty for default):
11
Use password-based authentication? [yes]: no
12
Lock out the account after creation? [no]:
13
Username : proftpd
14
Password : <disabled>
15
Full Name : FTP User
16
Uid : 2000
17
Class :
18
Groups : proftpd
19
Home : /home/proftpd
20
Shell : /usr/sbin/nologin
21
Locked : no
22
OK? (yes/no): yes
23
adduser: INFO: Successfully added (proftpd) to the user database.
24
Add another user? (yes/no): no
25
Goodbye!
Copied!
现在已经创建了自己的 proftpd 用户和组 ID。 因此,在添加 ftp 用户时,你将使用它。 你可以通过以 下方式确定 UID:
1
# cat /etc/passwd | grep proftpd
2
proftpd:*:2000:2000:FTP User:/home/proftpd:/usr/sbin/nologin
Copied!

日志相关

创建一个目录来存储 FTP 服务器的日志:
1
# mkdir /var/log/proftpd
Copied!
创建一个 MySQL 数据库和一个对创建的数据库具有完全访问权限的用户:
1
CREATE DATABASE `proftpd` CHARACTER SET utf8 COLLATE utf8_general_ci;
Copied!
创建数据库用户和密码(授权 proftpd 数据库):
1
grant select,insert,update,delete on proftpd.* to [email protected] identified by "123456";
2
FLUSH PRIVILEGES; #立即生效权限
Copied!
1
grant select,insert,update,delete on *.* to [email protected]"localhost" Identified by "123456";
Copied!
创建数据量:
1
DROP TABLE IF EXISTS users;
2
CREATE TABLE `users` (
3
`username` varchar(30) NOT NULL DEFAULT '',
4
`descr` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
5
`password` varchar(30) NOT NULL DEFAULT '',
6
`uid` int(11) DEFAULT NULL,
7
`gid` int(11) DEFAULT NULL,
8
`homedir` varchar(255) DEFAULT NULL,
9
`shell` varchar(255) DEFAULT NULL,
10
`count` int(11) NOT NULL DEFAULT '0',
11
UNIQUE KEY `username` (`username`)
12
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
13
DROP TABLE IF EXISTS worklog;
14
CREATE TABLE worklog (
15
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
16
date timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
17
user_name varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
18
file_and_path varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
19
bytes bigint(20) NULL DEFAULT NULL,
20
send_time varchar(9) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
21
client_ip varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
22
client_name text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
23
client_command varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
24
PRIMARY KEY (id) USING BTREE,
25
UNIQUE INDEX id(id) USING BTREE
26
) ENGINE = MyISAM CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
Copied!
创建一个目录和一个测试 FTP 用户,将创建的目录指定为用户目录:
1
# mkdir -p /home/www/ftp
2
# chown -R proftpd:proftpd /home/www/ftp
3
# mysql -u proftpd -p
4
INSERT INTO `proftpd`.`users` (`username` , `descr` , `password` , `uid` , `gid` ,`homedir` , `shell` , `count` ) VALUES ('test', 'Test user', ENCRYPT('FTPpassword_here' ) , '2000', '2000', '/home/www/ftp', NULL , '0' );
5
6
Query OK, 1 row affected, 1 warning (0.02 sec)
Copied!

服务操作

1
# sysrc proftpd_enable="YES"
2
3
# service proftpd start #启动服务器
4
5
# service proftpd stop #停止服务
6
7
# service proftpd restart #重启服务
Copied!

连接到 FTP 服务器

简单示例:
1
# telnet localhost 21
2
Trying 127.0.0.1...
3
Connected to localhost.
4
Escape character is '^]'.
5
220 FTP Server ready
6
quit
7
221 Goodbye.
Copied!
使用 ftp 命令可以快速连接到 FTP 服务器。
用法:
1
ftp [选项] [URL]
Copied!
选项:
-4 强制使用 IPv4 协议连接
-6 强制使用 IPv6 协议连接
-a 使用匿名登录
-q [quittime] 在设定时间后连接失败则自动放弃连接
-r [wait] 每隔 wait 秒发送一次连接请求
-A 强制使用主动模式
-d 开启调试模式
-v 开启啰嗦模式
-V 关闭啰嗦模式

登录后的命令:

1
account [passwd] 提交补充密码
2
3
append [locol-file] [remote-file] 以 remote-file 为文件名向服务器上传本地文件 local-file
4
5
ascii 将FTP文件传送类型设置为 ASCII 模式
6
7
bell 在文件传送完后发出提示音
8
9
bye 结束与服务器的会话
10
11
cd 切换目录
12
13
cdup 退回父目录
14
15
delete 删除文件
16
17
dir 显示该目录下的文件及文件夹
18
19
features 显示该服务器支持的功能
20
21
get remote-fil 下载服务器上的 remote-file
Copied!