写点什么

linux 入门系列 15-- 文件传输之 vsftp 服务

用户头像
黑马腾云
关注
发布于: 2020 年 08 月 25 日
linux入门系列15--文件传输之vsftp服务

前面的系列文章基本讲完了 linux 管理相关的基础知识,从本篇开始讲解 centos7 中服务程序的部署和配置,以便为外部提供各种服务。


日常工作和娱乐中,我们所需的各种资源都离不开网络以及各种服务,我们通过网络获取部署在其他服务器上的各种服务资源,这些服务包括文件服务、邮件服务、媒体服务等等。


一般情况下,我们使用计算机上网的一个重要目的就是为了获取资料,而文件传输则是获取资料的方式。因此,我们首先来了解下 linux 中文件传输相关的知识。


一、文件传输协议 FTP


1.1 FTP 产生背景


“无规矩不成方圆”,这说明了规则的重要性。同样,当今的互联网由成千上万台机器组成,这些机器包括个人计算机、工作站、服务器、巨型机等各种形形色色的设备,并且这些设备中使用的操作系统还不一样,有的可能是用的 windows,而有的则是 Linux 或其他系统。


要在这么纷繁复杂的设备之间传输文件,那就必须要有一定的规则,大家都按规则办事,传输的文件才能相互识别,达到正确传递信息的目的。在这种背景下,为了解决文件传输的问题,文件传输协议应运而生。


1.2 FTP 相关概念


文件传输协议(File Transfer Protocol,FTP),是一种在互联网中进行文件传输的协议,基于客户端/服务器模式,默认使用 20、21 号端口,其中 20 端口是数据端口用于进行数据传输,21 端口为命令端口,用于接收客户端发出的相关 FTP 命令和参数。


本系列文章第三篇提到的所有工具都可以实现在 Windows 中远程到 Linux 主机并上传下载文件,并且在 Linux 主机之间也可以通过 scp 命令上传文件,那为什么还需要 FTP 呢?个人认为应该是因为 FTP 一般搭建与内网之中,有具有容易搭建、方便管理的特点,并且一些 FTP 客户端工具还具有文件多点下载以及断点续传等功能,这些是 scp 做不到的。


FTP 是 C/S 架构,也就是基于客户端/服务器的模式,FTP 服务器是按照 FTP 协议在互联网上提供文件存储和访问服务的主机,FTP 客户端则是向服务器发送连接请求,以建立数据传输链路的主机。


FTP 协议的传输拓扑结构如下:



FTP 协议工作模式有两种:*主动模式和被动模式,其中被动模式是默认的工作模式*。


  • 主动模式:FTP 服务器主动向客户端发起连接请求。


  • 被动模式:FTP 服务器等待客户端发起连接请求。


由于 FTP 一般部署在企业内网,如果开启并配置了防火墙,有时候需要将 FTP 的工作模式设置为主动模式,才可以传输数据。


二、Linux 下基于 FTP 协议工具


2.1 vsftpd 服务安装


vsftpd(very secure ftp daemon)非常安全的 FTP 守护进程,是一款运行在 Linux 系统上的免费开源的 FTP 服务端程序。其主要特点是:安全性高、传输速度快、支持虚拟用户验证。


默认情况 Centos7 中是没有安装 vsftpd 的,因此需要手动通过 yum 仓库安装,根据前文的讲解可以用光盘资源自带的 yum 源,也可以直接配置外网源。本例采用默认的外网 yum 源进行安装。


~~~

[root@origin ~]# rpm -q vsftpd

package vsftpd is not installed

[root@origin ~]# yum install vsftpd

Loaded plugins: fastestmirror, langpacks

...省略部分内容

Installed size: 353 k

Is this ok [y/d/N]: y

Downloading packages:

vsftpd-3.0.2-25.el7.x86_64.rpm | 171 kB 00:00

Running transaction check

Running transaction test

Transaction test succeeded

Running transaction

Installing : vsftpd-3.0.2-25.el7.x86_64 1/1

Verifying : vsftpd-3.0.2-25.el7.x86_64 1/1

Installed:

vsftpd.x86_64 0:3.0.2-25.el7

Complete!

[root@origin ~]# rpm -q vsftpd

vsftpd-3.0.2-25.el7.x86_64

[root@origin ~]#

~~~


通过 rpm 命令查看是否已经安装过 vsftpd,如果没有安装则通过 yum install 命令安装即可,安装过程中需要按提示输入 y 继续下载并安装。


注意:从现在开始,凡是涉及到服务的配置,就要考虑防火墙和 SELinux 的因素,很多教程和书籍上都是直接关闭防火墙和 selinux,虽然这样在学习阶段可以避免干扰,但是这样非常不安全。另外凡是配置了服务,都要加入开机启动中,让其每次重启自动生效。


安装 vsftpd 服务后,会在/etc 下自动生成配置文件


~~~

[root@ftpserver ~]# ll /etc/vsftpd/

total 20

-rw-------. 1 root root 125 Oct 31 2018 ftpusers

-rw-------. 1 root root 361 Oct 31 2018 user_list

-rw-------. 1 root root 5116 Oct 31 2018 vsftpd.conf

-rwxr--r--. 1 root root 338 Oct 31 2018 vsftpdconfmigrate.sh

~~~


各个文件的解释


| 文件名 | 作用 |

| :--------------------- | :----------------------------------------------------- |

| vsftpd.conf | 主配置文件 |

