配置 vsftpd 搭建 FTP 服务器

常用命令:

# 安装 vsftpd
yum install -y vsftpd
# 检查|启动|停止|重启 vsftpd 服务
service vsftpd status|start|stop|restart
# 设置开机自启动
systemctl enable vsftpd.service
# 让防火墙开启 FTP 服务和 21 端口的使用
firewall-cmd --add-service=ftp --permanent
firewall-cmd --add-port=21/tcp --permanent
firewall-cmd --reload

在 vsftpd 服务器中支持匿名用户,本地用户,和虚拟用户3类用户账号,用途及区别如下:

匿名用户:是名为anonymous或ftp的用户,匿名FTP用户登录后将FTP服务器中的/var/ftp作为FTP根目录。

本地用户:是 Linux 系统用户账号,使用本地用户账号登录FTP服务器后,登录目录为本地用户的宿主目录。

虚拟用户:为了保证FTP服务器的安全性,由vsftpd服务器提供的非系统用户账号。虚拟用户FTP登录后将把指定的目录作为FTP根目录。虚拟用户与本地用户具有类似的功能,由于虚拟用户相对安全,因此正逐步替代本地用户账号的使用。

基本会用到的相关文件及所在目录:

# vsftp配置文件
/etc/vsftpd/vsftpd.conf
# PAM认证文件
/etc/pam.d/vsftpd
# 匿名用户默认目录
/var/ftp
# 匿名用户的下载目录
/var/ftp/pub
# 不能访问 ftp server 的用户列表
/etc/vsftpd/ftpusers
# 允许访问 ftp server 的用户列表
/etc/vsftpd/user_list
# ftp 的上传下载日志
/var/log/xferlog

为了正常使用,需要修改vsftpd.conf的部分内容如下:

# 是否允许匿名登录FTP服务器。
anonymous_enable=NO

# 是否允许本地用户(即linux系统中的用户帐号)登录FTP服务器,
# 默认设置为YES允许,本地用户登录后会进入用户主目录;
# 而匿名用户登录后进入匿名用户的下载目录/var/ftp;
# 若只允许匿名用户访问,前面加上#,可阻止本地用户访问FTP服务器。
local_enable=YES

# 是否允许本地用户对FTP服务器文件具有写权限,默认设置为YES允许。
write_enable=YES

# 设置本地用户的文件掩码为缺省022,
# 也可根据个人喜好将其设置为其他值。
local_umask=022

# 是否允许匿名用户上传文件,须将上面的write_enable设置为YES允许。
#anon_upload_enable=YES

# 是否允许匿名用户创建新文件夹。
#anon_mkdir_write_enable=YES

# 是否激活目录欢迎信息功能,
# 当用户用CMD模式首次访问服务器上某个目录时,FTP服务器将显示欢迎信息;
# 默认情况下,欢迎信息是通过该目录下的.message文件获得的,
# 此文件保存自定义的欢迎信息,由用户自己建立。
dirmessage_enable=YES

# 如果启用此选项,系统将会维护记录服务器上传和下载情况的日志文件;
# 默认情况该日志文件为/var/log/vsftpd.log,
# 也可以通过下面的xferlog_file选项对其进行设定。
xferlog_enable=YES

# 设定FTP服务器将启用FTP数据端口的连接请求,ftp-data数据传输,21为连接控制端口。
connect_from_port_20=YES

# 设定是否允许改变上传文件的属主,与下面一个设定项配合使用;
# 注意,不推荐使用root用户上传文件。
#chown_uploads=YES

# 设置想要改变的上传文件的属主,如果需要,则输入一个系统用户名;
# 例如可以把上传的文件都改成root属主。whoever:任何人。
#chown_username=whoever

# 设定系统维护记录FTP服务器上传和下载情况的日志文件,
# /var/log/vsftpd.log是默认的,也可以另设其它
#xferlog_file=/var/log/vsftpd.log

# 如果启用此选项,传输日志文件将以标准xferlog的格式书写;
# 该格式的日志文件默认为/var/log/xferlog,
# 也可以通过xferlog_file选项对其进行设定,默认值为NO
xferlog_std_format=YES

