vsftpd配置详解(一)

vsftpd配置详解


一、vsftpd 简介
    Vsftpd是一个基于GPL发布的类UNIX系统的ftp服务器软件。其全称是Very Secure FTP Deamon,在安全性、速度和稳定性都有着不俗的表现。在安全性方面,vsftpd针对程序的权限来设计,以一般身份启动服务,对Linux系统的使用权限较低;在千兆以太网上,

vsftpd的速度可以达到86MB/s;在稳定性上更是优秀,资料表明,完全工作24小时,传输数据达2.6TB,平均并发连接为1500用户,峰值达4000用户,而这些还是在单机上实现的。此外,vsftpd 还包括以下特性:
    基于IP的虚拟服务器
    虚拟用户,结合数据库的用户验证
    每个用户独立配置文件
    速率限制
    IPV6支持
    支持SSL加密传输
    ……

哪些站点在使用vsftpd
    以下站点一直在使用vsftpd(这仅仅是很少很少的一部分站点)
    ftp.redhat.com
    ftp.suse.com
    ftp.debian.org
    ftp.openbsd.org
    ftp.freebsd.org
    ftp.gnu.org
    ftp.gnome.org
    ftp.kde.org
    ftp.kernel.org
    rpmfind.net
    ftp.linux.org.uk
    ftp.gimp.org
    ftp-stud.fht-esslingen.de
    gd.tuwien.ac.at
    ftp.sunet.se
    ftp.ximian.com
    ftp.engardelinux.org
    ftp.sunsite.org.uk
    ftp.isc.org
    以上内容摘自vsftpd官方网站http://vsftpd.beasts.org/

二、软件安装和卸载

获得软件
    vsftpd目前最新版本为2.0.5,下载地址:ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.0.5.tar.gz

软件安装
    解压软件,编辑builddefs.h文件
    # tar zxvf vsftpd-2.0.5.tar.gz
    # cd vsftpd-2.0.5
    # vi builddefs.h
    找到下面三行,其含义如右所示
    #undef VSF_BUILD_TCPWRAPPERS             //是否允许使用TCP Wrappers
    #define VSF_BUILD_PAM                    //是否允许使用PAM认证
    #undef VSF_BUILD_SSL                     //是否允许使用SSL

    如果要允许以上所示某项功能,使把undef改为define即可,注意每行前的“#“号不是注释,不能去掉(熟悉C语言的同志应该知道这个“#”是什么意思)。其中TCP Wrappers是一个验证IP地址合法性的程序,PAM认证让vsftpd支持本地用户登陆服务器,使用SSL可

以建立一个加密的数据传输。这里我们把三项都启用。
    编译安装。如果系统中安装有旧版vsftpd,请先卸载它。默认安装执行文件在/usr/local/sbin中,man page放在/usr/local/man/man5与/usr/local/man/man8中。
    # make
    # make install

    将默认配置文件考贝到/etc/vsftpd/
    # mkdir /etc/vsftpd/
    # cp vsftpd.conf /etc/vsftpd/                   

    为了认vsftpd支持本地用户登录,我们将身份认证模块文件考入系统中。
    # cp RedHat/vsftpd.pam /etc/pam.d/vsftpd

    建立ftp用户及主目录:
    # mkdir /var/ftp
    # useradd -d /var/ftp ftp
  
    如果本来就已经存在ftp用户,则执行下面两条命令:
    # chown root:root /var/ftp
    # chmod 755 /var/ftp

    建立vsftpd需要的特殊目录:
    # mkdir /usr/share/empty/


软件卸载
    如果需要卸载,使用如下命令:
    # rm /usr/local/sbin/vsftpd
    # rm /usr/local/man/man5/vsftpd.conf.5
    # rm /usr/local/man/man8/vsftpd.8
    # rm /etc/xinetd.d/vsftpd
    # rm -rf /etc/vsftpd

三、配置vsftpd服务

服务的启动与停止
    启动服务之前,我们先编辑配置文件/etc/vsftpd/vsftpd.conf. 打开配置文件后可以看到许多以“#”开始的行,这些行都是注释行,大多是帮助信息,可以仔细阅读。vsftpd.conf文件的所有项目都是以“参数=值”来设置的,对格式要求比较严格,必须严格区分