| ftpusers | 黑名单 |

| vsftpdconfmigrate.sh | 迁移脚本 |

| userlist | 用户列表,与 userlistenbale 和 userlist_deny 选项密切相关 |


查看主配置文件 vsftpd.conf 内容可以看到各项配置信息,需要根据实际情况来进行配置,其中主要的参数和作用如下:


| 参数 | 作用 |

| :-------------------------------- | :----------------------------------------------------------- |

| listen=[YES\|NO] | 是否以独立运行的方式监听服务 |

| listen_address=IP 地址 | 设置要监听的 IP 地址 |

| listen_port=21 | 设置 FTP 服务的监听端口 |

| download_enable=[YES\|NO] | 是否允许下载文件 |

| userlist_enable=[YES\|NO] | 设置用户列表为“允许”操作 |

| userlist_deny=[YES\|NO] | 设置用户列表为“禁止”操作 |

| max_clients=0 | 最大客户端连接数,0 为不限制 |

| maxperip=0 | 同一 IP 地址的最大连接数,0 为不限制 |

| anonymous_enable=[YES\|NO] | 是否允许匿名用户访问 |

| anonuploadenable=[YES\|NO] | 是否允许匿名用户上传文件 |

| anon_umask=022 | 匿名用户上传文件的 umask 值 |

| anon_root=/var/ftp | 匿名用户的 FTP 根目录 |

| anonmkdirwrite_enable=[YES\|NO] | 是否允许匿名用户创建目录 |

| anonotherwrite_enable=[YES\|NO] | 是否开放匿名用户的其他写入权限(包括重命名、删 除等操作权限) |

| anonmaxrate=0 | 匿名用户的最大传输速率(字节/秒),0 为不限制 |

| local_enable=[YES\|NO] | 是否允许本地用户登录 FTP |

| local_umask=022 | 本地用户上传文件的 umask 值 |

| local_root=/var/ftp | 本地用户的 FTP 根目录 |

| chrootlocaluser=[YES\|NO] | 是否将用户权限禁锢在 FTP 目录,以确保安全 |

| localmaxrate=0 | 本地用户最大传输速率(字节/秒),0 为不限制 |


不用完全记住这些参数,需要时再来查看即可。


2.2 ftp 客户端安装


ftp 是 Linux 系统中以命令行界面的方式来管理 FTP 传输服务的客户端工具。默认也是没有安装的,需要手动安装。


~~~

[root@origin ~]# rpm -q ftp

package ftp is not installed

[root@origin ~]# yum install ftp

Loaded plugins: fastestmirror, langpacks

Loading mirror speeds from cached hostfile

...省略部分内容

Total download size: 61 k

Installed size: 96 k

Is this ok [y/d/N]: y

Downloading packages:

ftp-0.17-67.el7.x86_64.rpm | 61 kB 00:00

Running transaction check

Running transaction test

Transaction test succeeded

Running transaction

Installing : ftp-0.17-67.el7.x86_64 1/1

Verifying : ftp-0.17-67.el7.x86_64 1/1

Installed:

ftp.x86_64 0:0.17-67.el7

Complete!

[root@origin ~]# rpm -q ftp

ftp-0.17-67.el7.x86_64

[root@origin ~]#

~~~


通过 yum install 命令即可安装成功,ftp 客户端工具安装成功后,接下来就是及操作下文件传输的功能。


2.3 vsftpd 三种认证模式


vsftpd 作为更加安全的文件传输的服务程序,允许用户以三种认证模式登录到 FTP 服务器上:*匿名开放模式、本地用户模式、虚拟用户模式*。实际生产环境中虚拟用户模式用的较多。


  • 匿名开放模式:任何人都可以无需密码验证而直接登录到 FTP 服务器,是一种最不安全的认证模式。


  • 本地用户模式:是通过 Linux 系统本地的账户密码信息进行认证的模式。如果被黑客破解了账户信息,就可以畅通无阻地登录 FTP 服务器,从而完全控制整台服务器。


  • 虚拟用户模式:需要为 FTP 服务单独 建立用户数据库文件,虚拟出用来进行口令验证的账户信息,而这些账户信息在 服务器系统中实际上是不存在的,仅供 FTP 服务程序进行认证使用。这样,即使 黑客破解了账户信息也无法登录服务器,从而有效降低了破坏范围和影响。*是三种模式中最安全的一种认证模式*。


2.4 匿名开放模式


匿名开放模式是最不安全的一种认证模式,任何人都可以无需密码验证而直接登录到 FTP 服务器。针对匿名用户放开这些权限会带来潜在危险,生产环境不建议这样做,因此一般不会用匿名模式,尽管如此,但本节还是实际演示一下。


按之前的方法克隆准备 2 台虚拟机:一台主机名为:ftpserver ,用于安装 vsftpd 服务;另外一台主机名为:ftp,用于安装 ftp 客户端。


vsftpd 服务程序默认开启了匿名开放模式,我们需要做的就是开放匿名用户的上传、下 载文件的权限,以及让匿名用户创建、删除、更名文件的权限。


针对匿名模式的配置主要有如下几个参数:


| 参数 | 作用 |

| :-------------------------- | :--------------------------------- |

| anonymous_enable=YES | 允许匿名访问模式 |

| anon_umask=022 | 匿名用户上传文件的 umask 值 |

| anonuploadenable=YES | 允许匿名用户上传文件 |

