FTP服务器搭建及典型问题的解决

FTP服务器搭建及典型问题的解决

SSH管理远程Linux服务器少不了文件的传输,虽然lrzsz能够解决本地与远程服务器之间文件传输的问题,使用sz/rz即可,比如:

sz filename #发送一个文件到本地
sz filename1 filename2 #发送多个文件到本地
sz dir/* #发送dir目录下的所有文件,不包含dir下的文件夹

从本地传文件到服务器在终端输入rz即可。参考这里

但是lrzsz处理小文件可以,处理大文件效果就不太好,因此,可以选择另一种方式,没错,搭建一个FTP服务器。而且FTP服务器能支持多人对文件的共享。

搭建FTP服务器

我的服务器是CentOS的,因此下面的配置以CentOS下的配置为例,不过其他Linux系统大同小异,根据个人情况配置即可。

安装vsftpd

Linux下轻便的的ftp程序应该就是vsftpd了,这里我们直接yum安装:

yum install -y vsftpd

配置vsftpd

vsftpd的配置目录为/etc/vsftpd,包含下列的配置文件:

  • vsftpd.conf为主要配置文件
  • ftpusers配置禁止访问 FTP 服务器的用户列表
  • user_list配置用户访问控制

这里我们主要对vsftpd.conf进行配置,这里可以先用下面这条命令看初始的配置有哪些:

cat /etc/vsftpd/vsftpd.conf | grep -v "#" | more

各项配置的规则如下:

# 开启匿名登录
anonymous_enable=YES
# 允许使用本地帐户进行FTP用户登录验证
local_enable=YES
# 允许写
write_enable=YES
# 设置本地用户默认文件掩码022
local_umask=022
# 允许匿名上传
anon_upload_enable=YES
# 允许匿名创建新目录
anon_mkdir_write_enable=YES
# 同时开放其它权限
anon_other_write_enable=YES
# 可以发送消息当访问某个目录时
dirmessage_enable=YES
# 开启上传下载记录
xferlog_enable=YES
# 数据链通过20端口建立
connect_from_port_20=YES

# 允许其它用户上传匿名文件
#chown_uploads=YES
# 所有用户
#chown_username=whoever
# 日志保存到
#xferlog_file=/var/log/xferlog
# 日志标准输出
xferlog_std_format=YES
# 空闲会话时间
#idle_session_timeout=600
# 数据连接超时时间
#data_connection_timeout=120
# 隔离的安全用户
#nopriv_user=ftpsecure
# 开启异步数据线程
#async_abor_enable=YES
# 开启ASCII协议上传
ascii_upload_enable=YES
# 开启ASCII协议下载
ascii_download_enable=YES
# 开启邮箱验证
#deny_email_enable=YES
# 拒绝的邮箱列表
#banned_email_file=/etc/vsftpd/banned_emails

# 是否允许直接获取子目录信息
#ls_recurse_enable=YES
# 监听IPv4
listen=NO
# 监听IPv6和监听IPv4
listen_ipv6=YES

# 虚拟用户启用pam认证
pam_service_name=vsftpd
# 用户组管理
userlist_enable=YES
# 访问控制
tcp_wrappers=YES

# 允使用被动模式
pasv_enable=YES
# 指定使用被动模式时打开端口的最小值
pasv_min_port=10060
# 指定使用被动模式时打开端口的最大值。
pasv_max_port=10090
# 用户宽带限制200kps
#local_max_rate=200000
# 登录后欢迎内容
ftpd_banner=Welcome to My FTP service.

# ---------开启虚拟用户组参数--------
# 开启虚拟用户
guest_enable=YES
# 主虚拟用户名vsftpd,等下会建立
guest_username=vsftpd
# 虚拟用户配置(可以对每一个虚拟用户进行单独的权限配置)
user_config_dir=/etc/vsftpd/vconf

# 启用限定用户在其主目录下
chroot_local_user=YES
# 开启用户列表chroot管理
chroot_list_enable=YES
# chroot管理的用户列表(一行一用户,虚拟用户都要添加进去)
# 当设置用户只能在登录目录时,chroot管理的用户为不受限制,否则相反
chroot_list_file=/etc/vsftpd/chroot_list
# 允许chroot管理用户进行写操作
allow_writeable_chroot=YES

# ---------虚拟用户高级参数(请选择一组)--------
# 虚拟用户和本地用户有相同的权限
virtual_use_local_privs=YES

# 虚拟用户和匿名用户有相同的权限,默认是NO
virtual_use_local_privs=NO

# 虚拟用户具有写权限(上传、下载、删除、重命名)
virtual_use_local_privs=YES
write_enable=YES

# 虚拟用户不能浏览目录,只能上传文件,无其他权限
virtual_use_local_privs=NO
write_enable=YES
anon_world_readable_only=YES
anon_upload_enable=YES

# 虚拟用户只能下载文件,无其他权限
virtual_use_local_privs=NO
write_enable=YES
anon_world_readable_only=NO
anon_upload_enable=NO

# 虚拟用户只能上传和下载文件,无其他权限
virtual_use_local_privs=NO
write_enable=YES
anon_world_readable_only=NO
anon_upload_enable=YES

# 虚拟用户只能下载文件和创建文件夹,无其他权限
virtual_use_local_privs=NO
write_enable=YES
anon_world_readable_only=NO
anon_mkdir_write_enable=YES

# 虚拟用户只能下载、删除和重命名文件,无其他权限
virtual_use_local_privs=NO
write_enable=YES
anon_world_readable_only=NO
anon_other_write_enable=YES

而我们不一定每项都进行配置,在初始的基础之上,进行如下配置即可:

# 上面已经给了全部配置的含义,自己比对即可
anonymous_enable=NO
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
allow_writeable_chroot=YES
local_root=/data/ftp/ #给ftp账户指定主目录
listen_port=60021 #这里也可以不设置,默认ftp是21端口

配置完之后保存,然后重启vsftpd。

创建FTP用户

首先创建一个新账户ftpuser

useradd ftpuser

然后为其设置密码:

passwd ftpuser

现在这个账户其实是一个可登录的Linux用户,为了安全,我们要限制用户的权限,不能让其登录linux而只能用于登录FTP服务器:

usermod -s /sbin/nologin ftpuser

指定主目录

前面配置文件里看到了我们为ftp用户指定了主目录/data/ftp,但是初始情况该目录可能不存在,需要新建文件目录:

chmod a-w /data/ftp && chmod 777 -R /data/ftp/pub

这里同时也为目录设置了权限,可以看到pub目录是777权限,文件的上传、下载也就在此目录之下了。

然后设置为用户主目录:

usermod -d /data/ftp ftpuser

防火墙设置

前面的listen_port如果更改的话,也要在防火墙来开放其端口:

firewall-cmd --zone=public --add-port=60021/tcp --permanent

然后重启防火墙:

firewall-cmd --reload

至此,基础的配置也就完毕了,下面进行测试。

测试服务器及问题发现

连接FTP服务器可以选用一些FTP客户端软件:FileZilla ClientCuteFTP等很多,我用了FileZilla Client进行测试。

这里由于FTP的连接有两种模式:主动(POST)被动(PASV)两种模式:

POST模式:当客户端C向服务端S连接后,使用的是Port模式,那么客户端C会发送一条命令告诉服务端S(客户端C在本地打开了一个端口N在等着你进行数据连接),当服务端S收到这个Port命令后 就会向客户端打开的那个端口N进行连接,这种数据连接就生成了。

PASV模式:当客户端C向服务端S连接后,使用的是Port模式,那么客户端C会发送一条命令告诉服务端S(客户端C在本地打开了一个端口N在等着你进行数据连接),当服务端S收到这个Port命令后 就会向客户端打开的那个端口N进行连接,这种数据连接就生成了。

按照前面的基础配置在测试时发现主动和被动模式登录都存在问题

主动模式连接的问题

首次连接发现可以登录,但是读取目录列表失败,报错情况如下:

根据报错提示:

状态:	已登录
状态: 读取目录列表...
命令: PWD
响应: 257 "/data/ftp"
命令: TYPE I
响应: 200 Switching to Binary mode.
命令: PORT xx,xx,xx,xx,216,94
响应: 500 Illegal PORT command.
命令: PASV
响应: 227 Entering Passive Mode (xx,xx,xx,xx,227,27).
命令: LIST
错误: 20 秒后无活动,连接超时
错误: 读取目录列表失败

根据报错日志,不难理解,当成功登录之后,进行目录读取,其实也就是数据传输的时候,因为是主动模式,服务器会主动向客户端这边进行连接,即向21694端口进行连接,然后就报错了,根本原因应该就是客户端机器的防火墙对该端口并没有开放,因此连接肯定是失败的。然后又采用了被动模式进行连接,即服务器开放22727端口等待客户端连接,然而还是失败了,原因何在呢?

由于一些客观原因,我没有对自己的客户机的防火墙进行更改,而是换用被动模式,当然,也遇到了一些问题。

被动模式连接的问题

采用被动连接的方式,首先需要在vsftpd.conf下进行如下配置:

pasv_enable=YES	#开启被动模式
pasv_min_port=44550 #指定被动模式最小端口
pasv_max_port=44551 #指定被动模式最大端口
pasv_promiscuous=YES #关闭被动模式的安全检查(这个检查可以确保数据连接源于同一IP地址)

重启vsftpd服务

支持了被动模式,并且指定了端口开放范围,那么我们在防火墙进行端口的配置即可。

重启防火墙,然后再次测试:

可以看到目录成功列举了,问题得到解决。

上传文件失败的问题

当能成功登录、成功列举目录了之后,最主要的目的当然是文件的上传和下载了,然后当去测试的时候,又出现了问题:

报错:553 Could not create file.

本来想着很简单,应该是文件夹权限的问题,但是对文件夹改了777,甚至/data都改成777了还是不行,后来查资料,网上说可能是SELinux的问题,这是个什么呢?

SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。NSA是在Linux社区的帮助下开发了一种访问控制体系,在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。 –百科

SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)。

这里有一篇不错的文章可以参考。

那么我们关闭SELinux试试:setenforce 0,然后测试一下看看:

果然成了,那就是它的问题了,下面就对其进行配置
先看一下权限:getsebool -a | grep ftpd

# 网上是这样的
allow_ftpd_anon_write --> off
allow_ftpd_full_access --> off
allow_ftpd_use_cifs --> off
allow_ftpd_use_nfs --> off
ftpd_connect_db --> off
ftpd_use_passive_mode --> off
ftp_home_dir --> off

# 但是我的服务器是这样的
ftpd_anon_write --> off
ftpd_connect_all_unreserved --> off
ftpd_connect_db --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_fusefs --> off
ftpd_use_nfs --> off
ftpd_use_passive_mode --> off

系统之间的差异,没办法,但是解决方式是一样的,命令行执行下面两条命令:

setsebool -P ftp_home_dir 1 #这一条命令我的服务器上没执行成功
setsebool -P allow_ftpd_full_access 1

然后再开启SELinux:setenforce 1

再次进行测试:

可以看到,成功上传文件,问题解决。

下载文件失败的问题

尝试从服务器上下载文件时,又error了…

可以看到,下载文件时报错:550 Failed to open file.
这次问题其实不复杂,很容易想到是文件权限的问题,看一下:

可以看到test.cap文件是属于root用户组的,并且权限很小,你一个ftpuser用户去操作它肯定没权限,那简单,改一下不就好了:chmod -R 777 test.cap,再试试:

话说回来,如果没有特殊需要,还是用lrzsz方便…
最后,希望这篇文章能够帮助到你。

参考:
基于CentOS搭建FTP文件服务
CentOS7安装FTP服务器
553 Could not create file问题的解决

Comments


:D 一言句子获取中...

Loading...Wait a Minute!