大小写,等号两边不能有空格,每行的最后也不能有空格。每个参数都有一个默认值,没有在配置文件中明确指定的参数就会使用默认值。我们这里不理会配置文件本来的信息,把所有内容都删掉或注释掉,最后加上下面四行,每行右边的//及后的文字是含义说明,不

要输入到文件中:
    listen=yes                        //vsftpd工作在standalone 模式下
    anonymous_enable=yes                //允许匿名用户登陆服务器
    local_enable=yes                    //允许本地用户登录到服务器
    pam_service_name=vsftpd            //使用PAM认证

    vsftpd有两种工作模式,standalone模式和xinetd守护进程模式,第1行就是让其工作在standalone模式下。此种模式中,每次修改配置文件必须重新启动vsftpd服务才能生效,关于两种模式在后面有详细介绍。我们安装时还把 Redhat 目录下的 vsftpd.pam 文件复

制成了/etc/pam.d/vsftpd 文件。这个文件就是本地用户登陆的 pam 验证配置文件。关于这个文件我们会在后面具体介绍。这里我们要知道,必须得有这个配置文件,而且主配置文件里要加上 pam_service_name=vsftpd语句,我们才能让本地用户登陆。用以下命令启动

服务:
    # /usr/local/sbin/vsftpd /etc/vsftpd/vsftpd.conf &

    为保证服务确实启动,我们用如下命令检测:
    # netstat -an |grep 21
    tcp        0      0 0.0.0.0:21                  0.0.0.0:*                   LISTEN

    我们看到服务器已经打开了tcp21端口,表明ftp确实已经启动。再登录服务器:
    # ftp 127.0.0.1
    Connected to 127.0.0.1.
    220 (vsFTPd 2.0.5)
    530 Please login with USER and PASS.
    530 Please login with USER and PASS.
    KERBEROS_V4 rejected as an authentication type
    Name (127.0.0.1:root): ftp
    331 Please specify the password.
    Password:
    230 Login successful.

    这时我们已经用匿名用户(用户名ftp或anonymous,密码任意)登录到服务器了,还可以用本地用户登录。我们做测试时建议使用如上所示的ftp命令(windows、Linux及Unix都带这个命令,用法都是一样的)来登录服务器,这样可以看到更详细的信息,对于我们调

试服务器是非常有帮助的。最简单的ftp服务器就已经达建起来了。使用如下命令关闭ftp服务:
    # killall vsftpd

服务启动脚本的制作
    在standalone 模式中,经常用上面的命令启动服务比较麻烦,我们做一个脚本来启动和停止服务。
建立一个新文件/etc/rc.d/init.d/vsftpd,把以下内容复制到文件中:

#!/bin/bash
#
# vsftpd      This shell script takes care of starting and stopping
#             standalone vsftpd.
#
# chkconfig: - 60 50
# description: Vsftpd is a ftp daemon, which is the program \
#              that answers incoming ftp service requests.
# processname: vsftpd
# config: /etc/vsftpd/vsftpd.conf
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -x /usr/local/sbin/vsftpd ] || exit 0
RETVAL=0
prog="vsftpd"
start() {
        # Start daemons.
        if [ -d /etc/vsftpd ] ; then
                for i in `ls /etc/vsftpd/*.conf`; do
                        site=`basename $i .conf`
                        echo -n $"Starting $prog for $site: "
                        /usr/local/sbin/vsftpd $i &
                        RETVAL=$?
                        [ $RETVAL -eq 0 ] && {
                           touch /var/lock/subsys/$prog
                           success $"$prog $site"
                        }
                        echo
                done
        else
                RETVAL=1
        fi
        return $RETVAL
}
stop() {
        # Stop daemons.
        echo -n $"Shutting down $prog: "
        killproc $prog
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
        return $RETVAL
}
# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart|reload)
        stop
        start
        RETVAL=$?
        ;;
  condrestart)
        if [ -f /var/lock/subsys/$prog ]; then
            stop
            start
            RETVAL=$?
        fi
        ;;
  status)
        status $prog
        RETVAL=$?
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|condrestart|status}"
        exit 1