# 如果添加并启用此选项,将生成两个相似的日志文件;
# 默认在/var/log/xferlog和/var/log/vsftpd.log目录下;
# 前者是wu_ftpd类型的传输日志,可以利用标准日志工具对其进行分析,后者是vsftpd类型的日志。
#dual_log_enable

# 如果添加并启用此选项,则原本应该输出到/var/log/vsftpd.log中的日志,将输出到系统日志中。
#syslog_enable

# 设置数据传输中断间隔时间,此语句表示空闲的用户会话中断时间为600秒;
# 即当数据传输结束后,用户连接FTP服务器的时间不应超过600秒,可以根据实际情况对该值进行修改。
idle_session_timeout=600

# 设置数据连接超时时间,该语句表示数据连接超时时间为120秒,可根据实际情况对其个修改。
data_connection_timeout=120

# 运行vsftpd需要的非特权系统用户,缺省是nobody。
#nopriv_user=ftpsecure

# 如果FTPclient会下达“async ABOR”这个指令时,这个设定才需要启用;
# 而一般此设定并不安全,所以通常将其取消。
#async_abor_enable=YES

# 大多数FTP服务器都选择用ASCII方式传输数据,
# 将#去掉就能实现用ASCII方式上传文件。
#ascii_upload_enable=YES

# 将#去掉就能实现用ASCII方式下载文件
#ascii_download_enable=YES

# 将#去掉可设置登录FTP服务器时显示的欢迎信息,
# 可以修改=后的欢迎信息内容。
# 另外如在需要设置更改目录欢迎信息的目录下创建名为.message的文件,
# 并写入欢迎信息保存后,在进入到此目录会显示自定义欢迎信息。
#ftpd_banner=Welcome to blah FTP service. 

# 可将某些特殊的email address抵挡住。
# 如果以anonymous登录服务器时,会要求输入密码,也就是您的email address;
# 如果很讨厌某些email address,就可以使用此设定来取消他的登录权限,但必须与下面的设置项配合。
#deny_email_enable=YES

# 当上面的deny_email_enable=YES时,可以利用这个设定项来规定那个email address不可登录vsftpd服务器。
# 此文件需用户自己创建,一行一个email address即可。
#banned_email_file=/etc/vsftpd/banned_emails

# 是否将所有用户限制在主目录,YES 为启用,NO 禁用。
# 为 YES 时,用户被锁定在自己的home目录中;
# 为 NO 时,用户登录FTP服务器后具有访问自己目录以外的其他文件的权限。
# vsftpd 将寻找 chroot_list 文件作为用户名单,此文件需用户建立。
chroot_local_user=YES

# 如果用户被限定在了其主目录下,则该用户的主目录不能再具有写权限。
# 下面这条命令将允许主目录继续保持写权限。
allow_writeable_chroot=YES

# 是否启动限制用户例外的名单,YES 为启用,NO 禁用。
chroot_list_enable=NO

# 此文件需自己建立,每行一个用户,
# 被列入此文件的用户,在登录后将不能切换到自己目录以外的其他目录,
# 由FTP服务器自动地chrooted到用户自己的home目录下;
# 使得chroot_list文件中的用户不能随意转到其他用户的FTPhome目录下,
# 从而有利于FTP服务器的安全管理和隐私保护。
# chroot_list_file=/etc/vsftpd/chroot_list

# 举例:
# 所有用户限制在主目录下,chroot_list 中的用户不受限制:
# [chroot_local_user=YES] & [chroot_list_enable=YES]
# 所有用户限制在主目录下,不启用 chroot_list:
# [chroot_local_user=YES] & [chroot_list_enable=NO]
# 所有用户不限制在主目录下,chroot_list 中的用户受限制:
# [chroot_local_user=NO] & [chroot_list_enable=YES]

# 指定用户登录后的ftp主目录。
local_root=/usr/share/nginx/www/

# 是否允许递归查询,大型站点的FTP服务器启用此项可以方便远程用户查询。
ls_recurse_enable=YES

# 如果设置为YES,则vsftpd将以独立模式运行,由vsftpd自己监听和处理IPV4连接请求。
listen=YES

# 设定是否支持IPV6
#listen_ipv6=YES

# 设置PAM外挂模块提供的认证服务所使用的配置文件名;
# 即/etc/pam.d/vsftpd文件;
# 此文件中file=/etc/vsftpd/ftpusers字段,
# 说明了PAM模块能抵挡的帐号内容来自文件/etc/vsftpd/ftpusers中。
pam_service_name=vsftpd

