1.ftp简介
网络文件共享服务主流的主要有三种,分别是ftp、nfs、samba。
一般来讲,人们将计算机联网的首要目的就是获取资料,而文件传输是一种非常重要的获取资料的方式。今天的互联网是由几千万台个人计算机、工作站、服务器、小型机、大型机、巨型机等具有不同型号、不同架构的物理设备共同组成的,而且即便是个人计算机,也可能会装有Windows、Linux、UNIX、Mac等不同的操作系统。为了能够在如此复杂多样的设备之间解决问题解决文件传输问题,文件传输协议(FTP)应运而生。
FTP是一种在互联网中进行文件传输的协议,基于客户端/服务器模式,默认使用20、21号端口,其中端口20(数据端口)用于进行数据传输,端口21(命令端口)用于接受客户端发出的相关FTP命令与参数。FTP服务器普遍部署于内网中,具有容易搭建、方便管理的特点。而且有些FTP客户端工具还可以支持文件的多点下载以及断点续传技术,因此FTP服务得到了广大用户的青睐。FTP协议的传输拓扑如下图所示。
2.ftp数据连接模式
FTP服务器是按照FTP协议在互联网上提供文件存储和访问服务的主机,FTP客户端则是向服务器发送连接请求,以建立数据传输链路的主机。FTP协议有下面两种工作模式。
主动模式:FTP服务器主动向客户端发起连接请求。
被动模式:FTP服务器等待客户端发起连接请求(FTP的默认工作模式)。
两种数据传输模式的建立过程:
传输模式 | 建立过程 |
---|---|
主动模式 | 命令连接: Client(1025)–> Server(21) 客户端以一个随机端口(大于1023)来连服务器端的21号端口 数据连接: Server(20/tcp) --> Client(1025+1) 服务器端以自己的20号端口去连客户端创建命令连接时使用的随机端口+1的端口号 |
被动模式 | 命令连接: Client(1110) --> Server(21) 客户端以一个随机端口来连成服务器端的21号端口 数据连接: Client(1110+1) --> Server(随机端口) 客户端以创建命令连接的端口+1的端口号去连服务器端通过命令连接告知自己的一个随机端口号来创建数据连 |
3.用户认证
ftp的用户主要有三种:
- 虚拟用户:仅用于访问某特定服务中的资源
- 系统用户:可以登录系统的真实用户
- 匿名用户
4.vsftpd
vsftpd(very secure ftp daemon,非常安全的FTP守护进程)是一款运行在Linux操作系统上的FTP服务程序,不仅完全开源而且免费,此外,还具有很高的安全性、传输速度,以及支持虚拟用户验证等其他FTP服务程序不具备的特点。
4.1.vsftpd安装
在配置妥当Yum软件仓库之后,就可以安装vsftpd服务程序了。
[root@localhost ~]# yum -y install vsftpd
4.2.vsftpd配置
/etc/pam.d/vsftpd //vsftpd用户认证配置文件
/etc/vsftpd/ //配置文件目录
/etc/vsftpd/vsftpd.conf //主配置文件
//匿名用户(映射为ftp用户)的共享资源位置是/var/ftp
//系统用户通过ftp访问的资源位置为用户的家目录
//虚拟用户通过ftp访问的资源位置为给虚拟用户指定的映射成为的系统用户的家目录
vsftpd服务程序常用的参数以及作用
参数 | 作用 |
---|---|
anonymous_enable=YES | 启用匿名用户登录 |
anon_upload_enable=YES | 许匿名用户上传 |
anon_mkdir_write_enable=YES | 允许匿名用户创建目录,但是不能删除 |
anon_other_write_enable=YES | 允许匿名用户创建和删除目录 |
local_enable=YES | 启用本地用户登录 |
write_enable=YES | 允许本地用户有写权限 |
local_umask=022 | 通过ftp上传文件的默认遮罩码 |
chroot_local_user=YES | 禁锢所有的ftp本地用户于其家目录中 |
chroot_list_enable=YES | 开启禁锢文件列表 需要与chroot_list_file参数一起使用 |
chroot_list_file=/etc/vsftpd/chroot_list | 指定禁锢列表文件路径 在此文件里面的用户将被禁锢在其家目录中 |
allow_writeable_chroot=YES | 允许被禁锢的用户家目录有写权限 |
xferlog_enable=YES | 是否启用传输日志,记录ftp传输过程 |
xferlog_std_format=YES | 传输日志是否使用标准格式 |
xferlog_file=/var/log/xferlog | 指定传输日志存储的位置 |
chown_uploads=YES | 是否启用改变上传文件属主的功能 |
chown_username=whoever | 指定要将上传的文件的属主改为哪个用户 此用户必须在系统中存在 |
pam_service_name=vsftpd | 指定vsftpd使用/etc/pam.d下的哪个pam配置文件进行用户认证 |
userlist_enable=YES | 是否启用控制用户登录的列表文件: 默认为/etc/vsftpd/user_list文件 |
userlist_deny=YES | 是否拒绝userlist指定的列表文件中存在的用户登录ftp |
max_clients=# | 最大并发连接数 |
max_per_ip=# | 每个IP可同时发起的并发请求数 |
anon_max_rate | 匿名用户的最大传输速率,单位是“字节/秒” |
local_max_rate | 本地用户的最大传输速率,单位是“字节/秒” |
dirmessage_enable=YES | 启用某目录下的.message描述信息 假定有一个目录为/upload,在其下创建一个文件名为.message, 在文件内写入一些描述信息,则当用户切换至/upload目录下时会自动显示.message文件中的内容 |
message_file | 设置访问一个目录时获得的目录信息文件的文件名,默认是.message |
idle_session_timeout=600 | 设置默认的断开不活跃session的时间 |
data_connection_timeout=120 | 设置数据传输超时时间 |
ftpd_banner=“Welcome to chenlf FTP service.” | 定制欢迎信息,登录ftp时自动显示 |
5.vsftpd服务配置
5.1.匿名访问模式
允许匿名访问,并且匿名用户可以上传、下载、删除、创建文件,以及对上传文件设置这招码
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=YES
#
# Uncomment this to allow local users to log in.
# When SELinux is enforcing check for SE bool ftp_home_dir
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
local_umask=022
anon_umask=022
#
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
# When SELinux is enforcing check for SE bool allow_ftpd_anon_write, allow_ftpd_full_access
anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
[root@localhost ~]# systemctl start vsftpd
[root@localhost pub]# touch aa
[root@localhost pub]# mkdir zml
验证
- 图形化
[root@localhost pub]# ll
总用量 0
-rw-r--r--. 1 ftp ftp 0 2月 18 16:19 11.txt
drwxr-xr-x. 2 root root 6 2月 18 16:09 zml
- 命令行
[root@localhost ~]# lftp -u ftp 192.168.233.128
口令:
lftp ftp@192.168.233.128:~> ls
drwxrwxrwx 4 0 0 51 Feb 18 08:25 pub
lftp ftp@192.168.233.128:/> cd pub/
lftp ftp@192.168.233.128:/pub> mkdir 55
mkdir 成功, 建立 `55'
lftp ftp@192.168.233.128:/pub> ls
-rw-r--r-- 1 14 50 0 Feb 18 08:19 11.txt
drwxr-xr-x 2 14 50 6 Feb 18 08:25 55
-rw-r--r-- 1 14 50 0 Feb 18 08:22 aa
drwxr-xr-x 2 0 0 6 Feb 18 08:09 zml
[root@localhost ~]# touch pp
[root@localhost ~]# mkdir zxj
[root@localhost ~]# cd zxj
[root@localhost zxj]# touch zqq
[root@localhost ~]# lftp -u ftp 192.168.233.128
口令:
lftp ftp@192.168.233.128:~> cd pub/
lftp ftp@192.168.233.128:/pub> put pp
lftp ftp@192.168.233.128:/pub> ls
-rw-r--r-- 1 14 50 0 Feb 18 08:19 11.txt
drwxr-xr-x 2 14 50 6 Feb 18 08:25 55
-rw-r--r-- 1 14 50 0 Feb 18 08:36 aa
-rw-r--r-- 1 14 50 0 Feb 18 08:37 pp
drwxr-xr-x 2 0 0 6 Feb 18 08:09 zml
lftp ftp@192.168.233.128:/pub> mirror 55 zxj/
Total: 1 directory, 0 files, 0 symlinks
lftp ftp@192.168.233.128:/pub> exit
[root@localhost ~]# cd zxj/
[root@localhost zxj]# ls
55 zqq
// 在服务端修改权限
[root@localhost pub]# ll
总用量 0
-rw-r--r--. 1 ftp ftp 0 2月 18 16:19 11.txt
drwxr-xr-x. 2 ftp ftp 6 2月 18 16:25 55
-rw-r--r--. 1 ftp ftp 0 2月 18 16:36 aa
-rw-r--r--. 1 ftp ftp 0 2月 18 16:37 pp
drwxr-xr-x. 2 root root 6 2月 18 16:09 zml
[root@localhost pub]# chmod 777 55
lftp ftp@192.168.233.128:/pub> rmdir 55
rmdir 成功, 删除 `55'
lftp ftp@192.168.233.128:/pub> ls
-rw-r--r-- 1 14 50 0 Feb 18 08:19 11.txt
-rw-r--r-- 1 14 50 0 Feb 18 08:36 aa
-rw-r--r-- 1 14 50 0 Feb 18 08:37 pp
drwxr-xr-x 2 0 0 6 Feb 18 08:09 zml
5.2.本地用户模式
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
1 anonymous_enable=NO
2 local_enable=YES
3 write_enable=YES
4 local_umask=022
5 userlist_enable=YES
[root@localhost ~]# grep ftp /etc/shadow
ftp:*:16925:0:99999:7:::
[root@localhost ~]# useradd -g ftp -s /sbin/nologin ftp1
[root@localhost ~]# passwd ftp1
更改用户 ftp1 的密码 。
新的 密码:
无效的密码: 密码是一个回文
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# cd /home/ftp1/
[root@localhost ftp1]# touch test
[root@localhost ftp1]# cd
[root@localhost ~]# systemctl restart vsftpd
[root@localhost ~]# ls
aa anaconda-ks.cfg pp zxj zz
[root@localhost ~]# lftp -u ftp1 192.168.233.128
口令:
lftp ftp1@192.168.233.128:~> ls
-rw-r--r-- 1 0 0 0 Feb 18 09:05 test
lftp ftp1@192.168.233.128:~> get test
lftp ftp1@192.168.233.128:~> exit
[root@localhost ~]# ls
aa anaconda-ks.cfg pp test zxj zz
[root@localhost ~]# lftp -u ftp1 192.168.233.128
口令:
lftp ftp1@192.168.233.128:~> put pp aa
Total 2 files transferred
lftp ftp1@192.168.233.128:~> ls
-rw-r--r-- 1 1001 50 0 Feb 18 09:09 aa
-rw-r--r-- 1 1001 50 0 Feb 18 09:09 pp
-rw-r--r-- 1 0 0 0 Feb 18 09:05 test
5.3.虚拟用户模式
//在/etc/vsftpd/下建立vlogin.txt,用来存储虚拟用户的用户名和密码,其中奇数行为账户名,偶数行为密码。
[root@localhost vsftpd]# vim vlogin.txt
[root@localhost vsftpd]# cat vlogin.txt
ftp2
123
ftp3
456
ftp4
789
//生成数据库
保存虚拟账号和密码的文本文件无法被系统账号直接调用,需要使用db_load命令生成db数据库文件
[root@localhost vsftpd]# db_load -T -t hash -f /etc/vsftpd/vlogin.txt /etc/vsftpd/vlogin.db
[root@localhost vsftpd]#
//修改数据库文件访问权限
数据库文件中保存着虚拟账号的密码信息,为了防止非法用户盗取,我们可以修改文件权限,生成的认证文件的权限应设置为只对root用户可读可写,即600
[root@localhost vsftpd]# chmod 600 vlogin.db
[root@localhost vsftpd]# ll
总用量 36
-rw-------. 1 root root 125 3月 23 2017 ftpusers
-rw-------. 1 root root 365 2月 18 16:55 user_list
-rw-------. 1 root root 12288 2月 18 17:23 vlogin.db
-rw-r--r--. 1 root root 27 2月 18 17:18 vlogin.txt
-rw-------. 1 root root 5074 2月 18 16:51 vsftpd.conf
-rwxr--r--. 1 root root 338 3月 23 2017 vsftpd_conf_migrate.sh
//编辑pam文件,pam模块配置文件路径为/etc/pam.d/目录,此目录下保存着大量与认证有关的配置文件。为了以防万一,对pam文件进行备份。
[root@localhost ~]# cd /etc/pam.d/
[root@localhost pam.d]# cp vsftpd vsftpd.bak
[root@localhost pam.d]# vim vsftpd
[root@localhost pam.d]# cat vsftpd
#%PAM-1.0
auth required pam_userdb.so db=/etc/vsftpd/vlogin
account required pam_userdb.so db=/etc/vsftpd/vlogin
//添加一个系统用户来对应虚拟用户,光有虚拟用户是无法登陆的,我们需要让虚拟用户对应一个系统实际的用户,这样所有的用户登陆之后就会进入到系统实际用户的家目录,我们在通过各个虚拟用户来分配不同的权限
[root@localhost ~]# useradd -g ftp -d /var/ftp10 -s /sbin/nologin ftp10
[root@localhost var]# ll -d ftp10
drwx------. 2 ftp10 ftp 62 2月 18 17:45 ftp10
/修改vsftpd配置文件,添加虚拟用户支持
在配置文件的末尾添加内容
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
guest_enable=YES
guest_username=ftp10
//为不同的虚拟用户建立独立的配置文件
在配置文件的末尾添加内容
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
user_config_dir=/etc/vsftpd/vuserconfig
allow_writeable_chroot=YES
//在/etc/vsftpd/下建立vuserconfig目录,用于存放用户的权限配置文件,以便为各个用户分配不同的权限
[root@localhost ~]# cd /etc/vsftpd/
[root@localhost vsftpd]# mkdir vuserconfig
//在vuserconfig目录下面建立用户的权限配置文件,配置文件的名称必须要和vlogin.txt中添加的用户名一致
//设置ftp2用户可上传文件、创建目录
[root@localhost vuserconfig]# vim ftp2
[root@localhost vuserconfig]# cat ftp2
anon_upload_enable=YES
anon_mkdir_write_enable=YES
//设置ftp3只有默认的下载权限,只需要创建一个名为jerry的空文件即可
[root@localhost vuserconfig]# touch ftp3
//设置ftp4只能上传文件
[root@localhost vuserconfig]# vim ftp4
[root@localhost vuserconfig]# cat ftp4
anon_upload_enable=YES
//注意:虚拟用户是通过匿名访问的,所以必须开启匿名访问功能!!!
//重启服务
[root@localhost ~]# systemctl restart vsftpd
验证
[root@localhost ~]# ls
aa anaconda-ks.cfg pp zxj zz
[root@localhost ~]# lftp -u ftp2 192.168.233.128
口令:
lftp ftp2@192.168.233.128:~> ls
-rw-r--r-- 1 0 0 0 Feb 18 10:08 test
drwxr-xr-x 2 0 0 6 Feb 18 10:08 zml
lftp ftp2@192.168.233.128:/> mkdir dsz
mkdir 成功, 建立 `dsz'
lftp ftp2@192.168.233.128:/> put aa
lftp ftp2@192.168.233.128:/> ls
-rw-r--r-- 1 1002 50 0 Feb 18 10:11 aa
drwxr-xr-x 2 1002 50 6 Feb 18 10:09 dsz
-rw-r--r-- 1 0 0 0 Feb 18 10:08 test
drwxr-xr-x 2 0 0 6 Feb 18 10:08 zml
[root@localhost ~]# ls
aa anaconda-ks.cfg pp zxj zz
[root@localhost ~]# lftp -u ftp3 192.168.233.128
口令:
lftp ftp3@192.168.233.128:~> ls
-rw-r--r-- 1 1002 50 0 Feb 18 10:11 aa
drwxr-xr-x 2 1002 50 6 Feb 18 10:09 dsz
-rw-r--r-- 1 0 0 0 Feb 18 10:08 test
drwxr-xr-x 2 0 0 6 Feb 18 10:08 zml
lftp ftp3@192.168.233.128:/> get test
lftp ftp3@192.168.233.128:/> mirror zml
Total: 1 directory, 0 files, 0 symlinks
lftp ftp3@192.168.233.128:/> exit
[root@localhost ~]# ls
aa anaconda-ks.cfg pp test zml zxj zz
lftp ftp3@192.168.233.128:~> put pp
put: Access failed: 550 Permission denied. (pp)
[root@localhost ~]# ls
aa anaconda-ks.cfg kk pp test zml zxj zz
[root@localhost ~]# lftp -u ftp4 192.168.233.128
口令:
lftp ftp4@192.168.233.128:~> ls
-rw-r--r-- 1 1002 50 0 Feb 18 10:11 aa
drwxr-xr-x 2 1002 50 6 Feb 18 10:09 dsz
-rw-r--r-- 1 0 0 0 Feb 18 10:08 test
drwxr-xr-x 2 0 0 6 Feb 18 10:08 zml
lftp ftp4@192.168.233.128:/> put pp
lftp ftp4@192.168.233.128:/> mkdir hh
mkdir: Access failed: 550 Permission denied. (hh)
lftp ftp4@192.168.233.128:/> ls
-rw-r--r-- 1 1002 50 0 Feb 18 10:11 aa
drwxr-xr-x 2 1002 50 6 Feb 18 10:09 dsz
-rw-r--r-- 1 1002 50 0 Feb 18 10:16 pp
-rw-r--r-- 1 0 0 0 Feb 18 10:08 test
drwxr-xr-x 2 0 0 6 Feb 18 10:08 zml