esac
exit $RETVAL


    保存文件,再给该文件加上执行权限:
    # chmod 755 /etc/rc.d/init.d/vsftpd

    这样我们就可以通过下面的方法来管理服务了:
    # service vsftpd {start|stop|restart|condrestart|status}
    例如重新启动服务:
    # service vsftpd restart
    Shutting down vsftpd:                   [OK ]
    Starting vsftpd for vsftpd:             [OK ]

四、配置文件详解
    vsftpd配置文件只有一个,就是/etc/vsftpd/vsftpd.conf,上一小节我们就已经加入了两行参数了。在修改了配置文件之后,需要重新启动服务才能生效。下面我们就来详细解释其中的参数。

1. 匿名及本地用户共同参数
    write_enable=yes/no             //是否允许全局可写
    download_enable=yes/no            //是否允许所有用户可以下载
    dirlist_enable=yes/no             //是否允许所有用户可以浏览(列出文件列表)

    我们将write_enable=no、download_enable=yes两行加入配置文件,再测试:
    # ftp 127.0.0.1
    ……
    ftp> ls
    227 Entering Passive Mode (127,0,0,1,230,192)
    150 Here comes the directory listing.
    -rw-r--r--    1 0        0               4 May 13 11:43 ioo_file
    226 Directory send OK.
    ftp> get ioo_file
    local: ioo_file remote: ioo_file
    227 Entering Passive Mode (127,0,0,1,160,26)
    150 Opening BINARY mode data connection for ioo_file (4 bytes).
    226 File send OK.
    4 bytes received in 0.062 seconds (0.063 Kbytes/s)
    ftp> put scsrun.log
    local: scsrun.log remote: scsrun.log
    227 Entering Passive Mode (127,0,0,1,176,84)
    550 Permission denied.

    如上所示,我们看到了ftp上的文件,可以下载文件,但不可以上传文件。如果把dirlist_enable=no 也加上,便无法看到ftp上的文件(无法列出文件列表),但是如果你知道具体的文件名及路径,仍然可以下载文件的。实验结果就不贴上来了。

    再看下一组:
    ftpd_banner=欢迎语字符串
    banner_file=文件
    dirmessage_enable=yes/no
    message_file=文件
    参数ftpd_banner设置的欢迎语字符串将在登录时看到,如果想做出多行欢迎语,就要把内容单独存为banner_file参数指定的文件,应用中这两个参数二选一即可。dirmessage_enable和message_file参数是进入某个目录后显示的欢迎信息,用法与前两个参数一样。

2. 本地用户管理

2.1 本地用户常规配置参数
    local_root=/path                  //本地用户登陆服务器后直接进入的目录
    local_umask=八进制数       //本地用户上传档案权限的 umask值
    local_max_rate=数字            //本地用户传输速率单位为 bps
    chmod_enable=yes/no            // 是否允许本地用户改变ftp 服务器上档案的权限

    我们知道使用本地用户登录ftp后进入的是用户的主目录,locla_root这个参数允许我们登录服务器后直接进入其它的目录。此功能结合Apache 的userdir模块来实现网站内容更新上传是非常方便的。Linux系统中的任何文件都是有权限值的,上传的文件也不例外,

这个默认的权限值就由 local_umask参数指定。其计算方法为:
    默认建立文件的权限+local_umask =0666
    默认建立目录的权限+local_umask =0777
    由此我们可以看出,上传的文件无论如何都不可能有执行权限的。这也是vsftp安全性的体现啊!
    local_max_rate参数限定了数据传输速率,包括上传和下载。chmod_enable参数限制用户是否可以改变档案权限(使用chmod, site命令)。

    我们可能想让为每个用户进行单独的配置,或者想配置个别用户的权限。这样就得为每个本地用户配置一个文件。这些配置文件必须是在同一个目录下,所以我们可以设置本地用户单独配置文件所在的目录:
    user_config_dir=/path        //用户单独配置文件所在目录

    我们在配置文件中加入以下几行:
    local_umask=077
    local_max_rate=20000
    user_config_dir=/etc/vsftpd/vsftpd_user_dir
    给予用户上传权限:
    write_enable=yes
    新建一个普通用户ioo,再新建一个目录/etc/vsftpd/vsftpd_user_dir,其下建一个文件ioo,里面加入下面几行:
    local_root=/var/www/html
    local_umask=022
    local_max_rate=50000
    把/var/www/html的所有者改为ioo:
    chown ioo:ioo /var/www/html
    测试之后我们发现,使用ioo用户登录后就直接进入var/www/html了,上传的文件(夹)权限为644(755),传输速率为50k,自定义的设置覆盖了主配置文件中的设置。