| anonmkdirwrite_enable=YES | 允许匿名用户创建目录 |

| anonotherwrite_enable=YES | 允许匿名用户修改目录名称或删除目录 |


配置匿名模式主要步骤如下:


2.4.1 服务器配置 vsftp 服务,开启匿名模式


只需要按照上表查找主配置文件中对应的参数,如果是注射掉的就把注射去掉,如果是没有的就新加即可。


但是考虑到该配置文件里边的注释信息是在是太多了,影响配置,干脆我们把与配置无关的注射直接去掉。


~~~

[root@ftpserver ~]# mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak

[root@origin ~]# grep -v "#" /etc/vsftpd/vsftpd.conf.bak >/etc/vsftpd/vsftpd.conf

[root@ftpserver ~]# cat /etc/vsftpd/vsftpd.conf

anonymous_enable=YES

local_enable=YES

write_enable=YES

local_umask=022

dirmessage_enable=YES

xferlog_enable=YES

connectfromport_20=YES

xferlogstdformat=YES

listen=NO

listen_ipv6=YES

pamservicename=vsftpd

userlist_enable=YES

tcp_wrappers=YES

[root@ftpserver ~]#

~~~


上边示例中,我们先把主配置文件备份,然后通过 grep 命令匹配出非注释的参数,然后再重定向将其写入到主配置文件。这样配置文件看起来内容就简洁多了。


然后我们将上表的参数配置到主配置文件即可:


~~~

[root@origin ~]# vi /etc/vsftpd/vsftpd.conf

anonymous_enable=YES

anon_umask=022

anonuploadenable=YES

anonmkdirwrite_enable=YES

anonotherwrite_enable=YES

local_enable=YES

write_enable=YES

local_umask=022

dirmessage_enable=YES

xferlog_enable=YES

connectfromport_20=YES

xferlogstdformat=YES

listen=NO

listen_ipv6=YES

pamservicename=vsftpd

userlist_enable=YES

tcp_wrappers=YES

~~~


实际上第一行已经默认开启了,等于是添加第二到第五行即可。保存并退出,这样就完成了 vsftpd 服务的配置。


配置完成后重启服务,并添加到开机启动。配置并开启 vsftp 服务后,就可以在客户端执行 ftp 命令连接到远程的 FTP 服务器了。


~~~

[root@ftpserver ~]# systemctl restart vsftpd

[root@ftpserver ~]# systemctl enable vsftpd

ln -s '/usr/lib/systemd/system/vsftpd.service' '/etc/systemd/system/multi-user.target.wants/vsftpd.service'

[root@ftpserver ~]#

[root@ftpserver ~]# ll /var/ftp/pub/

total 0

[root@ftpserver ~]# echo "ftp server content">/var/ftp/pub/ftpserver.txt

[root@ftpserver ~]# ll /var/ftp/pub/

total 4

-rw-r--r--. 1 root root 19 Jan 13 23:09 ftpserver.txt

[root@ftpserver ~]#

~~~


在/var/ftp/pub 目录下准备文件,供 ftp 客户端下载。因为客户端连接到 FTP 服务器后,默认访问的是服务器的/var/ftp 目录(该目录下还有一个 pub 目录)。


2.4.2 客户机使用 ftp 服务下载文件


在 vsftpd 服务程序的匿名开放认证模式下,其账户统一为 anonymous,密码为空


~~~

[root@ftp ~]# ftp 192.168.78.101

ftp: connect: No route to host

ftp>

~~~


发现报错了,此时我们首先应该想到的就是 ftpserver 服务器的防火墙,因此我们关闭防火墙来验证一下


~~~

[root@ftpserver ~]# firewall-cmd --state

running

[root@ftpserver ~]# systemctl stop firewalld.service

[root@ftpserver ~]# firewall-cmd --state

not running

[root@ftpserver ~]#

~~~


在 ftpserver 服务器关闭防火墙后,在尝试连接就可以正常连接并下载服务器上的 ftpserver.txt 文件了。


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): anonymous

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> cd pub

250 Directory successfully changed.

ftp> ls

227 Entering Passive Mode (192,168,78,101,132,61).

150 Here comes the directory listing.

-rw-r--r-- 1 0 0 19 Jan 13 15:09 ftpserver.txt

226 Directory send OK.

ftp> get ftpserver.txt

local: ftpserver.txt remote: ftpserver.txt

227 Entering Passive Mode (192,168,78,101,115,121).

150 Opening BINARY mode data connection for ftpserver.txt (19 bytes).

226 Transfer complete.

19 bytes received in 7e-05 secs (271.43 Kbytes/sec)

ftp>

~~~


这样就把 ftpserver 服务器上的 ftpserver.txt 文件下载到了当前用户的家目录下


~~~

[root@ftp ~]# ll

-rw-r--r--. 1 root root 19 Jan 13 23:20 ftpserver.txt

...省略部分无关的文件

[root@ftp ~]# cat ftpserver.txt

ftp server content

[root@ftp ~]#

~~~


到此我们就可以使用 ftp 下载服务器上的文件了。但是有个问题必须的说明一下,前边遇到 ftp 连接问题时,我们直接关闭了服务器上的防火墙。但这是非常不安全的,生产环境中一般都是要求开启防火墙。


那么防火墙是如何阻止了 ftp 客户端连接呢?其实就是因为 firewall 防火墙默认禁止了 ftp 传输的端口号,因此可以清除防火墙的默认策略


