Vsftpd搭建SSL/TLS安全FTP
背景故事
好吧,大D的VPS已经无备份裸奔多日,一直在寻找靠谱的解决方案,无奈DropBox空间太小,百度云,360云又不开放API。被迅雷收购了的金山快盘虽然有SDK,也有一位大牛写出了Linux下的工具,但是大D写好了shell,测试了一周发现经常连接不上,上传不能。
还寻找了使用Amazon、OneDrive、阿里云、七牛云等等等等等。。。
最后还是买了一台年付VPS用来直接备份吧。
同时,由于FTP普通模式连接会将用户名和密码明文传输,遂决定搭建SSL/TLS安全FTP。
写这篇文章的时候,大D已经在服务器上搭建完毕了。装个虚拟机来写这篇文章吧,顺路可以学习一下Linux下的抓包。
实验环境
宿主机:DELL N5010-358(Intel Core i3-380M+8G)
虚拟化软件:Vmware Workstation 12
虚拟机配置:1核+1G+20G
虚拟机IP分配为:192.168.159.136
安装CentOS 6.7 Minimal
虚拟机配置
CentOS 6.7 Minimal不带Vmware的网卡配置,所以首先配置网卡。
1 |
vi /etc/sysconfig/network-scripts/ifcfg-eth0 |
虚拟机网卡模式NAT模式,所以开启onboot和dhcp即可。
1 2 3 4 5 6 7 8 |
DEVICE=eth0 HWADDR=00:0C:29:A9:12:65 TYPE=Ethernet UUID=fd78e0b1-073c-4698-8fe1-aef24e7cbee4 ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=dhcp |
然后重启网络服务。
1 2 3 4 5 6 7 8 |
[root@localhost ~]# service network restart Shutting down interface eth0: [ OK ] Shutting down loopback interface: [ OK ] Bringing up loopback interface: [ OK ] Bringing up interface eth0: Determining IP information for eth0... done. [ OK ] |
安装Vsftpd
这一步就很简单了。直接安装就是了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
[root@localhost ~]# yum install vsftpd Loaded plugins: fastestmirror Setting up Install Process base | 3.7 kB 00:00 base/primary_db | 3.6 MB 00:19 extras | 3.4 kB 00:00 extras/primary_db | 30 kB 00:00 updates | 3.4 kB 00:00 updates/primary_db | 3.1 MB 00:06 Resolving Dependencies --> Running transaction check ---> Package vsftpd.i686 0:2.2.2-14.el6 will be installed --> Finished Dependency Resolution Dependencies Resolved =================================================================================================== Package Arch Version Repository Size =================================================================================================== Installing: vsftpd i686 2.2.2-14.el6 base 157 k Transaction Summary =================================================================================================== Install 1 Package(s) Total download size: 157 k Installed size: 344 k Is this ok [y/N]: y Downloading Packages: vsftpd-2.2.2-14.el6.i686.rpm | 157 kB 00:00 warning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 Importing GPG key 0xC105B9DE: Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org> Package: centos-release-6-7.el6.centos.12.3.i686 (@anaconda-CentOS-201508042139.i386/6.7) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 Is this ok [y/N]: y Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : vsftpd-2.2.2-14.el6.i686 1/1 Verifying : vsftpd-2.2.2-14.el6.i686 1/1 Installed: vsftpd.i686 0:2.2.2-14.el6 Complete! |
新建一个用来连接ftp的用户,并设置不能登录ssh。
1 2 3 4 5 6 7 8 9 10 11 |
#新建FTP用户组 [root@localhost ~]# groupadd ftpgroup #新建用户test,将其添加到ftpgroup组,指定用户工作目录为/home/ftp,禁止该账户登录系统 [root@localhost ~]# useradd test -g ftpgroup -d /home/ftp -s /sbin/nologin #为test用户添加密码 [root@localhost ~]# passwd test Changing password for user test. New password: Retype new password: passwd: all authentication tokens updated successfully. |
配置一下配置文件。
1 |
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf |
需要配置的地方不是很多,首先要关闭匿名登录。
1 2 3 4 5 |
# Allow anonymous FTP? (Beware - allowed by default if you comment this out). anonymous_enable=NO #指定被动模式端口 pasv_min_port=2000 pasv_max_port=2100 |
最后将Vsftpd启动,并添加到开机启动项。
1 2 3 |
[root@localhost ~]# chkconfig vsftpd on [root@localhost ~]# service vsftpd start Starting vsftpd for vsftpd: [ OK ] |
添加防火墙规则。
1 2 3 4 5 6 7 8 |
[root@backdadclab ~]# vim /etc/sysconfig/iptables #添加主动模式规则 -A INPUT -p tcp -m state --state NEW -m tcp --dport 20 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT #添加被动模式规则 -A INPUT -p tcp -m state --state NEW -m tcp --dport 2000:2100 -j ACCEPT #重启iptables [root@backdadclab ~]# service iptables restart |
关闭SElinux
1 2 3 4 |
#关闭SELinux /usr/sbin/setenforce 0 #加入开机启动 echo "/usr/sbin/setenforce 0" >> /etc/rc.local |
这时可以使用Filezilla等FTP软件切换到普通FTP模式来连接一下,确认Vsftpd正常工作。
验证普通FTP模式下明文传输
首先安装一下抓包工具。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
[root@localhost home]# yum install tcpdump wireshark Loaded plugins: fastestmirror Setting up Install Process Loading mirror speeds from cached hostfile * base: mirrors.pubyun.com * extras: mirrors.neusoft.edu.cn * updates: mirrors.neusoft.edu.cn Package 14:tcpdump-4.0.0-5.20090921gitdf3cb4.2.el6.i686 already installed and latest version Resolving Dependencies --> Running transaction check ---> Package wireshark.i686 0:1.8.10-17.el6 will be installed --> Processing Dependency: libsmi.so.2 for package: wireshark-1.8.10-17.el6.i686 --> Running transaction check ---> Package libsmi.i686 0:0.4.8-4.el6 will be installed --> Processing Dependency: wget for package: libsmi-0.4.8-4.el6.i686 --> Running transaction check ---> Package wget.i686 0:1.12-5.el6_6.1 will be installed --> Finished Dependency Resolution Dependencies Resolved =================================================================================================== Package Arch Version Repository Size =================================================================================================== Installing: wireshark i686 1.8.10-17.el6 base 10 M Installing for dependencies: libsmi i686 0.4.8-4.el6 base 2.4 M wget i686 1.12-5.el6_6.1 base 483 k Transaction Summary =================================================================================================== Install 3 Package(s) Total download size: 13 M Installed size: 66 M Is this ok [y/N]: y Downloading Packages: (1/3): libsmi-0.4.8-4.el6.i686.rpm | 2.4 MB 00:04 (2/3): wget-1.12-5.el6_6.1.i686.rpm | 483 kB 00:00 (3/3): wireshark-1.8.10-17.el6.i686.rpm | 10 MB 00:23 --------------------------------------------------------------------------------------------------- Total 453 kB/s | 13 MB 00:29 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : wget-1.12-5.el6_6.1.i686 1/3 Installing : libsmi-0.4.8-4.el6.i686 2/3 Installing : wireshark-1.8.10-17.el6.i686 3/3 Verifying : wireshark-1.8.10-17.el6.i686 1/3 Verifying : libsmi-0.4.8-4.el6.i686 2/3 Verifying : wget-1.12-5.el6_6.1.i686 3/3 Installed: wireshark.i686 0:1.8.10-17.el6 Dependency Installed: libsmi.i686 0:0.4.8-4.el6 wget.i686 0:1.12-5.el6_6.1 Complete! |
安装完毕之后我们来抓取一下主机192.168.159.136端口21上的数据包,这时我们将FTP软件的工作模式暂时改成主动模式方便抓包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[root@localhost home]# tcpdump -i eth0 port 21 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 23:25:32.574743 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [S], seq 975941125, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0 23:25:32.574846 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [S.], seq 709574101, ack 975941126, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0 23:25:32.575910 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [.], ack 1, win 256, length 0 23:25:32.584614 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 1:21, ack 1, win 229, length 20 23:25:32.585480 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 1:12, ack 21, win 256, length 11 23:25:32.585561 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [.], ack 12, win 229, length 0 23:25:32.585923 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 21:55, ack 12, win 229, length 34 23:25:32.586313 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 12:32, ack 55, win 256, length 20 23:25:32.626553 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [.], ack 32, win 229, length 0 23:25:32.773752 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 55:78, ack 32, win 229, length 23 23:25:32.774545 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 32:46, ack 78, win 256, length 14 23:25:32.774576 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [.], ack 46, win 229, length 0 23:25:32.774817 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 78:104, ack 46, win 229, length 26 23:25:32.793391 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 46:51, ack 104, win 256, length 5 23:25:32.793629 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 104:121, ack 51, win 229, length 17 23:25:32.794517 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 51:59, ack 121, win 256, length 8 23:25:32.794754 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 121:152, ack 59, win 229, length 31 23:25:32.796935 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 59:86, ack 152, win 256, length 27 23:25:32.797377 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 152:203, ack 86, win 229, length 51 23:25:32.798095 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [P.], seq 86:92, ack 203, win 255, length 6 23:25:32.802967 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 203:242, ack 92, win 229, length 39 23:25:32.805447 IP 192.168.159.136.ftp > 192.168.159.1.63287: Flags [P.], seq 242:266, ack 92, win 229, length 24 23:25:32.806696 IP 192.168.159.1.63287 > 192.168.159.136.ftp: Flags [.], ack 266, win 255, length 0 |
抓到一堆包,但是这样的数据是看不出来的呀,于是将数据保存到/home/ftp.pcap,通过FTP下载回Windows,使用Wireshark分析一下包。
可以看到用户名和密码了。
配置SSL/TLS安全FTP
终于来到重点了。
首先我们了解一下FTPS的工作方式。
FTPS工作方式
为了提高整体安全性,我们有两种选择,一种是FTPS,相当于加密版的FTP。第二种是SFTP,也就是通过SSH文件传输协议加密从客户机到服务器的FTP连接。
SSL/TLS协议工作在传输层(TCP/IP)之上,应用层之下。因此它可以很容易的在诸如HTTP、POP3、IMAP4、SMTP和FTP等应用层协议上来实现。
SSL安全扩展至少有两种不同的初始化方法,一种是显式安全,另一种是隐式安全。
显示安全:为了建立SSL连接,显式安全要求FTP客户端在和FTP服务器建立连接之后发送一个特定命令,也就是AUTH SSL或者AUTH TLS,显式的告诉FTP服务器初始化对应的安全连接。这时默认的FTP端口就是21端口。
隐式安全:当FTP客户端连接到FTP时,隐式安全将会自动和SSL连接并自动建立安全。
配置SSL加密FTP数据传输
首先我们来查看Vsftpd是否支持SSL。
1 2 3 |
[root@localhost ~]# ldd `which vsftpd` | grep libssl libssl.so.10 => /usr/lib/libssl.so.10 (0x008cd000) |
如果输出有 libssl.so.10 => /usr/lib/libssl.so.10 (0x008cd000) 类似的一行,那么Vsftpd就是支持SSL的。
接下来我们使用Openssl生成证书。
生成顶级CA的公钥和私钥文件,有效期10年(RSA 1024bits)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[root@localhost ~]# openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/vsftpd/vsftpd.pem -out /etc/vsftpd/vsftpd.pem Generating a 1024 bit RSA private key ...............................................................++++++ ...........++++++ writing new private key to '/etc/vsftpd/vsftpd.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]: #国家 State or Province Name (full name) []: #省份 Locality Name (eg, city) [Default City]: #城市 Organization Name (eg, company) [Default Company Ltd]: #单位名称 Organizational Unit Name (eg, section) []: #部门 Common Name (eg, your name or your server's hostname) []:192.168.159.136 #域名/主机名/IP地址 Email Address []: #邮件地址 |
需要注意的是,域名/主机名/IP地址这块需要填写你主机的真实信息。
编辑Vsftpd的配置文件,添加SSL支持。
1 2 |
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf |
添加如下内容。
1 2 3 4 5 6 7 |
ssl_enable=YES #启用SSL支持 force_local_logins_ssl=YES #对本地用户登录启用ssl加密 force_local_data_ssl=YES #对本地用户数据传输启用ssl加密 rsa_cert_file=/etc/vsftpd/vsftpd.pem #RSA密钥文件保存位置 ssl_tlsv1=YES #启用TLS V1加密 ssl_ciphers=HIGH #启用高级加密方式,若不启用此项,会导致Filezilla报错 pam_service_name=vsftpd #不加这个linux下lftp无法连接 |
使用FileZilla连接时,按照如下进行配置。
配置完之后进行连接,输入密码,第一次连接时会提示你加载证书。如下:
由于大D的虚拟机没有调整系统时间,所以会显示尚未生效证书,这时点确定就可以进入FTP了。
Linux环境下可以使用curl或者lftp进行连接。
最后我们来验证一下加密是否还会明文传输用户名和密码。
换一种方式来抓包验证吧。
1 |
[root@localhost ~]# tshark -ni eth0 -R "tcp.dstport eq 21" |
抓到的数据包如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[root@localhost ~]# tshark -ni eth0 -R "tcp.dstport eq 21" Running as user "root" and group "root". This could be dangerous. Capturing on eth0 5.319639404 192.168.159.1 -> 192.168.159.136 TCP 60 64871 > 21 [FIN, ACK] Seq=1 Ack=1 Win=251 Len=0 5.320574528 192.168.159.1 -> 192.168.159.136 TCP 60 64871 > 21 [RST, ACK] Seq=2 Ack=11 Win=0 Len=0 5.327867834 192.168.159.1 -> 192.168.159.136 TCP 66 64887 > 21 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1 5.328559116 192.168.159.1 -> 192.168.159.136 TCP 60 64887 > 21 [ACK] Seq=1 Ack=1 Win=65536 Len=0 5.334886568 192.168.159.1 -> 192.168.159.136 FTP 64 Request: AUTH TLS 5.336815128 192.168.159.1 -> 192.168.159.136 FTP 274 Request: \026\003\001\000\327\001\000\000\323\003\003V\210\334\331S\a\t\210\356\31669\3075\215\003\240\230:\373{W*\322\311\330\244) 5.340513409 192.168.159.1 -> 192.168.159.136 FTP 66 Request: \026\003\003\000\a\v\000\000\003\000\000\000 5.340581057 192.168.159.1 -> 192.168.159.136 FTP 193 Request: \026\003\003\000\206\020\000\000\202\000\200v"\331\346\376\260\352\311\251\2206\210?\214\251OW\334#\263\342\247\364\323\v^Z\227"\340\344&\272bQ,\a\336!\227\351OC\212\0218\356\265\362\376\305\001e\313\272\364\021\271\313,\203\317:\256)\307\356t\206\370\365\266\360>\221.\241Q 5.340588739 192.168.159.1 -> 192.168.159.136 FTP 60 Request: \024\003\003\000\001\001 5.340595073 192.168.159.1 -> 192.168.159.136 FTP 99 Request: \026\003\003\000(\000\000\000\000\000\000\000\000\227\325\3546\vX 5.362956759 192.168.159.1 -> 192.168.159.136 FTP 94 Request: \027\003\003\000#\000\000\000\000\000\000\000\001\336\345\271\345\270\276"\326\246\230\237\337\271O{\357\357\373S 5.363844255 192.168.159.1 -> 192.168.159.136 FTP 103 Request: \027\003\003\000,\000\000\000\000\000\000\000\002?\023U\033\300\246\377\213\0348\325\020\352r\356\245\377i\255\221\257\227g\001\344.V\a\344\317\322s\272\220\246I 5.533292706 192.168.159.1 -> 192.168.159.136 FTP 97 Request: \027\003\003\000&\000\000\000\000\000\000\000\003\272y\002\306?b\244\234|\361\307h.)\311zR\332D6\260\v:8#\322\274\372^g 5.534274591 192.168.159.1 -> 192.168.159.136 FTP 91 Request: \027\003\003\000 \000\000\000\000\000\000\000\004\360\271\362\256+\004A(\275\366\364~\223 5.535663533 192.168.159.1 -> 192.168.159.136 FTP 91 Request: \027\003\003\000 \000\000\000\000\000\000\000\00505g_\f\354o\004Z,X->\031\244\206\026\200\354\315\340\017\224\241 5.551055684 192.168.159.1 -> 192.168.159.136 FTP 88 Request: \027\003\003\000\035\000\000\000\000\000\000\000\006I\371L\375\024k\255\300cJ\225\220B\341\270\263\247U\311\034\177 5.602988379 192.168.159.1 -> 192.168.159.136 TCP 60 64887 > 21 [ACK] Seq=673 Ack=1371 Win=64256 Len=0 |
可以看到在AUTH TLS开启加密之后,后面的数据包都是被加密过的了。保证了数据的安全。
已有 4 条评论
发表评论
电子邮件地址不会被公开。 必填项已标注。
Pingback: 利用树莓派搭建VPS异地备份系统 | 大D技研室 | 简单易懂的现代魔法|Build my world
感谢博主,完美解决了我的ftp问题!
百度云开放 API,但是速度太慢了。
就是因为速度慢,所以才不用。