2.2 本地用户登录限制参数
    在我们的服务器上本来就有很多的本地用户,这些本地用户应该都是可以登陆 ftp 服务器的。但是 ftp 服务是以明文传输的,如果允许管理员登陆的话,这种机制显然不好。又或者我们想让一些本地用户可以登陆,或者一些不能登陆我们的 ftp 服务器,这样我们

可以怎么设置呢?
    Vsftpd 提供了 userlist 功能。它使用一个文件来保存一些用户名,然后根据配置来决定是文件中的用户可以登录还是文件中没有列出的用户可以登陆 ftp 服务器,这样就对本地用户的登陆起到了限制作用。其配置参数有如下几个:
    userlist_enable=yes/no             //是否启用 userlist 功能模块
    userlist_deny=yes/no               //是否拒绝 userlist 文件中用户登陆 ftp 服务
    userlist_file=/path/to/file              //指定的 userlist 文件名
  
    当第1个参数值为yes时,第2、3行才起作用。我们将配置文件加上如下3行:
    userlist_enable=yes
    userlist_deny=yes
    userlist_file=/etc/vsftpd/vsftpd.userlist

    然后再新建一个文件/etc/vsftpd/vsftpd.userlist,在里面加入用户名,每个用户名一行,比如我这里加入用户root,再登录服务时出现以下信息:
    # ftp 127.0.0.1
    Connected to 127.0.0.1.
    ……
    Name (127.0.0.1:root): root
    530 Permission denied.
    Login failed.

    root用户已经不能登录了,在输入密码之前就被拒绝,但其它用户还可以登录的。如果把userlist_deny的值改为no,则只有文件中的用户才可以登录服务器。

2.3 本地用户的根目录参数
    大家再来看下面这一段:
    # ftp 127.0.0.1
    ……
    Name (127.0.0.1:root): ioo
    331 Please specify the password.
    Password:
    230 Login successful.
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> pwd
    257 "/home/ioo"
    ftp> cd /
    250 Directory successfully changed.
    ftp> ls
    227 Entering Passive Mode (127,0,0,1,163,193)
    150 Here comes the directory listing.
    drwxr-xr-x    2 0        0            4096 May 12 21:22 bin
    drwxr-xr-x    3 0        0            4096 Apr 30 19:57 boot
    drwxr-xr-x   12 0        0            3840 May 13 10:29 dev
    ……

    是不是感到吃惊了!我们用本地用户登录ftp服务器,却可以看到整个服务器的目录和文件,甚至还可以把/etc/passwd文件下载下来,这是非常不安全的,我们应该禁止这个功能,限制用户只能在自己的目录里浏览,这就要用到chroot功能。看下面三个参数:
    chroot_list_enable=yes/no             //是否启用 chroot_list 文件
    chroot_local_user=yes/no              //是否限制本地用户的根目录为自己的主目录
    chroot_list_file=/path/to/file                  //设置 chrootlist 文件名

    我们新建一个用户woo,再新建一个文件/etc/vsftpd/vsftpd.chroot_list,其中加入woo。然后在配置文件中添加以下几行:
    chroot_list_enable=yes
    chroot_local_user=yes
    chroot_list_file=/etc/vsftpd/vsftpd.chroot_list

    登录服务器测试:
    # ftp 127.0.0.1
    ……
    Name (127.0.0.1:root): woo
    331 Please specify the password.
    Password:
    230 Login successful.
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> pwd
    257 "/home/woo"

    Name (127.0.0.1:root): ioo
    331 Please specify the password.
    Password:
    230 Login successful.
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> pwd
    257 "/"

    我们看到,在文件中的用户woo根目录仍然是系统根目录,但文件外的用户根目录已经变成了“/”,就是说列在文件外的用户已经不能在自己主目录范围外浏览了。
    更改chroot_list_enable和chroot_local_user的值,得到以下几种组合:
参数     取值     取值     取值     取值
chroot_list_enable     yes     yes     no     no
chroot_local_user     yes     no     yes     no
意义     文件中列出的用户根目录为系统根目录,其它用户根目录为自己主目录。     文件中列出的用户根目录为自己主目录,其它用户根目录为系统根目录。     全部用户根目录都是自己主目录。     全部用户根目录都是系统根目录。


3. 匿名用户参数
    我们可以认为,本地用户进入自己主目录本身就应有比较大的权限,所以我们看到本地用户受限的语句不多。但是匿名用户通常涉及到一个公开、公共的互联网环境,所以限制匿名用户的权限语句就比较多,限制也比较细致。看看这一组参数:
    anon_upload_enable=yes/no           //是否允许匿名用户上传
    anon_mkdir_write_enable=yes/no      //是否允许匿名用户建立文件夹
    anon_other_write_enable=yes/no      //是否允许匿名用户可以使用除了建立文件夹和上传文件以外其他的ftp写操作命令。例如:delete、rename 等等
    anon_world_readable_only=yes/no      //匿名用户是否允许下载所有用户都可以访问的文件

    我们先把配置文件清理一下,现在配置文件只有下面几行:
    listen=yes  
    anonymous_enable=yes
    write_enable=yes
    download_enable=yes
    dirlist_enable=yes
    anon_upload_enable=yes
    anon_mkdir_write_enable=yes
    anon_other_write_enable=yes


    我们希望匿名用户有上传文件的权限,但这里还只是在ftp服务里给了写权限,还必须在文件权限考虑实现。于是我们给/var/ftp加上写权限:
    chmod a+w /var/ftp
    然后登录服务器:
    # ftp 127.0.0.1
    ……
    Name (127.0.0.1:root): ftp
    331 Please specify the password.
    Password:
    500 OOPS: vsftpd: refusing to run with writable anonymous root
    Login failed.
    421 Service not available, remote server has closed connection

    结果我们连服务器都登陆不了了!这是因为vsftpd出于在安全方面的考虑,不允许匿名用户对根目录有写权限。为此,我们只有去掉/var/ftp的写权限,再在其中新建一个目录,给予其写权限,让匿名用户上传文件到这个目录中。
    # chmod 755 /var/ftp
    # mkdir /var/ftp/upload
    # chmod 777 /var/ftp/upload

    现在我们可以匿名在upload里上传文件、建立文件夹、还可以删除改名等,但是却无法将上传的文件下载回来。如果你上传的文件是在一个新建的文件夹里,那么上传的文件不但下载不下来,而且连看都看不到:
    ftp> mkdir asm
    257 "/upload/asm" created
    ftp> cd asm
    250 Directory successfully changed.
    ftp> put file1
    local: file1 remote: file1
    227 Entering Passive Mode (127,0,0,1,135,56)
    150 Ok to send data.
    226 File receive OK.
    5 bytes sent in 0.063 seconds (0.077 Kbytes/s)
    ftp> get file1
    local: file1 remote: file1
    227 Entering Passive Mode (127,0,0,1,20,101)
    550 Failed to open file.
    ftp> ls
    227 Entering Passive Mode (127,0,0,1,133,186)
    150 Here comes the directory listing.
    226 Transfer done (but failed to open directory).
    ftp>
    这就要研究anon_world_readable_only这个参数了,它的默认值是yes。如果其值为yes,则匿名用户只可以下载所有用户都可访问的文件。比如:
    # ll
    total 40
    -rw----r-- 1 ftp ftp 34935 05-13 17:38 install.log
    -rw------- 1 ftp ftp   209 05-13 18:16 scsrun.log
    这里install.log文件权限其它位上有r权限,那么这个文件就可以被下载;scsrun.log文件其它位上没有任何权限,所以这个文件就不能被匿名用户下载。
    因此解决方法有两个,一是把参数anon_world_readable_only的值改为no;二是把上传文件默认权限的其它位上加上执行权限,这就用到下面这个参数:
    anon_umask=八进制数
    这个参数值的计算方法与本地用户local_umask参数一样,不在赘述。

    在以上的实验中,大家可能已经注意到匿名用户上传的档案所有者为ftp,这们也可能用下面两个参数来改变档案所有者:
    chown_uploads=yes/no         //是否开启修改默认匿名上传档案所有者的功能
    chown_username=本地用户名     //匿名上传档案的所有者名

    匿名用户使用任何密码都是可以登陆服务器的,那么我们可以免了匿名用户登陆必须输入密码的步骤,只要我们在配置文件中加入:
    no_anon_password=yes

    匿名用户的参数还有很多,我们就不一一介绍了

    到此,我们已经可以达建出的ftp服务器已经可以满足很多场合的需要了,如果有要求更加苛刻的场合,那就还需要进一步设置。

 

 