# 若此项设为YES,ftpusers 和 user_list 文件中的用户都允许登录FTP服务器;
# 若此项设为NO,ftpusers 中的用户禁止登录,user_list 中的用户允许登录;
userlist_enable=YES

# 仅当 userlist_enable=YES 时,userlist_deny 设置才有效。
# 若此项为YES,则 user_list 文件中的用户将不允许登录FTP服务器,
# 甚至连输入密码提示信息都没有,直接被FTP服务器拒绝。
#userlist_deny=YES

# 举例:
# ftpusers 中的用户禁止登录,user_list 中的用户无法登录(甚至连输入密码提示信息都没有,直接被FTP服务器拒绝)
# [userlist_enable=YES] & [userlist_deny=YES]
# ftpusers 中的用户禁止登录,user_list 中的用户可以登录
# [userlist_enable=YES] & [userlist_deny=NO]

# 表明服务器使用tcp_wrappers作为主机访问控制方式;
# tcp_wrappers可以实现linux系统中网络服务的基于主机地址的访问控制;
# 在/etc目录中的hosts.allow和hosts.deny两个文件用于设置tcp_wrappers的访问控制;
# 前者设置允许访问记录,后者设置拒绝访问记录。
# 例如想限制某些主机对FTP服务器192.168.57.2的匿名访问,
# 编缉/etc/hosts.allow文件,
# 如在下面增加两行命令:vsftpd:192.168.57.1:DENY 和vsftpd:192.168.57.9:DENY,
# 表明限制IP为192.168.57.1/192.168.57.9主机访问IP为192.168.57.2的FTP服务器,
# 此时FTP服务器虽可以PING通,但无法连接。
tcp_wrappers=YES

为了安全起见,我们不考虑使用 root 作为 ftp 帐号,新建一个专门用来 ftp 操作的帐号,操作步骤如下:

# 新建一个名为 ftper 的本地帐号,禁止登陆 shell,且不为其创建登录目录
useradd -M -s /sbin/nologin ftper
# 为建好的 ftper 帐号设置密码
passwd ftper
# 指定 ftper 的 ftp 登录主目录,要和配置文件里的 local_root= 结果保持一致
usermod -d /usr/share/nginx/www ftper
# 将 ftp 登录主目录的基本组和附加组为 ftper
chown -R ftper:ftper /usr/share/nginx/html
# 将 ftper 用户追加到 root 组
usermod -a -G root ftper

以上操作完成后,重启 ftp 即可生效。

然而,实际使用中也会遇到以下问题:

如果提示500 OOPS: vsftpd: refusing to run with writable root inside chroot ()

就意味着指定的登录主目录权限有问题,解决办法是,在配置文件里加入allow_writeable_chroot=YES

或者通过执行终端命令chmod a-w /home/youersite来取消写权限。

如果提示425 Security: Bad IP connecting

说明FTP客户端软件连接VSftpd服务报此错误,可能是在连接中变换了IP地址。

# 使用 vi 编辑配置文件 
vi /etc/vsftpd/vsftpd.conf
# 在配置文件中添加:
pasv_promiscuous=YES
# 保存退出后重启 vsftpd 服务
service vsftpd restart

FTP 分为两类,PORT FTP 和 PASV FTP,PORT FTP是一般形式的FTP。这两种FTP在建立控制连接时操作是一样的,都是由客户端首先和FTP服务器的控制端口(默认值为21)建立控制链接,并通过此链接进行传输操作指令。它们的区别在于使用数据传输端口(ftp- data)的方式。PORT FTP由FTP服务器指定数据传输所使用的端口,默认值为20。PASV FTP由FTP客户端决定数据传输的端口。 PASV FTP这种做法,主要是考虑到存在防火墙的环境下,由客户端与服务器进行沟通(客户端向服务器发出数据传输请求中包含了数据传输端口),决定两者之间的数据传输端口更为方便一些。

如果提示553 Could not create file,表现为可以通过服务器本地用户器登录到 ftp,可以查看到 ftp 上的各种路径及文件,但就是不能上传:

出现这种情况,如果不是目录权限的问题的话,可能就是 SELinux 的问题。

