企业网络基础服务-文件服务-FTP

企业网络基础服务-文件服务-FTP

Scroll Down

一、FTP服务

ftp1.png

网络诞生最初的动因就是去中心化和资源共享,文件是初期最主要的资源共享形式,把文件存放在集中的位置供大家访问。今天的互联网是由数以亿计的个人PC、工作站、服务器、小型机、大型机等具有不同型号、不同架构的物理设备所组成,而且还有不同的操作系统。那么如何在如此复杂的设备之间解决文件传输问题呢?

FTP(File transfer protocol,文件传输协议)用于局域网或者公网的文件共享。早期互联网的文件分享并没有考虑到安全问题,所以使用的是明文传输,使用TCP协议。特点就是使用简单、兼容性好、基于C/S架构。

二、FTP原理

FTP服务器是按照FTP协议在互联网上提供文件存储和访问服务的主机,C端则是向FTP服务器发送连接请求,以建立数据传输链路的主机。FTP服务端口和工作模式都有两个:

ftp2.png

1、工作模式

1)主动模式

主动模式(port)由客户端确定数据端口

ftp3.png

  1. C端端口N首先和FTP服务器的TCP 21建立连接(即命令通道建立)
  2. 当C端想要接收数据时,通过命令通道发送命令(port N+1,表示C端允许S端回连数据端口N+1传输数据)
  3. S端传输数据前,先和C端的N+1端口连接,然后通过20端口传输数据至C端N+1端口
vsftpd配置:

开启主动模式:pasv_enable=no

主动模式缺点就是FTP企图与C端的高位随机端口建立连接,这个高位端口可能会被C端防火墙阻塞

2)被动模式

被动模式(pasv)是由FTP服务器确定数据端口:C端主动向S发起数据连接

ftp4.png

  1. C端端口N连接到S端的21/tcp
  2. C端想要接收数据,通过命令通道发送命令(pasv,表示被动模式),S端接收命令开启端口P
  3. S端通过命令通道发送命令(port P,表示连接P端口)
  4. C端使用N+1端口连接S端P端口,进行数据传输
注意:
  • 如果FTP服务器前存在防火墙,那么就必须放行以下会话或者端口:
    C端高端口(>1024端口)N主动连接到S端21端口;所以S端防火墙需要放开21/tcp
  • C端高端口(>1024端口)N+1主动连接到S端高端口;所以S端防火墙需要放开ftp配置文件中的高端口范围
vsftpd配置:
  • 开启被动模式:pasv_enable=YES
  • 数据连接的最大端口和最小端口,其中0表示任意端口:
    pasv_min_port=30000
    pasv_max_port=30099

被动模式缺点与改进:C端要与FTP建立两个连接,其中一个要和高位端口连接,可能被S端防火墙阻塞。如果FTP需要和更多的C端建立连接,那么就必须支持pasv,为了安全和避免被防火墙阻塞,需要一个有限的端口范围来减少服务器高位端口的暴露,这样不在这个范围的任何端口会被服务器的防火墙阻塞(防火墙上需要放开相应端口),尽管没有消除对FTP的威胁,但是减少了很多危险。

2、传输类型

ftp5.png

3、企业部署FTP服务注意事项

企业通常考虑安全性方面,会将FTP服务器放置在独立于企业防火墙之外/DMZ区,采取只读挂载存储,这样C端只能读取和下载文件,不能上传文件。这就避免了黑客将文件上传至FTP服务器,导致其他C端下载了恶意文件。同时企业FTP服务器采用被动模式,可以使得更多的客户端连接到FTP。

三、vsftpd

vsftpd(very secure ftp deamon,非常安全的FTP守护进程)是一款灵活、安全、开源的FTP服务程序。特点是具有高安全性、高传输速度、支持虚拟用户认证。vsftpd的服务端口在21/tcp。

1、账号&用户主目录