4. IP监听与连接控制
     vsftpd工作在独立模式(standalone)下的启动参数有两项:
     listen=yes/no
     listen_ipv6=yes/no
     其中第一条已经前面已经提过了,第二条应用在ipv6网络环境中,这两相参数只能有一条值为yes。
     在实际的网络环境中,服务器通常都有多个IP地址,而每个IP地址连接不同的网段,我们可能并不希望在所有网段的上的计算机都能访问服务器。而默认情况下,vsftpd将在所有的IP地址上监听,因此,我们需要下面两行:
     listen_address=监听 ip
     listen_address6=监听 ip
     这两行分别是针对IPv4和IPv6环境的。

     下面的两项是vsftpd并发连接控制:
     max_clients=数字
     max_per_ip=数字
     参数max_clients设置了服务器可以接受的最大并发连接数量,max_per_ip设置了每个客户端IP可以发起的最大连接数。针对服务器性能适当设置这两个参数,可以在服务器可接受的连接数量和连接速度之间找到平衡点。这两项默认值均为0,表示无限制。

     accept_timeout=数字
     connect_timeout=数字
     data_connection_timeout=数字
     idle_session_timeout=数字
     上面的数字都是以秒为单位的。其中 access_timeout 代表以 pasv数据连接模式的时候,数据连接的超时;connect_timeout 表示以 port模式连接数据连接时的超时时间;关于ftp服务连接模式下面会有详细介绍。data_connection_timeout 表示数据连接后数据

连接等待的空闲时间超时,超过时间后,数据连接将断开连接;idle_session_timeout 设置发呆时间,也就是客户端隔多长时间不与服务器有交互 ftp 命令,将自动断开 ftp 服务连接。

5. 关于连接端口设置
     我们知道 ftp 服务有一点是不同于其他的服务的是,ftp 服务使用的是 tcp 双连接通道,也就是ftp-server 和 ftp-data 连接。我们可以这么理解:ftp-server 连接接受客户端连接请求、并发控制、身份和权限认证以及传输客户端下达的命令。ftp-data连接负

责传输数据,也就是说当有数据传输的时候才会有这条连接。我们先来看一下 ftp-server 的设置:
     listen_port=端口号
     那么这条设置可以设置 ftp-server 端口号,默认为21,如果我们指定了其它端口号,那么客户端连接服务器上时就得使用指定端口号了。我们将这一行加入主配置文件中:
     listen_port=2121
     # ftp 127.0.0.1
     ftp: connect: Connection refused
     ftp> open 127.0.0.1 2121
     Connected to 127.0.0.1.
     220 (vsFTPd 2.0.5)
     530 Please login with USER and PASS.
     ……
     已经看到效果了,接下来我们讨论ftp-data连接的问题。
     FTP数据传输有两种模式:FTP Port模式和FTP Passive模式,两种工作方式截然不同。
     FTP Port模式
     在FTP Port模式下,客户端与服务器建立ftp-server连接之后,如果某条指令涉及到数据传送,就需要建立ftp-data连接。其实连接步骤如下:
     (1) 客户端启用另一个高于1024的空闲端口xx做连接准备,并且使用port命令利用ftp-server信道向服务器发送一个数据包,数据包里包含客户端的IP地址和xx端口,告诉服务器客户端xx端口已做好连接准备。Port命令还支持第三方(third-party)模式,第三方