~~~

[root@ftpserver ~]# systemctl start firewalld.service

[root@ftpserver ~]# firewall-cmd --state

running

[root@ftpserver ~]# iptables -F

[root@ftpserver ~]# service iptables save

iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

[root@ftpserver ~]#

~~~


清除防火墙默认策略并保存,这样即使服务器不关闭防火墙也可以正常使用功能 ftp 功能下载文件了。


2.4.3 通过 ftp 客户端在服务器上创建目录


接下来我们切换到 pub 目录,并尝试创建一个目录 test


~~~

ftp> cd pub

250 Directory successfully changed.

ftp> mkdir test

550 Create directory operation failed.

ftp>

~~~


好神奇,居然报错了。大家不用担心,学习阶段要的就是这种效果,遇到的错误越多,越能快速积累经验,并建立一套分析问题和解决问题的逻辑思维套路。


分析一下,我们第一步时已经在主配置文件中添加了运行匿名用户创建目录和写入文件的权限,但为何还是会报错呢?既然排除了是用户权限的问题,那么是不是/var/ftp 这个目录的权限问题呢?


~~~

[root@ftpserver ~]# ll -d /var/ftp/pub

drwxr-xr-x. 2 root root 26 Jan 13 23:09 /var/ftp/pub

[root@ftpserver ~]# chown -Rf ftp /var/ftp/pub

[root@ftpserver ~]# ll -d /var/ftp/pub

drwxr-xr-x. 2 ftp root 26 Jan 13 23:09 /var/ftp/pub

[root@ftpserver ~]# ll -d /var/ftp/

drwxr-xr-x. 3 root root 16 Jan 13 22:59 /var/ftp/

~~~


通过查看,果然发现/var/ftp 目录只有 root 用户才有写入的权限,因此我们直接把 pub 目录所有者改为 ftp 用户,让 ftp 用户拥有写入的权限,我们再次来试下看能否创建文件夹


~~~

ftp> mkdir test

550 Create directory operation failed.

ftp>

~~~


奇怪,依然报错。前面排除了用户权限、目录权限之外,我们应该想到很有可能是 SELinux 造成的,因此我们关闭 SELinux 再来验证一下


~~~

[root@ftpserver ~]# setenforce 0

[root@ftpserver ~]#

~~~


关闭 SeLinux 后后,再去创建目录,发现创建成功


~~~

ftp> mkdir test

257 "/pub/test" created

ftp>

~~~


因此,说明不仅要让 pub 目录的属主拥有写入权限,并且同时还要关闭 SELinux 才能创建目录。


但是实际生产环境中不建议关闭 SELinux,所以我们要弄清楚究竟 SELinux 哪个配置影响了


~~~

[root@ftpserver ~]# setenforce 1

[root@origin ~]# getenforce

Enforcing

[root@origin ~]# getsebool -a | grep ftp

ftphomedir --> off

ftpdanonwrite --> off

ftpdconnectall_unreserved --> off

ftpdconnectdb --> off

ftpdfullaccess --> off

ftpdusecifs --> off

ftpdusefusefs --> off

ftpdusenfs --> off

ftpdusepassive_mode --> off

httpdcanconnect_ftp --> off

httpdenableftp_server --> off

sftpdanonwrite --> off

sftpdenablehomedirs --> off

sftpdfullaccess --> off

sftpdwritessh_home --> off

tftpanonwrite --> off

tftphomedir --> off

[root@origin ~]#

~~~


我们查看下 SELinux 状态为开启,查看与 ftp 域相关的策略,其中有一条 ftpdfullaccess --> off 其实就是这条规则导致了操作失败。


修改该策略,并使用-P 参数使其永久生效。


~~~

[root@origin ~]# setsebool -P ftpdfullaccess=on

~~~


再次登录创建目录,发现成功了


~~~

ftp> mkdir test2

257 "/pub/test2" created

ftp>

~~~


因此遇到问题,从用户权限、目录权限、网络防火墙、SELinux 服务几个方面去逐个排查。


2.5 本地用户模式


本地模式比匿名模式更加安全,现在继续在前面的虚拟机中做实验,开始之前先关闭上一实验中开启的匿名模式。


~~~

[root@ftpserver ~]# vim /etc/vsftpd/vsftpd.conf

[root@ftpserver ~]# cat /etc/vsftpd/vsftpd.conf

anonymous_enable=NO

#anon_umask=022

#anonuploadenable=YES

#anonmkdirwrite_enable=YES

#anonotherwrite_enable=YES

local_enable=YES

write_enable=YES

local_umask=022

dirmessage_enable=YES

xferlog_enable=YES

connectfromport_20=YES

xferlogstdformat=YES

listen=NO

listen_ipv6=YES

pamservicename=vsftpd

userlist_enable=YES

tcp_wrappers=YES

[root@ftpserver ~]#

~~~


将 anonymous_enable=YES 改为 NO,即关闭了本地模式,此时就不能在使用匿名模式登陆了。


另外前面新加的与匿名配置参数可以保留,也可以直接删除,只要总开关 anonymous_enable 关闭了就禁用了匿名登录。


现在开始演示本地用户模式操作 ftp。


其实从前面的配置文件可以看出,vsfftpd 服务默认既开启了匿名模式也开启了本地用户模式(local_enable=YES)。以下几个参数是本地用户模式相关的配置


| 参数 | 作用 |