vsftpd存在三种用户,分别是匿名用户、本地用户、虚拟用户。匿名用户是在安装完vsftpd后自动在文件系统中创建名为ftp的FTP账号,该账号没有shell登录权限。本地用户是指存在于本地文件系统中/etc/passwd和/etc/shadow这两个文件中的用户。虚拟用户是指在FTP服务器上拥有账号,但是该账号只能用于文件传输的用户,该用户需要映射到本地用户。

ftp6.png

匿名用户ftp默认主目录是/srv/ftp;本地用户默认主目录是自己的家目录;虚拟用户默认主目录也是自己的家目录。为了安全性,vsftpd的chroot机制默认不允许主目录有w权限(可修改),否则无法登录。但是这样就算登录到FTP服务器也不能执行操作,那么就需要在主目录下创建一个属组和属主都是登录用户的可写目录。

用户在登录FTP服务器后默认是可以浏览和访问主目录上一级或多级目录的,为了安全起见,vsftpd设计了chroot。chroot即牢笼机制,启用该机制,那么chroot只能访问指定目录而不能越权访问其他目录。

ftp7.png

2、登录认证模式

vsftpd允许用户以三种认证模式登录到FTP服务器:

ftp8.png

3、配置文件参数解析

vsftpd的配置文件是/etc/vsftpd.conf:

端口相关
listen= {YES|NO}       #是否以独立运行的方式监听服务
listen_address=IP地址	 #设置要监听的IP地址
listen_port=21	     #设置FTP服务的监听端口

工作模式
pasv_enable= YES/NO  #被动模式/主动模式
pasv_min_port=30000   #被动模式数据端口最小端口号
pasv_max_port=30099   #被动模式数据端口最大端口号
pasv_address=x.x.x.x #被动模式返回给客户端IP地址,一般用于服务器内网穿透时用,地址填写服务器外网IP

登录模式
1)匿名模式
anonymous_enable={YES|NO} #是否允许匿名用户访问
anon_root=/srv/ftp  #主目录
anon_upload_enable={YES|NO}  #是否允许上传文件
anon_world_readable_only={YES|NO}  #是否允许下载可读(下载到本机可读)
anon_mkdir_write_enable={YES|NO}   #是否允许创建目录(前提需要write_enable=YES)
anon_other_write_enable={YES|NO}   #是否开放其他写入权限(重命名、删除等操作)
anon_umask=022   #上传文件的umask值,比如创建一个权限为666的文件,文件的实际权限为666-022=644
anon_max_rate=0   #最大传输速率(字节/秒),0为不限制
匿名模式只设置和使用默认的ftp用户
2)本地模式
local_enable={YES|NO}  #是否允许本地用户访问
local_root=/var/ftp
local_umask=022 
local_max_rate=0	本地用户最大传输速率(字节/秒)
设置不允许哪些本地用户登录:
userlist_enable={YES|NO}   #是否启用控制用户登录的列表文件,默认/etc/vsftpd.user_list
userlist_deny={YES|NO}	 #是否拒绝userlist指定的列表文件中存在的用户登录FTP

用户主目录&chroot
1)主目录设置&权限
前面说到vsftpd为了安全,默认chroot机制不允许主目录可写,那么怎么使得用户登录上来后能够下载和上传文件呢?以本地用户epiol为例,为该用户创建根目录:
sudo useradd epiol -s /sbin/nologin
sudo passwd epiol
sudo mkdir /home/epiol && chmod -w /home/epiol
sudo chown root:epiol /home/epiol && mkdir /home/epiol/upload
sudo chown epiol:epiol /home/epiol/upload && chmod 777 /home/epiol/upload
sudo vim /etc/vsftpd.conf && local_root=/home/epiol
2)chroot
chroot_local_user=YES  #是否锁死所有本地用户在主目录内,无法回溯
chroot_list_enable=YES  #是否开启锁死特例
chroot_list_file=/etc/vsftpd.chroot_list  #锁死特例文件指定,默认该文件不存在需要创建
allow_writeable_chroot=YES  #是否允许主目录可写登录

