• ftp服务及其实现之vsftpd


    本文最早发布于我的51CTO博客,目前已迁移至博客园。

    简介

    FTP,File Transfer Protocol,文件传输协议
    文件服务器,具备存储和共享文件(权限设置合理的情况下)的功能
    命令端口:TCP/21
    数据端口:TCP/20(主动模式)
    明文传输指令与数据,解决办法是SFTP(SSH)和FTPS(SSL/TLS)

    实现

    服务器端实现

    Linux:vsftpd, pureftpd, proftpd
    Windows:Filezilla Server, Serv-U, ...

    客户端实现

    Linux:ftp, lftp, ...
    Windows:cuteftp, Filezilla, Flashfxp, ...

    连接模式

    FTP协议是一种古老的协议,比较特别。一般的协议,客户端和服务器端之间只需要一条连接即可,但是FTP需要两条,一条是命令连接,用于传输FTP命令;另外一条是数据连接,用于传输上传下载的数据。
    命令连接为客户端启用一个随机端口连接服务器端的21端口。
    数据连接有主动模式和被动模式两种。

    主动模式

    主动模式,positive,PORT

    1. 客户端启用一个高位随机端口x去连接服务器的21端口建立命令连接。
    2. 命令连接建立完毕后,客户端使用“PORT x+1”命令告诉服务器端客户端在x+1号监听数据连接。
    3. 服务器端使用20号端口去连接客户端的x+1号端口建立数据连接。
    4. 客户端通过数据连接向服务器端发送一个应答,表示数据连接建立成功开始传输数据。

    FTP主动模式

    缺陷:客户端需要启用一个数据连接监听端口等待服务器端来连接,因此客户端如果有防火墙的话,就需要对此端口进行放行。同时又由于端口号为随机的x+1号端口,因此在客户端防火墙要放行一个随机的端口就有一定的难度了!加之客户端的用户很多都是计算机小白用户,一般不太懂的做这个设置,也不太情愿。

    被动模式

    被动模式,passive,PASV
    由于主动模式缺陷的存在,诞生了被动模式。

    1. 客户端启用一个高位随机端口x去连接服务器的21端口建立命令连接。
    2. 客户端通过命令连接向服务器端发送PASV指令表示要使用被动模式。
    3. 服务器端同意使用PASV模式,并开始监听一个高位随机端口m,并将此端口号告知客户端。
    4. 客户端使用x+1号端口与服务器端口m建立数据连接。
    5. 服务器端响应客户端发起的数据连接请求,数据连接成功建立。

    FTP被动模式

    数据传输模式

    参考资料:
    https://mingersoft.com/blog/2011/01/ftp-and-the-difference-between-ascii-and-binary-modes/
    http://www.jscape.com/blog/ftp-binary-and-ascii-transfer-types-and-the-case-of-corrupt-files

    ASCII

    数据在计算机中存储或者在计算机间传输,需要以计算机可识别的一种形式而存在。这种形式就是二进制的数据,即0和1。将字母a翻译成二进制数值存储在计算机中,这种翻译过程可理解为编码。不同的计算机,编码可能不同,因此需要统一,应该是ISO给统一的,后来就诞生了ASCII这种编码。ASCII编码将大写字母、小写字母、数字以及控制符号都定义了ASCII值。比如数字0的十进制ASCII值是48,二进制的值是00110000。
    一般用于传输纯文本文件(例如批处理脚本、shell脚本、HTML文件、JavaScript文件等)。对于跨平台(例如Windows和Linux)的传输来说,ASCII传输模式可以自动修改行结束符,避免出现换行错乱的情况。
    FTP ASCII Transfer Mode

    Image / Binary

    逐字节传输数据,保留数据本身模样,不会像ASCII那样转换数据,因此不会自动转换文本文件的行结束符,可能出现跨操作系统传输文件后文本换行错乱的情况。
    一般用于传输二进制文件,库文件、图片、视频、Linux下的ELF可执行文件等。

    纯文本文件区分

    可以通过文本编辑器来区分文件是否是文本文件,常见的文本编辑器如下:

    • Windows记事本
    • Sublime Text 3
    • Notepad++
    • Vim

    文本文件使用文本编辑器打开后是正常显示的,而二进制文件如果使用编辑器打开一般会是此类乱码。
    编辑器打开二进制文件

    模式选择

    1. FTP图形客户端程序一般会自动识别,因此我们无需干预。
      FTP客户端设置数据传输类型

    2. FTP命令行工具可通过type命令切换

    ftp> type ascii
    200 Switching to ASCII mode.
    ftp> type binary
    200 Switching to Binary mode.
    ftp> type image
    200 Switching to Binary mode.
    

    用户

    匿名用户

    登录的用户名为anonymous或者ftp,密码为空。映射到本地用户ftp,家目录为/var/ftp/。

    本地用户

    登录的用户名和密码与Linux本地用户相同。每个FTP本地用户都会映射到同用户名的Linux用户,家目录为Linux用户的家目录。

    虚拟用户

    虚拟用户可以有多个,所有的虚拟用户都只会映射到一个本地用户,此本地用户在配置文件中被称为来宾用户(guest_username),来宾用户的家目录即为虚拟用户的家目录,每个虚拟用户都可以拥有独立的用户名和密码。本文中,虚拟用户的用户认证方式目前有两种:

    • 伯克利DB文件
    • MySQL

    环境

    系统:CentOS 6.9
    软件:vsftpd 2.2.2
    本实验在iptables和selinux均关闭的情况下进行

    帮助

    官网:http://vsftpd.beasts.org
    查看配置文件中的样例说明

    vim /etc/vsftpd/vsftpd.conf
    

    查看man手册

    man 5 vsftpd.conf
    

    配置文件

    /etc/vsftpd/vsftpd.conf
    此配置文件也是主配置文件
    每一行就是一句指令(directive)或者注释
    指令的格式如下

    option=value
    

    在option、=和value的两边都不可以存在空格
    指令有默认值,如果没有显式定义指令,则采用默认值,默认值查看man手册。
    “#”开头的行表示注释,“#”后接着1个空格表示描述信息

    # Example config file /etc/vsftpd/vsftpd.conf
    #
    # The default compiled in settings are fairly paranoid. This sample file
    # loosens things up a bit, to make the ftp daemon more usable.
    # Please see vsftpd.conf.5 for all compiled in defaults.
    

    “#”后不接空格表示被注释掉的指令

    #chown_uploads=YES
    #chown_username=whoever
    

    配置文件修改之后需要重启vsftpd服务才会使修改生效

    # service vsftpd restart
    Shutting down vsftpd:                                      [  OK  ]
    Starting vsftpd for vsftpd:                                [  OK  ]
    

    匿名用户和本地用户的实现

    指令说明

    vsftpd对权限的设置要求事无巨细,特别是对匿名用户的读(下载)、写(上传文件、创建目录、删除文件和重命名等)操作,除了要求对应的Linux用户权限设置妥当以外,还要有对应的不同指令的正确设置。

    首先

    write_enable:控制FTP是否可写,无论用户类型。最终用户是否具备相应的权限,一个是看指令上是否允许,另一个就是和Linux用户权限相关。

    匿名用户

    anonymous_enable:是否启用匿名用户。
    anon_upload_enable:是否允许匿名用户上传文件。
    anon_mkdir_write_enable:是否允许匿名用户创建目录。
    anon_other_write_enable:是否允许匿名用户执行其他写操作,包括删除和重命名。
    no_anon_password:是否不向匿名用户询问密码,反正匿名用户也没有密码,因此这项可以设置为YES。

    本地用户

    local_enable:是否启用本地用户。
    local_umask:本地用户创建文件的umask,文件使用666去减,目录使用777去减。

    目录消息

    dirmessage_enable:第一次进入某个目录的欢迎/描述信息,默认在每个目录下搜索.message文件,是否显示与客户端有关。
    message_file:指定目录消息文件的文件名。

    数据传输日志

    xferlog_enable:是否启用传输日志,传输日志记录用户上传下载的细节信息。
    vsftpd_log_file:传输日志的位置。当且仅当xferlog_enable为YES且xferlog_std_format为NO的时候有效。默认值是/var/log/vsftpd.log。
    xferlog_std_format:是否启用标准格式的传输日志,标准格式的传输日志易读性差,不过可用于传输统计生成器(猜测应该是一种日志统计工具)再利用。
    xferlog_file:指定标准格式的传输日志文件存储位置,当且仅当xferlog_enable和xferlog_std_format都被启用的情况下有效。默认值是/var/log/xferlog。

    数据传输模式

    port_enable:是否启用PORT模式,默认值是YES。
    connect_from_port_20:指定FTP的PORT模式是否使用20号端口;
    ftp_data_port:当connect_from_port_20为NO的时候,此选项设置PORT模式下FTP服务器使用的数据连接端口,默认值是20。
    ascii_download_enable和ascii_upload_enable:上传和下载的时候是否明确使用ASCII数据传输模式。默认情况下服务器假装允许ASCII模式但实际上会忽略ASCII请求。某些FTP如果启用此特性,会被通过FTP命令SIZE一个大文件来达到DoS***的效果。
    pasv_enable:是否启用PASV模式,默认值是YES。
    pasv_max_port和pasv_min_port:指定PASV模式下的端口范围,设置了好配合防火墙设置,0表示使用任意端口。

    修改匿名用户上传文件的属主

    chown_uploads:是否修改匿名用户上传文件的属主,不修改的话默认匿名用户上传的文件的属主和属组都是ftp。
    chown_username:设置匿名用户上传文件的新属主,不会改变属组。
    chown_upload_mode:设置匿名用户上传文件后文件的权限,默认是0600。

    设定超时时长

    idle_session_timeout:客户端输入两次FTP命令间隔时间的超时时长,默认是300秒。
    connect_timeout:PORT模式下,客户端响应数据连接的超时时长,默认是60秒。
    data_connection_timeout:数据传输停止的大致超时时长,默认是300秒。

    命令连接的监听端口

    standalone(独立模式):表示直接运行在后台,自己监听,不依靠类似xinetd的守护进程管理。

    listen:启用的话,使vsftpd运行于独立模式。
    listen_address:当vsftpd运行于独立模式时,此选项设置vsftpd监听的ipv4地址,默认是0.0.0.0。
    listen_port:当vsftpd运行于独立模式时,此选项设置vsftpd监听端口,默认是21。

    设定连接及传输速率

    local_max_rate:本地用户最大数据传输速率,单位是“字节/秒”,默认是0,表示无限制。
    anon_max_rate:匿名用户最大数据传输速率,单位是“字节/秒”,默认是0,表示无限制。
    max_clients:当vsftpd运行于独立模式时,此选项设置vsftpd支持的最大客户端连接数,0表示无限制,默认值是2000。
    max_per_ip:当vsftpd运行于独立模式时,此选项设置vsftpd支持的最大相同IP地址的客户端连接数,0表示无限制,默认值是50。

    禁锢本地用户

    chroot可以理解为禁锢的意思,使得用户在自己的家目录,无法切换至其他目录,但是进入自己的子目录除外。
    匿名用户始终被禁锢。

    chroot_local_user:是否禁锢所有本地用户。
    chroot_list_enable:是否启用禁锢列表文件。当chroot_local_user为YES的时候,chroot_list_file表示不被禁锢的本地用户。当chroot_local_user为NO的时候,chroot_list_file表示被禁锢的本地用户。
    chroot_list_file:禁锢列表文件位置。
    注意:vsftpd从2.3.5版本开始,如果设置了禁锢用户,那么当用户登录的时候,默认是会报错的。

    refusing to run with writable root inside chroot ()
    

    解决的办法有两种:

    1. 将用户的家目录设置为只读模式。
    2. 选项allow_writeable_chroot的值设置为YES。

    控制用户登录

    /etc/vsftpd/ftpusers:这是一个文件,非指令。黑名单文件,文件中的用户将被禁止登录FTP。不过是在输入密码之后才禁止登录的,密码仍然被传输了。
    将zwl用户加入ftpusers文件中

    # grep 'zwl' /etc/vsftpd/ftpusers 
    zwl
    

    在客户端上测试登录

    # ftp 192.168.17.100
    Connected to 192.168.17.100 (192.168.17.100).
    220 (vsFTPd 2.2.2)
    Name (192.168.17.100:root): zwl
    331 Please specify the password.
    Password:
    530 Login incorrect.
    Login failed.
    

    userlist_enable:是否启用用户列表文件。
    userlist_file:用户列表文件位置。认值是/etc/vsftpd/user_list。
    userlist_deny:用户列表文件中的用户是否被拒绝。如果用户被用户列表给拒绝了,那么连输入账号密码的机会都没有。默认值是YES。
    在配置文件中启用用户列表userlist_enable,选项userlist_file和userlist_deny保持默认值即可。

    # grep "userlist" /etc/vsftpd/vsftpd.conf
    userlist_enable=YES
    

    将用户zwl加入userlist_file

    # grep "zwl" /etc/vsftpd/user_list 
    zwl
    

    FTP客户端测试,可以看到报错的信息和ftpusers文件是不同的,** 重要的是使用用户列表拒绝的话,用户无法输入密码。 **

    # ftp 192.168.17.100
    Connected to 192.168.17.100 (192.168.17.100).
    220 (vsFTPd 2.2.2)
    Name (192.168.17.100:root): zwl
    530 Permission denied.
    Login failed.
    

    PAM简述

    要配置虚拟用户的话,需要理解PAM,不过我个人不太懂PAM,目前只能简单理解。

    PAM,Pluggable Authentication Modules,可插拔认证模块。
    vsftpd是通过PAM来完成用户认证的,配置文件中通过pam_service_name来指定vsftpd使用的PAM服务文件。

    pam_service_name=vsftpd
    

    这是相对路径,相对于/etc/pam.d/,即使用/etc/pam.d/vsftpd这个PAM服务文件,此目录下每一个文件都是一个pam服务。
    下面是vsftpd默认使用的PAM服务文件,目前并不详细理解,大概理解就可以了,比如从文件的第三行中的可以看出文件/etc/vsftpd/ftpusers中的每一行表示用户(item=user),每个用户都被拒绝登录(sense=deny)。

    # cat /etc/pam.d/vsftpd
    #%PAM-1.0
    session    optional     pam_keyinit.so    force revoke
    auth       required	pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
    auth       required	pam_shells.so
    auth       include	password-auth
    account    include	password-auth
    session    required     pam_loginuid.so
    session    include	password-auth
    

    PAM服务文件中调用的“.so”文件是相对路径,相对于/lib64/security/,此类文件是动态链接(dynamically linked)的库文件也是PAM的模块文件。

    虚拟用户之伯克利DB文件的实现

    创建用户信息文本文件

    # cat /etc/vsftpd/virtual_user.txt 
    tom
    123456
    jerry
    123456
    

    安装db4相关包获取db_load工具,此工具存在于包db4-utils中,理论上安装此包即可。

    # rpm -qa | grep 'db4'
    db4-devel-4.7.25-22.el6.x86_64
    db4-utils-4.7.25-22.el6.x86_64
    db4-cxx-4.7.25-22.el6.x86_64
    db4-4.7.25-22.el6.x86_64
    

    生成用户信息db文件

    # db_load -T -t hash -f /etc/vsftpd/virtual_user.txt /etc/vsftpd/virtual_user.db
    

    db_load的具体用法可以查阅RPM包db4-utils中的HTML文件

    # rpm -ql db4-utils | grep 'db_load'
    /usr/bin/db_load
    /usr/share/doc/db4-utils-4.7.25/utility/db_load.html
    

    pam服务文件替换

    # mv /etc/pam.d/vsftpd{,.bak}
    # vim /etc/pam.d/vsftpd
    auth required pam_userdb.so db=/etc/vsftpd/virtual_user
    account required pam_userdb.so db=/etc/vsftpd/virtual_user
    

    关于pam_userdb模块的介绍,请参照官网:http://www.linux-pam.org/Linux-PAM-html/sag-pam_userdb.html
    模块的参数db的值不可以是virtual_user.txt或者virtual_user.db,一定得是virtual_user!
    创建虚拟用户所映射的本地用户

    useradd -d /home/virtual_user_home -s /sbin/nologin virtual_user
    chmod 755 /home/virtual_user_home/
    

    当来宾用户的家目录的权限不是所有人都可读而且anon_world_readable_only的值为YES的时候,虚拟用户登录后执行ls查看目录会报错

    226 Transfer done (but failed to open directory).
    

    目前找到的解决办法有两种
    i. 虚拟用户的主目录,确保所有人都有读的权限。
    ii. 显式地设置anon_world_readable_only为NO。

    anon_world_readable_only
    	当启用的时候,匿名用户只能下载那些全局(所有者、所有组和其他人)可读的文件。这是意识到了FTP用户可能会拥有自己的文件,特别是在允许上传的时候。这样可以防止匿名用户下载其他FTP用户上传的自己没有读权限的文件。默认值是YES。
    

    配置文件中虚拟用户相关配置

    local_enable=YES
    	非匿名用户想要登录的话,必须开启,包括虚拟用户。
    guest_enable=YES
    	如果启用,所有非匿名(本地和虚拟)登录都会被认为是guest登录。guest登录的用户会被映射成选项guest_username所指定的用户。
    guest_username=virtual_user
    pam_service_name=vsftpd
    

    配置了虚拟用户之后,匿名用户可以登录,本地用户无法登录(因为pam服务文件已被我们修改)。
    虚拟用户在OS中的权限设置是被识别为选项guest_username所指定的用户。
    虚拟用户在配置文件中的权限设置,默认是被识别为匿名用户,也就是说如果要确保虚拟用户具备所有权限的话,还需要如下设置。

    anon_upload_enable=YES
    anon_mkdir_write_enable=YES
    anon_other_write_enable=YES
    

    如果想要修改虚拟用户默认映射的用户的话,可以参考下面这个选项。

    virtual_use_local_privs
    	默认情况下虚拟用户被识别为匿名用户(这么做是为了使得虚拟用户的权限设置更为严格,特别是在写权限上),通过设置此项可以将虚拟用户识别为本地用户。默认值是NO。
    

    虚拟用户和匿名用户一样,默认是被禁锢

    ftp> pwd
    257 "/"
    ftp> cd /etc
    550 Failed to change directory.
    

    目前为止,我们已经可以通过伯克利DB来实现虚拟用户了,但是所有的虚拟用户的权限都是一样的,如果想要使不同的虚拟用户具备不同的权限呢?
    可以借助配置文件中的选项user_config_dir,通过此选项我们可以配置一个目录:

    user_config_dir=/etc/vsftpd/user_conf/
    

    在目录下创建以用户名命名的文本文件,在文本文件中针对不同的虚拟用户设置不同的权限:

    # cat /etc/vsftpd/user_conf/tom
    anon_upload_enable=YES
    anon_mkdir_write_enable=YES
    anon_other_write_enable=YES
    # cat /etc/vsftpd/user_conf/jerry
    anon_upload_enable=NO
    anon_mkdir_write_enable=NO
    anon_other_write_enable=NO
    

    这种方式称为per-user basis,每个虚拟用户的配置文件的语法和主配置文件是一样的,但不是所有的选项都会生效,比如某些设置在用户的会话启用前就已经被应用了,比如listen_address、banner_file、max_per_ip、max_clients和xferlog_file等。
    在此基础上可以在主配置文件中禁用匿名用户

    anonymous_enable=NO
    

    这样子实现的结果就是:

    • 匿名用户无法登录。
    • 虚拟用户tom具有所有的权限。
    • 虚拟用户jerry只有下载那些所有人可读的文件的权限。

    虚拟用户之MySQL的实现

    安装mysql服务器端,我这边是通过下载官网5.7的yum源后安装的

    # rpm -qa | grep 'mysql'
    mysql-community-libs-compat-5.7.21-1.el6.x86_64
    mysql57-community-release-el6-11.noarch
    mysql-community-client-5.7.21-1.el6.x86_64
    mysql-community-libs-5.7.21-1.el6.x86_64
    mysql-community-common-5.7.21-1.el6.x86_64
    mysql-community-server-5.7.21-1.el6.x86_64
    mysql-community-devel-5.7.21-1.el6.x86_64
    

    注意:如果pam-mysql是源码编译安装的话,一定要记得安装mysql的devel包,否则在configure阶段会报错,无法找到头和库文件等。

    # ./configure --with-pam-mods-dir=/lib64/security/ --with-mysql=/usr
    checking if "/usr" is a mysql_config script... no
    checking mysql_config availability in /usr/bin... no
    checking mysqlclient availability in /usr/lib... no
    checking mysqlclient availability in /usr/lib/mysql... no
    checking mysql headers availability in /usr/include... no
    checking mysql headers availability in /usr/include/mysql... no
    configure: error: Cannot locate mysql client library. Please check your mysql installation.
    

    关于mysql 5.7的初始化密码以及密码要求
    一般我们安装并启动完mysql之后,都会运行mysql_secure_installation这个安全初始化脚本,以前的版本默认初始MySQL的root密码为空,因此直接回车即可通过
    但是在5.7中,会替用户初始化一个随机密码,并将此密码写在log当中
    记得提取此密码来运行mysql_secure_installation

    # grep 'temporary password' /var/log/mysqld.log 
    2018-04-11T09:38:41.716068Z 1 [Note] A temporary password is generated for root@localhost: H;CPodi6OhDt
    

    降低密码策略以及密码长度要求,方便我们设置简单的密码

    mysql> SET GLOBAL validate_password_policy = 'LOW';
    mysql> SET GLOBAL validate_password_length = 4;
    

    初始化虚拟用户数据及MySQL用户授权

    mysql> CREATE DATABASE vsftpd_auth CHARACTER SET utf8;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> USE vsftpd_auth;
    Database changed
    
    mysql> CREATE TABLE users (
        -> name VARCHAR(100),
        -> password VARCHAR(100)
        -> );
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> INSERT INTO `users` VALUES ('tom',PASSWORD('123456')),('jerry',PASSWORD('123456'));
    Query OK, 2 rows affected, 2 warnings (0.01 sec)
    Records: 2  Duplicates: 0  Warnings: 2
    
    mysql> SELECT * FROM `users`;
    +-------+-------------------------------------------+
    | name  | password                                  |
    +-------+-------------------------------------------+
    | tom   | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
    | jerry | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
    +-------+-------------------------------------------+
    2 rows in set (0.01 sec)
    
    mysql> CREATE USER 'vsftpd_auth'@'localhost' IDENTIFIED BY '123456';
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> GRANT ALL ON `vsftpd_auth`.* TO 'vsftpd_auth'@'localhost';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> FLUSH PRIVILEGES;
    Query OK, 0 rows affected (0.01 sec)
    

    在创建表users中设置字段的长度为100,因为我们使用了PASSWORD函数加密,加密后的字符长度为42,长度设置不够的话,在INSERT的时候会报错

    ERROR 1406 (22001): Data too long for column 'password' at row 1
    

    来宾账户依然使用之前在伯克利DB文件实验环节中使用的

    # grep 'virtual_user' /etc/passwd
    virtual_user:x:501:501::/home/virtual_user_home:/sbin/nologin
    # ls -ld /home/virtual_user_home/
    drwxr--r-- 4 virtual_user virtual_user 4096 Apr 10 11:04 /home/virtual_user_home/
    # grep 'guest' /etc/vsftpd/vsftpd.conf
    guest_enable=YES
    guest_username=virtual_user
    

    下载安装pam-mysql-第三方RPM包
    网上许多安装pam-mysql的教程都是通过官网:http://pam-mysql.sourceforge.net/
    来源码编译安装,通过源码编译安装的pam-mysql,安装成功后在我的环境下会登录失败
    通过/var/log/secure日志,发现频繁出现这两句报错

    Apr 13 16:47:52 server vsftpd[50238]: PAM unable to dlopen(/lib64/security/pam_mysql.so): /lib64/security/pam_mysql.so: undefined symbol: make_scrambled_password
    Apr 13 16:47:52 server vsftpd[50238]: PAM adding faulty module: /lib64/security/pam_mysql.so
    

    Google了一番发现这应该是pam-mysql自身的bug,网上有针对此问题而制作的RPM包,如下
    RPM包参考网址:https://centos.pkgs.org/6/epel-x86_64/pam_mysql-0.7-0.12.rc1.el6.x86_64.rpm.html
    此RPM的changelog刚好解决了此问题

    2011-06-10 - Paul P. Komkoff Jr <i@stingr.net> 1:0.7-0.12.rc1
    - make_scrambled_password fix (bz#709534)
    

    下载安装过程

    # wget http://dl.fedoraproject.org/pub/epel/6/x86_64/Packages/p/pam_mysql-0.7-0.12.rc1.el6.x86_64.rpm
    # rpm -ivh pam_mysql-0.7-0.12.rc1.el6.x86_64.rpm
    # rpm -ql pam_mysql
    /lib64/security/pam_mysql.so
    /usr/share/doc/pam_mysql-0.7
    /usr/share/doc/pam_mysql-0.7/COPYING
    /usr/share/doc/pam_mysql-0.7/CREDITS
    /usr/share/doc/pam_mysql-0.7/ChangeLog
    /usr/share/doc/pam_mysql-0.7/NEWS
    /usr/share/doc/pam_mysql-0.7/README
    

    如果上面那个RPM包安装的pam-mysql模块,使用失败的,可以考虑官网的源码安装,如下两步
    安装开发环境包组用于源码编译安装

    # yum groupinstall "Development Tools" "Server Platform Development"
    

    下载安装pam-mysql-官网源码编译安装

    # cd /usr/local/src/
    # wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql-0.7RC1.tar.gz
    # tar -xzf pam_mysql-0.7RC1.tar.gz
    # cd pam_mysql-0.7RC1/
    # ./configure --with-pam-mods-dir=/lib64/security/ --with-mysql=/usr
    # make
    # make install
    

    关于pam-mysql的参数说明,记得阅读一下README

    RPM包安装的位于:/usr/share/doc/pam_mysql-0.7/README
    源码编译安装的位于:/usr/local/src/pam_mysql-0.7RC1/README
    

    创建PAM服务文件
    参数verbose:设置后可用于排错,应该也是设置了我才看到了/var/log/secure中的报错
    参数crypt:设置用户密码的加密方法,0或者plain表示纯文本,2或者mysql表示使用MySQL的PASSWORD()函数加密

    # cat /etc/pam.d/vsftpd.mysql 
    auth required pam_mysql.so user=vsftpd_auth passwd=123456 host=localhost db=vsftpd_auth table=users usercolumn=name passwdcolumn=password crypt=2 verbose=1 sqllog=1
    account required pam_mysql.so user=vsftpd_auth passwd=123456 host=localhost db=vsftpd_auth table=users usercolumn=name passwdcolumn=password crypt=2 verbose=1 sqllog=1
    

    设置vsftpd调用PAM服务文件

    # grep 'pam_service' /etc/vsftpd/vsftpd.conf
    pam_service_name=vsftpd.mysql
    

    vsftpd配置文件有修改的话,记得重启服务

    # service vsftpd restart
    Shutting down vsftpd:                                      [  OK  ]
    Starting vsftpd for vsftpd:                                [  OK  ]
    

    我自己测试登录是OK的,就不贴上来了。
    基于pam-mysql的虚拟用户做per-user basis的权限设置,应该是和基于伯克利DB文件实现是一样的,这里没测试。

    总结

    vsftpd的使用感觉还是有点麻烦,以前尝试过pure-ftpd,相对简单很多。
    vsftpd使用到这个程度的话,我觉得已经很足够了,毕竟这个服务目前已经不是很多人在使用了。

  • 相关阅读:
    小程序-自定义组件
    51Nod
    CodeForces
    JSON、闭包和原型----透视Javascript语言核心
    转载:动态规划法总结
    to初学者:从汉诺塔问题深入理解递归算法思想
    不知‘时间复杂度’所云的看过来
    盲点流水账记录
    常用序列化协议总结
    排序——了解总体以及插入排序
  • 原文地址:https://www.cnblogs.com/alongdidi/p/ftp_vsftpd.html
Copyright © 2020-2023  润新知