模式是客户端告诉服务器端打开与另台主机的连接。
     (2) 服务器以ftp-data端口(默认为20)主动向客户端xx端口进行连接。
     (3) 客户端响应服务器连接,并继续完成三次握手后,ftp-data连接建立,开始传送数据。当数据传输完毕后,服务器ftp-data端口就处于等待关闭状态。
     我们看到,Port模式下ftp-data连接请求是由服务器发起的。现在来看一下vsftpd中关于Port模式的语句设置:
     port_enable=yes/no                               //是否启用 port 模式
     connect_from_port_20=yes/no                    //port 模式下是否默认使用固定的 20 端口
     ftp_data_port=port_number                        //指定 port 模式的端口号
     port_promiscuous=yes/no                 //是否使用安全的 port 模式
     将port_enable 设置为 yes,就采用 port 模式。在 port 模式下端口如果采用固定的20 端口,就把connect_from_port_20选项就设为yes,这是很多服务器默认的设置规则。我们也可以指定其他的端口,那么这也就由ftp_data_port 来指定固定端口。

port_promiscuous 默认值为no,表示ftp-data连接之前检验一下数据连接的目标ip 的是否是真正客户端的IP,反之则不检查。除非你确保服务器是与真正的客户端进行连接,否则不要将此参数值改为yes。
     我们将下面两行加入配置文件中:
     port_enable=yes
     connect_from_port_20=no
     登录服务器运行3次ls(显示文件列表)命令,再在服务器端运行netstat命令查看效果:
     # ftp 127.0.0.1
     Connected to 127.0.0.1.
     ……
     230 Login successful.
     Remote system type is UNIX.
     Using binary mode to transfer files.
     ftp> passive
     Passive mode off.
     ftp> ls
     ……
     226 Directory send OK.
     ftp> ls
     ……
     ftp> ls
     ……
     ftp> bye
     # netstat -an|more
     ……
     tcp 0 0 127.0.0.1:1069 127.0.0.1:1068 TIME_WAIT
     tcp 0 0 127.0.0.1:21   127.0.0.1:1065 TIME_WAIT
     tcp 0 0 127.0.0.1:1071 127.0.0.1:1070 TIME_WAIT
     tcp 0 0 127.0.0.1:1067 127.0.0.1:1066 TIME_WAIT
     ……
     我们看到服务器开了3个大于1024的端口去连接客户端,这3个连接就是3次ls命令产生的。如果我们把connect_from_port_20参数的值改为yes,再做上述实验,就会发现服务器3次连接都固定打开20端口。如果我们再加上ftp_data_port=2020语句,再做上述实验,

服务器就会固定开启2020端口。

[attach]167[/attach]

    大家来看这张图,局域网客户机使用私有IP地址,并采用出口路由器做的 NAT(网络地址转换)连到 internet。ftp 服务器采用的是port模式。当客户端使用port命令向服务器发出包含自身IP地址和端口的包,此包通过路由器时路由器必须检查其内容,把包中的IP

地址和端口翻译成分配给客户的地址和端口,而这个操作要求路由器必须工作在应用层!我们不可能要求每个客户的路由器都有此功能,但如果路由器没有正常完成这步工作,ftp数据传输就失败了。
     另外,由于第三方third-party模式的支持,黑客还可能在PORT命令中设置IP地址和端口号参数来指定一台其它主机的地址和端口号来发动攻击(称为FTP反弹攻击)。虽然有的防火墙设备已经修正了该问题,但对于大多数防火墙和路由器来说这个问题还是一个非常

严重的。

     FTP Passive模式
     下面描述了Passive模式的ftp-data连接建立的步骤:
     (1) 当用户请求数据传输的时候,客户端软件发送PASV命令给服务器端表明客户端希望进入Passive模式;
     (2) 服务器端进行应答,应答数据包内有服务器的IP地址和一个临时端口,这个临时的端口是客户端在打开数据传输连接时应该使用的端口;
     (3) 客户端服务器发出连接请求,源端口为客户端自己选择的一个临时端口,目的端口为服务器在PASV应答命令中指定的临时端口号;
     (4) 服务器响应客户端请求,并继续完成TCP三次握手之后,ftp-data连接建立,开始传送数据。
     接下来我们来看看vsftpd中关于Passive模式中设置语句:
     pasv_enable=yes/no
     pasv_min_port=yes/no
     pasv_max_port=yes/no
     pasv_promiscuous=yes/no
     pasv_address=ip_address
     第一行设置是否启用 pasv 模式。pasv_min_port 和pasv_max_port 是设置在 pasv 模式下开启的端口范围。一般情况下,如果设置成 pasv 模式,我们最好指定端口范围,便于防火墙设置开启这个范围的端口以接受客户端的连接请求。pasv_promiscuous与