| :------------------ | :--------------------------------------------------- |

| local_enable=YES | 允许本地用户模式 |

| write_enable=YES | 设置可写权限 |

| local_umask=022 | 本地用户模式创建文件的 umask 值 |

| userlistenable=YES | 启用“禁止用户名单”,名单文件为 ftpusers 和 userlist |

| userlist_deny=YES | 开启用户作用名单文件功能 |


2.5.1 配置本地用户模式


其实 vsftpd 默认已经开启了本地用户模式,因此没什么可以配置的,查看下配置文件:


~~~

[root@ftpserver ~]# cat /etc/vsftpd/vsftpd.conf

anonymous_enable=NO

#anon_umask=022

#anonuploadenable=YES

#anonmkdirwrite_enable=YES

#anonotherwrite_enable=YES

local_enable=YES

write_enable=YES

local_umask=022

dirmessage_enable=YES

xferlog_enable=YES

connectfromport_20=YES

xferlogstdformat=YES

listen=NO

listen_ipv6=YES

pamservicename=vsftpd

userlist_enable=YES

tcp_wrappers=YES

[root@ftpserver ~]#

~~~


参考上表,与本地用户配置相关的主要参数为:localenable=YES,writeenable=YES,local_umask=022。如果你的配置文件默认没配置这几个项则手动配置一下即可。


注意,如果修改了配置需要从新启动下 vsftpd 服务


~~~

[root@ftpserver ~]# systemctl restart vsftpd

[root@ftpserver ~]# systemctl enable vsftpd

[root@ftpserver ~]#

~~~


另外再创建一个普通用户 ftptest 并设置密码,用于客户端登录


~~~

[root@ftpserver home]# useradd ftptest

[root@ftpserver home]# passwd ftptest

Changing password for user ftptest.

New password:

BAD PASSWORD: The password is shorter than 8 characters

Retype new password:

passwd: all authentication tokens updated successfully.

[root@ftpserver home]#

~~~


这样 ftp 服务器就准备好了。


特别说明:根据前文的经验,需要按前文方法设置防火墙和 SELinux 策略客户端才能使用,由于我们是沿用之前的配置,之前已经配置好了,所以这里不用配置。默认情况下防火墙将限制登录、SELinux 则限制创建目录等操作。


2.5.2 ftp 客户端操作服务器


现在就可以直接采用 ftpserver 服务器上的普通账户 ftptest 进行文件操作了。


~~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): ftptest

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> mkdir test

257 "/home/ftptest/test" created

ftp> rename test test1

350 Ready for RNTO.

250 Rename successful.

ftp> ls

227 Entering Passive Mode (192,168,78,101,106,178).

150 Here comes the directory listing.

drwxr-xr-x 2 1001 1001 6 Jan 14 09:01 test1

226 Directory send OK.

ftp> rmdir test1

250 Remove directory operation successful.

ftp> exit

221 Goodbye.

[root@ftp ~]#

~~~~


案例中成功通过 ftp 服务器中的 ftptest 用户对目录进行创建、重命名、删除等操作。并且 ftp 客户端创建的目录,在 ftpserver 服务器对应的用户目录下也可以查到新建的目录。


因此可以看到,本地用户模式相对匿名模式,配置更简单一些。但是大家想过为啥 ftptest 用户登录后就可以对目录进行创建、删除等操作吗?*那是因为本地用户模式登录 FTP 服务器后,默认访问的是该用户的家目录*,即/home/ftptest 目录,它的默认所有者、所属组都是该用户自己,因此不存在写入权限不足的情况。


2.5.3 本地用户登录模式之填坑


如果你是按照我的文章步骤操作,一定会很顺畅,但是如果一开始并不是新建 ftptest 用户来登录,而是直接使用 root 用户来进行远程登录,那就有个坑需要注意一下。


在客户端用 root 登录试试看


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): root

530 Permission denied.

Login failed.

ftp>

~~~


哦豁,目前的系统 root 是拥有最高权限的,居然被拒了,而前边创建的普通用户 ftptest 用户居然可以正常使用 ftp 功能!我就遇到过,哈哈哈哈,百思不得解。


如果是初次接触真可能怀疑是自己哪个步骤操作错了,其实这里有一个规则:


vsftpd 服务程序配置目录存放着两个“用户名单”的文件:ftpusers、user_list。原因就在这 2 个文件,只要这 2 个文件中存在的用户,就不允许登录 FTP 服务器上。


来看看这 2 个文件内容:


~~~

[root@ftpserver ~]# cat /etc/vsftpd/user_list

root

bin

daemon

adm

lp

sync

shutdown

halt

mail

news

uucp

operator

games

nobody

[root@ftpserver ~]# cat /etc/vsftpd/ftpusers

root

bin

daemon

adm

lp

sync

shutdown

halt

mail

news

uucp

operator

games

nobody

[root@ftpserver ~]#

~~~


果然里边存在 root 用户,这正是 vsftpd 服务为了保证服务器安全默认就禁止了 root 和大部分系统用户登录 ftp。这样做的好处是避免黑客通过 FTP 服务器对 root 密码进行暴力破解。


而为啥之前创建的 ftptest 用户可以登录 ftp 呢,那是因为创建的用户并没有被默认写入这 2 个文件。如果确保在生产环境中直接使用 root 用户对安全性没有影响,则直接在这 2 个文件中把 root 删除即可,否则请使用这 2 个文件中不存在的普通用户来登录 ftp 服务器。