在终端执行以下命令来解决问题:

# 查看 SELinux 设置
getsebool -a | grep ftp
# 得到以下结果输出
allow_ftpd_anon_write --> off
allow_ftpd_full_access --> off
allow_ftpd_use_cifs --> off
allow_ftpd_use_nfs --> off
ftp_home_dir --> off
ftpd_connect_db --> off
ftpd_use_fusefs --> off
ftpd_use_passive_mode --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
tftp_use_cifs --> off
tftp_use_nfs --> off
# 需要把 allow_ftpd_full_access 的结果设置为 on
setsebool allow_ftpd_full_access on

改好后重新查看 SELinux 的设置,确认 allow_ftpd_full_access 的结果为 on 后,就可以通过 ftp 在指定目录上传文件了。

其实也可以直接关闭 SELinux。它为 Linux 提供安全强化同时,也让 Linux 服务安装变得更复杂。如果无法正确的为某项服务配置好 SELinux,那么它将很可能导致某项服务无法正常的运行。所以对于 Linux 初学者来说,也可以考虑完全关闭 SELinux:

临时关闭或开启 SELinux,可以使用下面的命令:

# 设置 SELinux 成为 permissive 模式(关闭SELinux)
setenforce 0
# 设置 SELinux 成为 enforcing 模式(开启SELinux)
setenforce 1

也可以通过vi /etc/selinux/config的指令来修改 SELinux 的配置文件,来永久关闭 SELinux:

# 在原配置里用井号注释掉下面两项
#SELINUX=enforcing
#SELINUXTYPE=targeted
# 然后增加下面这条即可
SELINUX=disabled

保存退出后,重启系统,然后 SELinux 就彻底关闭了。

附录

在终端执行 ftp 连接的命令说明:

ftp> ascii  # 设定以ASCII方式传送文件(缺省值) 
ftp> bell   # 每完成一次文件传送,报警提示. 
ftp> binary # 设定以二进制方式传送文件. 
ftp> case # 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母. 
ftp> cd     # 同UNIX的CD命令. 
ftp> cdup   # 返回上一级目录. 
ftp> mkdir directory-name   # 在远端主机中建立目录. 
ftp> chmod  # 改变远端主机的文件权限. 
ftp> pwd  # 列出当前远端主机目录. 
ftp> close  # 终止远端的FTP进程,返回到FTP命令状态, 所有的宏定义都被删除. 
ftp> delete # 删除远端主机中的文件. 
ftp> mdelete [remote-files] # 删除一批文件. 
ftp> dir [remote-directory] [local-file] # 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件. 
ftp> help [command] # 输出命令的解释. 
ftp> lcd # 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录. 
ftp> ls [remote-directory] [local-file] # 同DIR. 
ftp> macdef                 # 定义宏命令. 
ftp> open host [port] # 重新建立一个新的连接. 
ftp> prompt           # 交互提示模式. 
ftp> rename [from] [to]     # 改变远端主机中的文件名. 
ftp> rmdir directory-name   # 删除远端主机中的目录. 

ftp> status   # 显示当前FTP的状态. 
ftp> system   # 显示远端主机系统类型. 
ftp> user user-name [password] [account] # 重新以别的用户名登录远端主机. 
ftp> ? [command] # 同HELP. [command]指定需要帮助的命令名称。如果没有指定 command,ftp 将显示全部命令的列表。
ftp> ! # 从 ftp 子系统退出到外壳。 

关闭 ftp 连接的命令如下任一:

ftp> bye
ftp> exit
ftp> quit

下载文件:

ftp> get readme.txt # 下载 readme.txt 文件
ftp> mget *.txt     # 下载 
ftp> recv remote-file [local-file] # 同 get

上传文件:

ftp> put /path/readme.txt # 上传 readme.txt 文件
ftp> mput *.txt           # 可以上传多个文件
ftp> send local-file [remote-file] # 同 put 

状态码

230 - 登录成功
200 - 命令执行成功
150 - 文件状态正常,开启数据连接端口
250 - 目录切换操作完成
226 - 关闭数据连接端口,请求的文件操作成功
上一篇 下一篇

 

© 2017 老柴的宅. Powered by Chaishiwei.com. 鄂ICP备11006811号