port_promiscuous参数一样是设置在pasv下是否设置安全的传输,我们也要将其值设为no(默认值即为no)。pasv_address 后接一个有效的ip地址,来指定pasv打开端口的ip地址。但是默认情况下这行是取消的,因为服务会在 tcp 连接的套接字中知道连接的ip地址。

我们把主配置文件改成这样然后看一下设置效果:
     listen=yes
     anonymous_enable=yes
     pasv_enable=yes
     pasv_min_port=3000
     pasv_max_port=3003

     登录服务器运行3次ls命令,再在服务器端运行netstat命令查看效果:
     # netstat -an
     ……
     tcp 0 0 192.168.0.105:3000 192.168.0.122:11066 TIME_WAIT
     tcp 0 0 192.168.0.105:3002 192.168.0.122:11065 TIME_WAIT
     tcp 0 0 192.168.0.105:3001 192.168.0.122:11063 TIME_WAIT

     我们看到,每次ls命令产生了一个连接,服务器开的端口是3000和3003之间。在 vsftpd2.0.3 以后的版本中, pasv 端口允许我们重复开启,在之前的版本里是不允许的,也就是说同一个端口可以同时与客户端建立多条连接,大家可以自己试验一下。
     大多数人认为在防火墙网络环境中Passive模式比Port模式的问题少,但我们注意到在Passive模式下,客户端向服务器端一个临时的目的端口发起连接,一些防火墙或者设备的访问控制列表(ACL)可能会阻止这种连接;同样服务器的回应也是从一个临时的端口到另

一个临时的端口,防火墙或者访问列表也会阻止这种连接。在许多路由器和防火墙上(包括iptables)允许你使用访问列表关键字"established"来避免第二个问题,"established"关键字告诉路由器允许带ACK标志的包通过。而对于第一个问题,我们虽然使用

pasv_min_port和pasv_max_port语句来限制服务器开设临时端口的范围,从而在防火墙上打开这些端口,但这样做还是存在一定的安全漏洞。好在多数状态检测防火墙例如Linux netfileters支持ftp协议的深层状态检测,进行准确的PASV动态端口过滤。

     五、vsftpd高级操作
     这一节我们介绍一下vsftpd的其它一些知识,其中包括:双模式切换、基于ip的虚拟ftp 站点、基于数据库虚拟用户建立及管理、基于 OpenSSL 的加密数据传输。
    1. vsftpd双模式切换
     前面我们提过,vsftpd 服务是支持在linux下的两种服务模式:独立(standalone)模式和守护进程(xinetd)模式。在standalone模式下,vsftpd进程启动后会一直占用系统资源,当有连接请求时,它会迅速反应;在xinetd模式下,ftp服务是由守护进程统一管理,

当出现ftp连接请求时,守护进程才将ftp服务启动,这种方式最大的优点是没有连接的时候ftp服务不会占用系统资源,处于睡眠状态,但因为要花费时间去唤醒该服务,所以响应时间较长。
    之前做的试验一直是把vsftpd 做在独立模式下,下面我们把它移到守护进程下。注意在工作在守护进程下时,有的参数并不起作用,详细请查阅vsftpd帮助信息(man vsftpd.conf)。
     我们需要在守护进程配置目录/etc/xinetd.d/里建立vsftpd 的守护进程文件。我们在安装时已经将该文件考到/etc/xinetd.d/目录下了。我们稍稍修改其内容:
     #vi /etc/xinetd.d/vsftpd
     service ftp
     {
         disable             = no
         socket_type                = stream
         wait                        = no
         user                        = root
         server                = /usr/local/sbin/vsftpd
         server_args                = /etc/vsftpd/vsftpd.conf
         nice                        = 10
     }
     接下来把配置文件中的listen=yes或listen_ipv6=yes去掉,停掉vsftpd服务,重启xinetd服务:
     # sesrvice vsftpd stop
     # service xinetd restart
     重新启动守护进程后,vsftpd 服务就会让守护进程来管理了。在守护进程管理过程中,我们再修改主配置文件的话,就不需要重新启动服务了。

猜你喜欢

转载自zhangnet1.iteye.com/blog/939818