文件或目录操作权限(针对所有登录模式下的所有用户)
write_enable=YES	 #允许登录用户对FTP服务器文件具有写权限
更多全局操作
dirmessage_enable = YES  #激活目录欢迎信息功能(默认开启)
xferlog_enable = YES      #开启FTP日志
xferlog_file=/var/log/vsftpd.log  #存放FTP日志的目录
idle_session_timeout=600       #会话超时时长
hide_ids=YES   #显示属主/属组名   
#最大客户端连接数,0为不限制, 同一IP地址的最大连接数,0为不限制
max_clients=0
max_per_ip=0
ftpd_banner= “Welcom”  #设置banner信息,登录时自动显示	
ls_recurse_enable=NO #禁止用户登录FTP后使用ls -R,该命令会对服务器性能造成巨大影响
tcp_wrappers=YES  #设置支持TCP wrappers

四、FTP最佳实践

1、匿名开放模式FTP配置

该模式适合公开分享文件,我们需要做的就是开放匿名用户上传、下载文件的权限,以及让匿名用户创建、删除、更名文件的权限,vsftpd默认禁用匿名开放模式。不建议设置为匿名开放模式!

1st. 修改主配置文件/etc/vsftpd.conf有关匿名开放模式的参数:

anonymous_enable=YES  #开启匿名用户模式
local_enable=NO        #关闭本地用户模式
anon_upload_enable=YES 
anon_umask=022  
anon_mkdir_write_enable=YES 
anon_other_write_enable=YES
write_enable=YES

pasv_enable= YES 
pasv_min_port=30000   
pasv_max_port=30999 

2nd. 重启服务:sudo systemctl restart vsftpd.service
3rd. 开机自启:sudo systemctl enable vsftpd
4th. 防火墙配置:sudo firewall-cmd --add-port=21/tcp --permanent && sudo firewall-cmd --add-port=30000-30999/tcp --permanent && sudo firewall-cmd --reload

5th. 客户端登录

在匿名开放认证模式下,其账户统一为ftp,密码为空。并且连接到FTP服务器后默认访问的是/srv/ftp目录。但是默认只有root才对/srv/ftp目录有w权限。就算我们对配置文件修改有w权限,但是也没有任何用:

ftp9.png

ftp10.png

使匿名用户可以上传文件,在/srv/ftp目录下新建一个目录,给这个新建的目录允许上传文件的权限:

  1. sudo chown ftp:ftp /srv/ftp/upload/
  2. sudo chmod 777 /srv/ftp/upload/
  3. sudo chown root:ftp /srv/ftp

ftp11.png

ftp12.png

2、本地用户模式FTP配置

本地用户模式特点就是默认不能上传只能下载可回溯到根目录(可看到整个服务器的目录树结构,造成严重的安全隐患),出于使用和安全性考虑,需要让本地用户登录后能够上传、不可回溯到根目录!

1st. 修改主配置文件/etc/vsftpd.conf有关本地用户模式的参数:

anonymous_enable=NO  #关闭匿名用户模式
local_enable=YES        #开启本地用户模式
local_umask=022        # 本地用户模式创建文件的umask值

#userlist_enable=YES     
#userlist_deny=YES   #默认禁止登录的用户文件在/etc/vsftpd.user_list中
#userlist_file=/etc/vsftpd.user_list
chroot_local_user=YES  
chroot_list_enable=YES    
chroot_list_file=/etc/vsftpd.chroot_list   
write_enable=YES      

pasv_enable= YES
pasv_min_port=30000   
pasv_max_port=30999 
vsftpd.user_list和vsftpd.chroot_list必须创建!

vsftpd为了让FTP更安全,默认是禁止root用户登录的

2nd. 重启服务
3rd. 开机自启
4th. 防火墙配置(端口开放如匿名模式)
5th. 客户端登录