删除这 2 个文件中的 root 用户,然后重启 vsftpd 服务,再次使用 root 登录 ftp 即可成功操作。


2.6 虚拟用户模式


再来看一种更加安全的认证模式即虚拟用户模式,因为更加安全所以配置起来稍微要麻烦一些。


我们仍然在之前的机器上继续操作,步骤步骤如下:


2.6.1 创建用户数据库文件


在 ftpserver 服务器中的 vsftpd 配置目录下创建包含用户信息的文件 vuser.list(文件名字任意取)


~~~

[root@ftpserver ~]# cd /etc/vsftpd/

[root@ftpserver vsftpd]# ls

ftpusers userlist vsftpd.conf vsftpd.conf.bak vsftpdconf_migrate.sh

[root@ftpserver vsftpd]# vim vuser.list

vuser1

123456

vuser2

123456

~~~


vuser.list 文件中包含 vuser1 和 vuser2 两个用户,密码均为 123456。文件中奇数行表示账号名,偶数行表示密码。


接下来要将 vuser.list 文件转换为 vsftpd 服务程序能直接加载的格式,转换格式使用 db_load 命令,该命令用哈希算法将原始的明文信息文件转换为数据库文件。


在使用 db_load 命令前,查看该命令是否安装


~~~

[root@ftpserver vsftpd]# db_load

usage: db_load [-nTV] [-c name=value] [-f file]

[-h home] [-P password] [-t btree | hash | recno | queue] db_file

usage: dbload -r lsn | fileid [-h home] [-P password] dbfile

[root@ftpserver vsftpd]#

~~~


出现该命令的用法,说明默认已经安装了。


如果未安装需要手动安装,该命令包含在 db4 包中,使用命令 yum -y install db4 安装即可。


既然安装了 db_load 命令,那就使用它来转换用户文件格式


~~~

[root@ftpserver vsftpd]# db_load -T -t hash -f vuser.list vuser.db

[root@ftpserver vsftpd]# file vuser.db

vuser.db: Berkeley DB (Hash, version 9, native byte-order)

[root@ftpserver vsftpd]# ll vuser.db

-rw-r--r--. 1 root root 12288 Jan 14 21:16 vuser.db

[root@ftpserver vsftpd]# chmod 600 vuser.db

-rw-------. 1 root root 12288 Jan 14 21:16 vuser.db

[root@ftpserver vsftpd]# rm -rf vuser.list

[root@ftpserver vsftpd]#

~~~


通过 db_load 命令就把明文的 vuser.list 文件转换为了 vuser.db 格式的文件,并通过 chmod 命令降低该文件的权限,从而避免其他人查看到该数据库文件的内容,最后直接把明文的 vuser.list 文件删除。


2.6.2 创建 PAM 文件


PAM(Pluggable Authentication Module)是一种认证机制,它将服务与认证方式分开,使得系统管理员可以轻易的调整服务程序的认证方式,而不必对应用程序进行任何修改。它涉及的内容挺多的,此处仅仅先了解概念即可。


在 ftpserver 服务器上新建一个 PAM 文件 vsftpd.vu(文件名可以任意)用于虚拟用户认证,文件内的 db 参数为上一步使用功能 db_load 命令生成的数据库文件的路径,但不用写后缀名


~~~

[root@ftpserver vsftpd]# vim /etc/pam.d/vsftpd.vu

auth required pam_userdb.so db=/etc/vsftpd/vuser

account required pam_userdb.so db=/etc/vsftpd/vuser

~~~


2.6.3 创建本地用户


既然是虚拟用户认证,为啥还需要建立本地用户呢?可以简单理解为虚拟指定一个 ftp 文件存储的根目录,当虚拟用户登录 ftp 服务器后默认访问的就是这个目录。


由于 Linux 中一切文件都有所有者和所属组,假设前文创建的虚拟用户 vuser1 创建了一个文件,但是系统中却没有 vuser1 这个用户,就会导致文件的权限出现错误。因此需要创建一个本地用户来映射虚拟用户,让虚拟用户默认登录到与之有映射关系的这个系统本地用户的家目录中,虚拟用户创建的文件的属性也都归属于这个系统本地用户,从而避免 Linux 系统无法处理虚拟用户所创建文件的属性权限。


由于 ftp 目录中的文件可能经常变化,因此我们新建一个本地用户 virtual 并指定其家目录为/var/ftpdir 目录。同时我们禁用此本地用户登录 FTP 服务器,从而避免黑客利用该本地用户登录系统。禁止与虚拟用户关联的本地用户并不会影响虚拟用户的登录。


~~~

[root@ftpserver vsftpd]# useradd -d /var/ftpdir -s /sbin/nologin virtual

[root@ftpserver vsftpd]# ll -d /var/ftpdir/

drwx------. 3 virtual virtual 74 Jan 14 21:46 /var/ftpdir/

[root@ftpserver vsftpd]# chmod -Rf 755 /var/ftpdir/

[root@ftpserver vsftpd]# ll -d /var/ftpdir/

drwxr-xr-x. 3 virtual virtual 74 Jan 14 21:46 /var/ftpdir/

[root@ftpserver vsftpd]#

~~~


修改目录权限,让其他人可读。


2.6.4 vsftpd 主配置文件配置


配置 vsftpd 主配置文件,指定之前创建的 PAM 认证文件以及与虚拟用户关联的本地用户。


~~~

