FTP
FTP(File Transfer Protocol)文件传输协议,作为最早期的网络传输协议,他没有像HTTP协议那样仍然老当益壮,随着云存储等许多文件保存传输方案的出现,FTP已经慢慢退出历史舞台,但在内网仍然还有的公司会使用这样的传输协议,但是FTP的诟病也是很多,最重要的是很不安全(明文),所以我们来说说Linux下最流行的vsftpd(very secure ftp)。
用户分类
Real帐户
这类用户是指在FTP服务上拥有帐号。当这类用户登录FTP服务器的时候,其默认的主目录就是其帐号命名的目录。但是,其还可以变更到其他目录中去。如系统的主目录等等。
Guest用户(虚用户)
在FTP服务器中,我们往往会给不同的部门或者某个特定的用户设置一个帐户。但是,这个账户有个特点,就是其只能够访问自己的主目录。服务器通过这种方式来保障FTP服务上其他文件的安全性。这类帐户,在Vsftpd软件中就叫做Guest用户。拥有这类用户的帐户,只能够访问其主目录下的目录,而不得访问主目录以外的文件。
Anonymous(匿名)用户
这也是我们通常所说的匿名访问。这类用户是指在FTP服务器中没有指定帐户,但是其仍然可以进行匿名访问某些公开的资源。
在组建FTP服务器的时候,我们就需要根据用户的类型,对用户进行归类。默认情况下,Vsftpd服务器会把建立的所有帐户都归属为Real用户。但是,这往往不符合企业安全的需要。因为这类用户不仅可以访问自己的主目录,而且,还可以访问其他用户的目录。这就给其他用户所在的空间带来一定的安全隐患。所以,企业要根据实际情况,修改用户所在的类别。
支持模式
FTP支持两种模式:Standard (PORT方式,主动方式),Passive (PASV,被动方式)。
Port模式
FTP 客户端首先和服务器的TCP 21端口建立连接,用来发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。PORT命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口连接至客户端的指定端口发送数据。FTP server必须和客户端建立一个新的连接用来传送数据。
Passive模式
建立控制通道和Standard模式类似,但建立连接后发送Pasv命令。服务器收到Pasv命令后,打开一个临时端口(端口号大于1023小于65535)并且通知客户端在这个端口上传送数据的请求,客户端连接FTP服务器此端口,然后FTP服务器将通过这个端口传送数据。
很多防火墙在设置的时候都是不允许接受外部发起的连接的,所以许多位于防火墙后或内网的FTP服务器不支持PASV模式,因为客户端无法穿过防火墙打开FTP服务器的高端端口;而许多内网的客户端不能用PORT模式登陆FTP服务器,因为从服务器的TCP 20无法和内部网络的客户端建立一个新的连接,造成无法工作,但目前高级的防火墙都已经支持链接追踪功能,可以很好的解决这种问题。
vsftpd基本配置项
匿名用户:
1 | anonymous_enable=YES |
2 | anon_upload_enable=YES |
3 | 匿名用户的上传操作;生效以赖write_enable=YES |
4 | anon_mkdir_write_enable=YES |
5 | 匿名用户创建目录的权限 |
6 | anon_other_write_enable |
7 | 匿名用户的删除及重命名操作权限 |
本地用户:
1 | local_enable |
2 | 所有的非匿名的生效,都依赖于此指令 |
3 | local_umask=022 |
4 | 本地用户上传文件的权限掩码 |
目录消息:
1 | dirmessage_enable=YES |
2 | 用户第一次进入目录时,vsftpd会查找.messages文件,并将其内容显示给用户 |
3 | message_file指定文件路径,而不使用默认的.message |
数据传输日志:
1 | xferlog_enable |
2 | xferlog_std_format #建议不开启 |
3 | xferlog_file=/var/log/xferlog |
数据传输模式:
1 | connect_from_port_20: 是否启用port模式 |
修改匿名用户上传的用户用户组:
1 | chown_uploads: 是否修改上传上来的属主属组 |
2 | chown_username: 启动chown_uploads指令时,将文件属主修改为此指令指定的用户;默认为root |
3 | chown_upload_mode: 匿名用户上传文件的权限,默认600 |
设定会话超时时长:
1 | idle_session_timeout: 空闲会话超时时长 |
2 | connext_timeout: port模式下,连接超时时长 |
3 | data_connection_timeout: 数据传输的超时时长 |
命令连接的监听端口:
1 | listen: 默认21 |
设定连接及传输速率:
1 | local_max_rate: 本地用户的传输速率,单位是字节,默认为0,表示无限制 |
2 | anon_max_rate: 匿名用户的最大速率 |
3 | max_clients:最大并发连接数,默认2000,0表示无限制 |
4 | max_per_ip:每ip允许发起的最大连接数 |
5 | max_login_fails: 最大连接失败次数 |
禁锢本地用户:
1 | chroot_local_user: 禁锢所有本地用户 |
2 | 要求对家目录无写权限 |
3 | |
4 | chroot_list_enable |
5 | chroot_list_file |
6 | 禁锢指定用户于家目录 |
7 | |
8 | userlist_enable |
9 | 启用时,vsftpd将加载一个userlist_file指令指定的用户列表文件;此文件的用户是否能访问vsftpd服务取决于userlist_deny指令; |
10 | userlist_deny=YES: 表示此列表为黑名单 |
11 | userlist_deny=NO: 表示此列表为白名单 |
pam_myql虚用户认证
官网:http://pam-mysql.sourceforge.net/
开始编译:
1 | ~]#./configure --with-mysql=/usr/local/mysql --with-openssl --with-pam=/usr --with-pam-mods-dir=/lib64/security |
2 | ~]#make && make install |
3 | ~]#cd /lib64/security/ |
4 | ~]#ll pam_mysql.so #这就是我们需要的pam_mysql的库文件 |
创建虚用户
1 | MariaDB [vsftpd]> desc users; |
2 | +--------+----------+------+-----+---------+----------------+ |
3 | | Field | Type | Null | Key | Default | Extra | |
4 | +--------+----------+------+-----+---------+----------------+ |
5 | | id | int(11) | NO | PRI | NULL | auto_increment | |
6 | | name | char(30) | NO | | NULL | | |
7 | | passwd | char(48) | NO | | NULL | | |
8 | +--------+----------+------+-----+---------+----------------+ |
9 | 3 rows in set (0.00 sec) |
10 | |
11 | MariaDB [vsftpd]> insert into users (name,passwd) values ('jusene',password('jusene')); |
12 | Query OK, 1 row affected (0.02 sec) |
13 | |
14 | MariaDB [vsftpd]> insert into users (name,passwd) values ('tom',password('tom')); |
15 | Query OK, 1 row affected (0.00 sec) |
16 | |
17 | MariaDB [vsftpd]> select * from users; |
18 | +----+--------+-------------------------------------------+ |
19 | | id | name | passwd | |
20 | +----+--------+-------------------------------------------+ |
21 | | 1 | jusene | *F4FC8B2A0A53CB6EB68F6F87B760AE616E8E2A78 | |
22 | | 2 | tom | *71FF744436C7EA1B954F6276121DB5D2BF68FC07 | |
23 | +----+--------+-------------------------------------------+ |
24 | 2 rows in set (0.00 sec) |
我们可以在/etc/vsftpd/vsftpd.conf看见一个使用pam的选项pam_service_name
我们来看下这个pam是怎么配置的:
1 | ~]#cat /etc/pam.d/vsftpd |
2 | #%PAM-1.0 |
3 | session optional pam_keyinit.so force revoke |
4 | auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed |
5 | auth required pam_shells.so |
6 | auth include password-auth |
7 | account include password-auth |
8 | session required pam_loginuid.so |
9 | session include password-auth |
10 | |
11 | 根据这个pam我们也可以知道/etc/vsftpd/ftpusers这个文件里的用户为什么就无法访问了 |
12 | |
13 | 我们按照这个改下,具体后面的参数我们可以在编译源码包中的README中得知 |
14 | ~]#cat /etc/pam.d/vsftpd.mysql |
15 | auth required pam_mysql.so user=vsftpd passwd=vsftpd host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=passwd crypt=2 |
16 | account required pam_mysql.so user=vsftpd passwd=vsftpd host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=passwd crypt=2 |
ftp的工作模式是需要衍射到本地的一个账号,所以我们还需要一个本地账号来对应虚账号:
1 | ~]# useradd -s /sbin/nologin -d /ftpdata vuser |
配置vsftpd配置文件
1 | 只列出需要修改或添加的配置项 |
2 | ~]# cat /etc/vsftpd/vsftpd.conf |
3 | pam_service_name=vsftpd.mysql |
4 | guest_enable=YES |
5 | guest_username=vuser |
注意:虚账号的默认采用了chroot的jail模式,所以我们还得保证/ftpdata没有w权限,不然会报错而导致认证失败,这也是vsftpd对权限控制严格,所以才安全
1 | ~]# chown vuser.vuser /ftpdata |
2 | ~]# cd /ftpdata |
3 | ~]# mkdir {pub,upload} |
4 | ~]# chown vuser upload |
5 | ~]# chmod a-w /ftpdata |
但是这样我们会发现全部的虚账号都映射到一个本地账号上了(vuser),而我们需要怎么控制每个账户的上传下载的权限呢?
1 | ~]#cat /etc/vsftpd/vsftpd.conf |
2 | user_config_dir=/etc/vsftpd/vuser.conf.d |
3 | ~]#cd vuser.conf.d/ |
4 | ~]#ls |
5 | jusene tom |
6 | ~]#cat jusene |
7 | anon_upload_enable=YES |
8 | ~]#cat tom |
9 | anon_upload_enable=NO |
注意:虚账号的权限是受到匿名用户的配置选项控制
该过配置记得重启服务咯!
简单展示:
1 | [root@www ~]# ftp 10.211.55.24 |
2 | Connected to 10.211.55.24 (10.211.55.24). |
3 | 220 (vsFTPd 3.0.2) |
4 | Name (10.211.55.24:root): jusene |
5 | 331 Please specify the password. |
6 | Password: |
7 | 230 Login successful. |
8 | Remote system type is UNIX. |
9 | Using binary mode to transfer files. |
10 | ftp> |
11 | ftp> |
12 | ftp> ls |
13 | 227 Entering Passive Mode (10,211,55,24,243,74). |
14 | 150 Here comes the directory listing. |
15 | drwxr-xr-x 2 0 0 6 Mar 23 02:44 pub |
16 | drwxr-xr-x 2 1013 0 18 Mar 23 03:03 upload |
17 | 226 Directory send OK. |
18 | ftp> cd uplo |
19 | 550 Failed to change directory. |
20 | ftp> cd upload |
21 | 250 Directory successfully changed. |
22 | ftp> lcd /etc |
23 | Local directory now /etc |
24 | ftp> !ls |
25 | adjtime crypttab fstab iproute2 magic ntp.conf profile.d rsyslog.d sudo-ldap.conf |
26 | aliases csh.cshrc gai.conf iscsi mailcap openldap protocols rwtab sysconfig |
27 | aliases.db csh.login gcrypt issue mail.rc opt proxychains.conf rwtab.d sysctl.conf |
28 | alternatives cups ghostscript issue.net makedev.d pam.d rc sasl2 sysctl.d |
29 | anacrontab dbus-1 glances java man.config pango rc0.d securetty system-release |
30 | asound.conf default gnupg jvm maven passwd rc1.d security system-release-cpe |
31 | at.deny depmod.d group jvm-commmon mime.types passwd- rc2.d selinux terminfo |
32 | audisp dhcp group- krb5.conf mke2fs.conf php.d rc3.d services test.pass |
33 | audit DIR_COLORS grub.conf ld.so.cache modprobe.d php.ini rc4.d sestatus.conf test.passwd |
34 | bash_completion.d DIR_COLORS.256color gshadow ld.so.conf motd pkcs11 rc5.d sgml Trolltech.conf |
35 | bashrc DIR_COLORS.lightbgcolor gshadow- ld.so.conf.d mtab pki rc6.d shadow udev |
36 | blkid dracut.conf hal lftp.conf multipath plymouth rc.d shadow- vimrc |
37 | centos-release dracut.conf.d host.conf libaudit.conf my.cnf pm rc.local shells virc |
38 | chkconfig.d drirc hosts libuser.conf named pm-utils-hd-apm-restore.conf rc.sysinit skel wgetrc |
39 | ConsoleKit dropbear hosts.allow libvirt named.conf polkit-1 redhat-lsb ssh X11 |
40 | cron.d environment hosts.deny localtime named.iscdlv.key popt.d redhat-release ssl xdg |
41 | cron.daily ethers httpd login.defs named.rfc1912.zones portreserve resolv.conf statetab xinetd.conf |
42 | cron.deny exports init logrotate.conf named.root.key postfix rndc.key statetab.d xinetd.d |
43 | cron.hourly favicon.png init.conf logrotate.d NetworkManager ppp rpc subversion xml |
44 | cron.monthly filesystems init.d lsb-release networks prelink.conf.d rpm sudo.conf yum |
45 | crontab fonts inittab lsb-release.d nsswitch.conf printcap rsyncd.conf sudoers yum.conf |
46 | cron.weekly foomatic inputrc lvm ntp profile rsyslog.conf sudoers.d yum.repos.d |
47 | ftp> put hosts.allow |
48 | local: hosts.allow remote: hosts.allow |
49 | 227 Entering Passive Mode (10,211,55,24,78,51). |
50 | 150 Ok to send data. |
51 | 226 Transfer complete. |
52 | 370 bytes sent in 4.2e-05 secs (8809.52 Kbytes/sec) |
53 | ftp> exit |
54 | 221 Goodbye. |
55 | |
56 | |
57 | [root@www ~]# ftp 10.211.55.24 |
58 | Connected to 10.211.55.24 (10.211.55.24). |
59 | 220 (vsFTPd 3.0.2) |
60 | Name (10.211.55.24:root): tom |
61 | 331 Please specify the password. |
62 | Password: |
63 | 230 Login successful. |
64 | Remote system type is UNIX. |
65 | Using binary mode to transfer files. |
66 | ftp> lcd /etc |
67 | Local directory now /etc |
68 | ftp> ls |
69 | 227 Entering Passive Mode (10,211,55,24,44,80). |
70 | 150 Here comes the directory listing. |
71 | drwxr-xr-x 2 0 0 6 Mar 23 02:44 pub |
72 | drwxr-xr-x 2 1013 0 36 Mar 23 03:12 upload |
73 | 226 Directory send OK. |
74 | ftp> cd upload |
75 | 250 Directory successfully changed. |
76 | ftp> !ls |
77 | adjtime crypttab fstab iproute2 magic ntp.conf profile.d rsyslog.d sudo-ldap.conf |
78 | aliases csh.cshrc gai.conf iscsi mailcap openldap protocols rwtab sysconfig |
79 | aliases.db csh.login gcrypt issue mail.rc opt proxychains.conf rwtab.d sysctl.conf |
80 | alternatives cups ghostscript issue.net makedev.d pam.d rc sasl2 sysctl.d |
81 | anacrontab dbus-1 glances java man.config pango rc0.d securetty system-release |
82 | asound.conf default gnupg jvm maven passwd rc1.d security system-release-cpe |
83 | at.deny depmod.d group jvm-commmon mime.types passwd- rc2.d selinux terminfo |
84 | audisp dhcp group- krb5.conf mke2fs.conf php.d rc3.d services test.pass |
85 | audit DIR_COLORS grub.conf ld.so.cache modprobe.d php.ini rc4.d sestatus.conf test.passwd |
86 | bash_completion.d DIR_COLORS.256color gshadow ld.so.conf motd pkcs11 rc5.d sgml Trolltech.conf |
87 | bashrc DIR_COLORS.lightbgcolor gshadow- ld.so.conf.d mtab pki rc6.d shadow udev |
88 | blkid dracut.conf hal lftp.conf multipath plymouth rc.d shadow- vimrc |
89 | centos-release dracut.conf.d host.conf libaudit.conf my.cnf pm rc.local shells virc |
90 | chkconfig.d drirc hosts libuser.conf named pm-utils-hd-apm-restore.conf rc.sysinit skel wgetrc |
91 | ConsoleKit dropbear hosts.allow libvirt named.conf polkit-1 redhat-lsb ssh X11 |
92 | cron.d environment hosts.deny localtime named.iscdlv.key popt.d redhat-release ssl xdg |
93 | cron.daily ethers httpd login.defs named.rfc1912.zones portreserve resolv.conf statetab xinetd.conf |
94 | cron.deny exports init logrotate.conf named.root.key postfix rndc.key statetab.d xinetd.d |
95 | cron.hourly favicon.png init.conf logrotate.d NetworkManager ppp rpc subversion xml |
96 | cron.monthly filesystems init.d lsb-release networks prelink.conf.d rpm sudo.conf yum |
97 | crontab fonts inittab lsb-release.d nsswitch.conf printcap rsyncd.conf sudoers yum.conf |
98 | cron.weekly foomatic inputrc lvm ntp profile rsyslog.conf sudoers.d yum.repos.d |
99 | ftp> put hosts.deny |
100 | local: hosts.deny remote: hosts.deny |
101 | 227 Entering Passive Mode (10,211,55,24,129,57). |
102 | 550 Permission denied. |
103 | ftp> |
很明显可以看见tom没有上传权限,jusene有上传权限…