创建一个新用户epiola,并创建主目录/home/epiola,主目录权限不可写(因为chroot默认要求主目录不可写),属组属主都是epiola。主目录下存在upload目录,该目录可写,属组属主都是epiola。由于设置了chroot那么该用户登录后无法回溯:

  1. 增加新用户:useradd epiola -s /sbin/nologin
  2. passwd epiola
  3. 创建主目录并收回w权限:sudo mkdir /home/epiola && chmod -w epiola
  4. 更改属组:sudo chown epiola:epiola /home/epiola
  5. sudo mkdir /home/epiola/upload
  6. sudo chmod 777 /home/epiola/upload && chown epiola:epiola /home/epiola/upload
  7. sudo vim /etc/vsftpd.conf && local_root=/home/epiola
  8. sudo systemctl restart vsftpd.service
  9. sudo systemctl status vsftpd.service

ftp13.png

3、虚拟用户模式FTP配置

虚拟用户是指在FTP服务器上拥有账号,并且账号只能用于文件传输服务的用户,也称为Guest用户。该类用户可以通过输入账号以及口令来进行授权登录,登录系统后根目录只能是指定的目录,拥有上传和下载权限,没有删除和重命名权限。

vsftpd的虚拟用户的账户和口令单独被存放在一个数据库,与系统本地用户(/etc/passwd、/etc/shadow)分开,大大增强了系统的安全性。vsftpd可以采用数据库文件存放账户和口令也可使用专门的数据库服务器(mysql)来存放。

数据库文件或者数据库服务器中存放的账户和口令独立于本地系统用户

vsftpd验证虚拟用户采用PAM方式,即使用guest用户来读取数据库文件或者数据库服务器完成验证,Guset用户可以被认为是映射虚拟用户。

ftp14.png

PAM:PAM登录认证模块是一种认证机制,不会直接使用系统用户,而是用自己的用户数据库,但是由于vsftpd必须要存取操作系统上的文件,所以离不开系统用户,那么就通过不直接登录,只是做映射,只要用自己的用户登录后和系统用户做映射就安全很多。,通过一个动态链接库和统一的API把系统提供的服务与认证方式分开,得系统管理员可以根据需求灵活调整服务程序的不同认证方式。

1)生成虚拟用户数据库文件

1st. 生成虚拟用户数据库文件

vim /etc/vuser.list
该文件内容格式为:

用户名A

密码A

用户名B

密码B

...

2nd. 生成虚拟用户数据库文件
db5.3_load -T -t hash -f vuser.list vuser.db

3rd. 删除原始明文数据库文件

sudo rm -rf vuser.list

4th. 查看虚拟用户数据库文件属性

file vuser.db

5th. 修改数据库文件权限(权限最小化原则)

chmod 600 vuser.db
如果没有db5.3_load命令,请先安装

2)创建认证文件

编辑虚拟用户所需要的PAM配置(文件位置为/etc/pam.d/vsftpd),加入以下两行内容:

auth     required   pam_userdb.so  db=/etc/vuser
account  required   pam_userdb.so  db=/etc/vuser
注意是vuser而不是vuser.db

3)指定虚拟用户的FTP根目录和权限

本地用户(即vuser)登录后的根目录(即/home/vuser),以及配置相应权限提高安全性:

useradd -d /home/vuser -s /sbin/nologin vuser && mkdir /home/vuser

chmod -w /home/vuser && chown vuser:vuser /home/vuser

4)修改主配置文件

anonymous_enable=NO
local_enable=YES #PAM必须为YES,因为需要映射本地用户,否则所有虚拟用户无法访问
local_umask=022 
write_enable=YES

chroot_local_user=YES #所有本地用户限制在自己的FTP根目录中
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list

guest_enable=YES             #开启虚拟用户模式
guest_username=vuser         #指定虚拟用户需要映射的本地用户
pam_service_name=/etc/pam.d/vsftpd      #指定虚拟用户存在的文件 
virtual_use_local_privs=YES  #设定虚拟用户的权限符合他们的宿主用户

pasv_enable= YES
pasv_min_port=30000   
pasv_max_port=30999 

5)重启服务并测试

创建vsftpd服务程序用于存储文件的根目录以及虚拟用户映射的系统本地用户。由于linux系统中的每一个文件都有属主、属组属性。例如使用虚拟账户“张三”新建了一个文件,但是系统中找不到账户“张三”,就会导致这个文件的权限出现错误。所以需要创建一个可以映射到虚拟用户的系统本地用户。