[root@ftpserver vsftpd]# vim /etc/vsftpd/vsftpd.conf

anonymous_enable=NO

#anon_umask=022

#anonuploadenable=YES

#anonmkdirwrite_enable=YES

#anonotherwrite_enable=YES

local_enable=YES

guest_enable=YES

guest_username=virtual

allowwriteablechroot=YES

write_enable=YES

local_umask=022

dirmessage_enable=YES

xferlog_enable=YES

connectfromport_20=YES

xferlogstdformat=YES

listen=NO

listen_ipv6=YES

pamservicename=vsftpd.vu

userlist_enable=YES

tcp_wrappers=YES

~~~


实际就是在原有基础上添加:guestenable=YES、guestusername=virtual、allowwriteablechroot=YES,并修改 pamservicename=vsftpd.vu 为之前创建的 pam 认证文件。另外注意,必须开启本地模式(local_enable=YES)。


虚拟用户认证相关参数及作用如下:


| 参数 | 作用 |

| :------------------------- | :---------------------------------------------------------- |

| anonymous_enable=NO | 禁止匿名开放模式 |

| local_enable=YES | 允许本地用户模式 |

| guest_enable=YES | 开启虚拟用户模式 |

| guest_username=virtual | 指定虚拟用户账户 |

| pamservicename=vsftpd.vu | 指定 PAM 文件,存放于/etc/pam.d/目录下,默认是 vsftpd 文件 |

| allowwriteablechroot=YES | 允许对禁锢的 FTP 根目录执行写入操作,而且不拒绝用户的登录请求 |


2.6.5 虚拟用户权限设置


假设我们要区别对待 vuser1 和 vuser2,只允许 vuser1 查看文件,而允许 vuser2 上传、创建、修改、查看、删除文件。这种需求在企业真实环境中是常见的,我们可以通过 vsftpd 服务器程序来实现。


~~~

[root@ftpserver vsftpd]# mkdir /etc/vsftpd/vusers_dir

[root@ftpserver vsftpd]# cd vusers_dir/

[root@ftpserver vusers_dir]# touch vuser1

[root@ftpserver vusers_dir]# vim vuser2

anonuploadenable=YES

anonmkdirwrite_enable=YES

anonotherwrite_enable=YES

~~~


只需要在 vsftpd 配置目录下新建 vusers_dir 目录(名字可以任意取),在目录中分别对应这 2 个用户创建文件并写入权限即可。


同时修改 vsftpd 主配置文件,过添加 userconfigdir 参数来定义这两个虚拟用户不同权限的配置文件所存放的路径。


~~~

[root@ftpserver vsftpd]# vim /etc/vsftpd/vsftpd.conf

...省略原有内容

userconfigdir=/etc/vsftpd/vusers_dir

~~~


配置完成之后重启 vsftpd 服务。


2.6.6 验证不同虚拟用户设置的权限是否生效


此时我们就可以使用虚拟用户 vuser1 和 vuser2 登录 ftp 进行测试了


由于我们按照之前的基础上进行演示,之前已经配置好了防火墙和 SELinux 相关策略,因此这里无需配置(实际操作时要根据实际情况进行,防火墙和 SELinux 会对 ftp 客户端的操作造成影响)。


使用 vuser1 登录测试验证是否有创建目录权限


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): vuser1

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> mkdir test

550 Permission denied.

ftp> exit

221 Goodbye.

[root@ftp ~]#

~~~


正如之前设置一样,vuser1 只有查看权限,没有创建目录的权限。


再来看看 vuser2


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): vuser2

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> mkdir vuser2

257 "/vuser2" created

ftp> rmdir vuser2

250 Remove directory operation successful.

ftp> exit

221 Goodbye.

[root@ftp ~]#

~~~


正如需求一致,vuser2 具备创建和删除目录的权限。这样就可以根据实际需要灵活配置不同用户的权限。


2.6.7 其他注意事项及常见错误


(1)配置了虚拟用户登录后,本地用户登录就会失效


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): root

331 Please specify the password.

Password:

530 Login incorrect.

Login failed.

ftp> exit

221 Goodbye.

[root@ftp ~]#

~~~


(2)2.6.4 节中的 vsftpd 主配置文件中必须要开启本地登录模式


如果不开,将报错,提示本地模式和匿名模式必须开启一个,显然虚拟用户模式就是为了提高安全,因此我们不开匿名模式而开启本地模式。


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

500 OOPS: vsftpd: both local and anonymous access disabled!

ftp> exit

[root@ftp ~]#

~~~


(3)2.6.4 节中的主配置文件参数 allowwriteablechroot=YES 必须开启


如果不开将报错


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): vuser1

331 Please specify the password.

Password:

500 OOPS: vsftpd: refusing to run with writable root inside chroot()

Login failed.

421 Service not available, remote server has closed connection

ftp> exit

[root@ftp ~]#

~~~


(3)防火墙影响 ftp 登录不了


默认情况防火墙策略阻止了 ftp 端口,ftp 客户端登录将得到如下错误


~~~

[root@ftp ~]# ftp 192.168.78.101

ftp: connect: No route to host

ftp> exit

~~~


此时需要在 ftp 服务器上执行:iptables -F


(4)SELinux 阻止文件创建


本来 vuser2 是有创建文件权限的,但是由于受到默认 SELinux 策略影响,将不能创建文件


~~~

[root@ftp ~]# ftp 192.168.78.101