简单的说:让虚拟用户默认登录到与之有映射关系的系统本地用户的家目录中,虚拟用户创建的文件属性也都归属于该系统本地用户,从而避免了linux系统无法处理虚拟用户所创建的属性权限。

为了方便管理FTP服务器上的数据,可以把系统本地用户的家目录设置为/var目录,并且为了安全起见,我们将这个系统本地用户设置为不允许登录FTP服务器,这不会影响虚拟用户登录,而且还可以避免何可通过该系统本地用户进行登录。

4、客户端登录FTP

服务器支持客户端浏览器登录、终端登录、专用FTP客户端登录

ftp15.png

文件同步客户端:自动同步客户端某个目录下的文件到FTP服务器,ubuntu中有很多这种软件,比如simplebackup

五、FTP安全

FTP由于天生的缺陷,导致安全性非常差。所以如果有要求强安全性的场景,就需要用到FTPS(FTP over SSL)或者SFTP(基于SSH加密通道传输文件):

  • FTPS账号无需shell登录权限
  • SFTP账号需要shell登录权限,可设置禁止权限

1、FTPS

ftp16.png

信任证书指合法颁发机构颁发给公司或个人的证明,即拥有身份认证功能。自签名证书是指没有身份认证功能,但是加密效果不变的应用。
生成信任证书:

1st. 生成加密的密钥文件

openssl genrsa -des3 -out ftp.key 4096
这样就生成了加密的公私钥对,如果需要生成证书请求文件,就需要先临时解密成未加密的公私钥对文件

2nd. 解密加密的密钥文件

openssl rsa -in ftp.key -out ftp.key.insecure && mv ftp.key ftp.key.secure && mv ftp.key.insecure ftp.key

3rd. 生成证书请求文件(即csr文件)

openssl req -new -key ftp.key -out ftp.csr

4th. 将csr文件发送给证书颁发机构,机构会审核你的信息是否正确,然后颁发权威证书

如果不需要权威证书,那就生成自签名证书,继续下面步骤

5th. 生成自签名证书

openssl x509 -req -days 365 -in ftp.csr -signkey ftp.key -out ftp.pem

6th. 部署

sudo cp ftp.key /etc/ssl/private/
sudo cp ftp.pem /etc/ssl/certs/
生产环境建议由证书颁发机构签名生成证书

整合以上命令为一行命令:sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/vsftpd.key -out /etc/ssl/certs/vsftpd.pem

  • x509:x.509证书数据管理
  • days:定义证书有效日期
  • newkey:指定证书密钥管理器
  • keyout:设置密钥存储文件
  • out:设置证书存储文件

7th. 修改vsftpd的主配置文件

必要选项
ssl_enable=YES  #激活并使用SSL
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem  #证书(公钥)
rsa_priviate_key_file=/etc/ssl/private/ssl-cert-snakeoil.key  #私钥

可选选项
debug_ssl=YES  #开启后openssl连接诊断会被记录到vsftpd日志文件
ssl_ciphers=HIGH  #选择vsftpd允许用于加密ssl连接的ssl算法,有效限制部分尝试发现使用存在缺陷的特定算法的攻击者
require_ssl_reuse=NO  #不要求所有ssl数据连接都会重用ssl会话,有利于保护命令通道的主密码
ssl_tlsv1=YES
ssl_sslv2=NO #V2版本安全性不好
ssl_sslv3=NO #V3版本安全性不好

ftp17.png

2、SFTP

占位

六、FTP问题汇总

1、无法连接到服务器
防火墙未开通21/tcp,三次握手不成功,命令通道无法建立
2、文件传输失败
被动传输模式下,防火墙未开通高端口30000-30099/tcp,命令通道成功建立,但是数据通道无法建立,无法传输数据文件
3、503 login incorrect
FTP服务器的文件系统中的/etc/shells不存在/sbin/nologin。查看登录shell(cat /etc/shells),如果没有/sbin/nologin,则添加到/etc/shells中即可

FTP被动模式数据包 提取码1234