Connected to 192.168.78.101 (192.168.78.101).

220 (vsFTPd 3.0.2)

Name (192.168.78.101:root): vuser2

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> mkdir vuser2

550 Create directory operation failed.

ftp> exit

221 Goodbye.

[root@ftp ~]#

~~~


此时需要在 ftp 服务器执行:setsebool -P ftpdfullaccess=off 命令即可。


三、简单文件传输协议 TFTP


3.1 TFTP 概述


TFTP(Trivial File Transfer Protocol)简单文件传输协议,是一种基于 UDP 协议在客户端和服务器之间进行简单文件传输的协议。可以认为它是 FTP 协议的简化版本。


3.2.1 TFTP 缺点


TFTP 的命令功能不如 FTP 服务强大,不能遍历目录,在安全性方比 FTP 差。传输文件采用 UDP 协议,端口号为 69,文件传输过程不如 FTP 协议可靠。


3.2.2 TFTP 优点


TFTP 不需要客户端的权限认证, 减少了无谓的系统和网络带宽消耗,因此在传输琐碎(trivial)不大的文件时,效率更高。


3.2 TFTP 操作案例


3.2.1 TFTP 安装并启动


我们还是继续使用之前的两台虚拟机,在主机 ftpserver 上安装 tftpsever 服务,在主机 ftp 上安装 tftp 服务。


(1)tftp 服务器安装


~~~

[root@ftpserver ~]# rpm -q tftp-server

package tftp-server is not installed

[root@ftpserver ~]# yum install tftp-server

...省略中间内容

Installed:

tftp-server.x86_64 0:5.2-22.el7

Complete!

[root@ftpserver ~]

~~~


在 RHEL7 系统中,TFTP 服务是使用 xinetd 服务程序来管理的,在安装 TFTP 软件包后,还需要在 xinetd 服务程序中将其开启。


配置之前先看 tftp 服务器是否安装 xinetd 服务


~~~

[root@ftpserver ~]# systemctl restart xinetd

Failed to issue method call: Unit xinetd.service failed to load: No such file or directory.

~~~


出现这个结果表示为安装 xinetd,需要手动进行安装。


~~~

[root@ftpserver ~]# yum install xinetd

~~~


在 tftp 服务器中,修改/etc/xinetd.d/tftp 配置文件,将 disable=yes 改为 no


~~~

[root@ftpserver ~]# vim /etc/xinetd.d/tftp

service tftp

{

socket_type = dgram

protocol = udp

wait = yes

user = root

server = /usr/sbin/in.tftpd

server_args = -s /var/lib/tftpboot

disable = no

per_source = 11

cps = 100 2

flags = IPv4

}

[root@ftpserver ~]#

~~~


修改后重启 xinetd 服务并添加到开机启动。


~~~

[root@ftpserver ~]# systemctl restart xinetd

[root@ftpserver ~]# systemctl enable xinetd

~~~


考虑到有些系统的防火墙默认没有允许 UDP 协议的 69 端口,因此 需要手动将该端口号加入到防火墙的允许策略中。


~~~

[root@ftpserver ~]# firewall-cmd --permanent --add-port=69/udp

success

[root@ftpserver ~]# firewall-cmd --reload

success

[root@ftpserver ~]#

~~~


TFTP 的根目录为/var/lib/tftpboot。


在 tftp 服务器上,创建文件 tftptest.txt 以供 tftp 下载


~~~

[root@ftpserver ~]# echo "test tftp">/var/lib/tftpboot/tftptest.txt

[root@ftpserver ~]# ll /var/lib/tftpboot/

total 4

-rw-r--r--. 1 root root 10 Jan 14 23:05 tftptest.txt

[root@ftpserver ~]#

~~~


(2)fttp 客户端安装


~~~

[root@ftp ~]# rpm -q tftp

package tftp is not installed

[root@ftp ~]# yum install tftp

...省略中间内容

Installed:

tftp.x86_64 0:5.2-22.el7

Complete!

[root@ftp ~]#

~~~


3.2.2 使用 TFTP


在 tftp 客户端连接到 tftpserver 并下载文件


~~~

[root@ftp ~]# tftp 192.168.78.101

tftp> get tftptest.txt

tftp> quit

[root@ftp ~]# ll tftptest.txt

-rw-r--r--. 1 root root 10 Jan 14 23:09 tftptest.txt

[root@ftp ~]# cat tftptest.txt

test tftp

[root@ftp ~]#

~~~


可以看到已经成功把文件下载到本地了。


3.2.3 TFTP 相关的命令


列举几个 tftp 相关的命令和参数


| 命令 | 作用 |

| :------ | :-------------------- |

| ? | 帮助信息 |

| put | 上传文件 |

| get | 下载文件 |

| verbose | 显示详细的处理信息 |

| status | 显示当前的状态信息 |

| binary | 使用二进制进行传输 |

| ascii | 使用 ASCII 码进行传输 |

| timeout | 设置重传的超时时间 |

| quit | 退出 |


当然 TFTP 还有很多其他用户,以后有机会在深入讨论。


下一篇文章将讲解 Linux 下文件共享的方法。



自学帮


发布于: 2020 年 08 月 25 日阅读数: 107
用户头像

黑马腾云

关注

程序员、终身学习者、创业者。 2020.06.22 加入

“自学帮”公众号主。

评论

发布
暂无评论
linux入门系列15--文件传输之vsftp服务