使用pam_mysql和VSFTPD实现ftp虚拟账号

来源:互联网 发布:银行家算法避免死锁 编辑:程序博客网 时间:2024/04/30 01:06

一、vsftpd特点                                                 

vsftpd是在Linux一个较安全的ftp服务,在使用中,发现具有以下特点:

l       支持chroot

l       ftp账号和local user账号映射机制

l       与客户连接的子进程使用低权限账号运行

l       有最大用户量限制、每用户连接数限制,匿名账号速率控制

 

在安装测试中发现一些vsftpd独特的运行机制和概念,在此列举解释:

1、配置文件,默认的vsftpd配置文件是/etc/vsftpd.conf。如果需要指定另外的路径,那么需要在启动vsftpd时以参数形式指定,如:

#/usr/local/sbin/vsftpd /etc/my_vsftpd.conf

 

2、ftp账号

1)       anonymoususer,登陆名为anonymousftp。匿名账号在登陆到vsftpd后,vsftpd将匿名账号映射成一个localuser,默认是ftp,可在配置文件中指定。

2)       Localuser,即linux本机账号,出于安全考虑,默认的配置文件中,是不允许local user登陆的。

3)       Virtualuser,虚拟账号,虚拟账号和匿名账号类似,启用虚拟账号机制后,用户使用非匿名账号都被视为虚拟账号,虚拟账号登陆后,vsftpd将他们映射成一个localuser,默认也是ftp,可以在配置文件中指定。

4)       连接子进程账号,vsftpd为了防止意外攻击攻破后,黑客得到高权限的账号,所以所有的连接子进程都是用一个低权限的账号运行。默认是nobody,可以通过配置文件修改。

3、账号映射

账号映射的目的在于便于管理,因为svftpd本身是没有账号管理机制的。它借助linux系统自身的账号管理、权限系统。

匿名用户、虚拟用户登陆vsftpd后,其用户的文件访问权限被映射到相应的linux账号(local user)上。

则使用独立的、低权限的local user实现映射有助于安全。

4、Chroot

l       Anonymoususervirtual userlocal user登陆后,vsftpd会使用chroot把这些用户锁在特定的目录里面,防止他们访问其他目录。

l       Anonymoususer默认情况下映射到local user后,会chroot到该local userhome目录下。在配置文件中可以通过anon_root参数再chroot到该参数指定的目录。

l       localuser登陆后,会进入该账号的home目录,但如果不通过配置文件强制chroot的话,该账号可以转到其他目录(父目录)chroot_local_user=YES可以实现强制chroot

l       virtualuser需要vsftpd启动localuser支持,并指定guest_enable参数。当启用virtualuser后,所有非anonymous user登陆都被视为virtual user。对virtualuser账号的管理,vsftpd常用的方式是pam_db或者pam_mysql


 

二、vsftpd安装                                                 

此次安装方案采用vsftpd+pam_mysql进行virtual user验证,在redhatenterprise 4下测试。以下是一些配置定义:

 

1 vsftpd用户

用户

说明

vsftpd子进程用户

vsftpd(默认是nobody,由于使用nobody的进程太多,所以独立使用另外的用户)

Anonymous user所映射的local user

anoftp

Virtual user 所映射的local user

ftp

 

2 路径定义

路径定义

说明

/opt/vsftpd/users

Virtual user (ftp)home目录

/opt/vsftpd/empty

vsftpd用户的home目录

/opt/vsftpd/users/pub

Anonymous user (anoftp)home目录

/etc/vsftpd.conf

vsftpd配置文件

/etc/pam.d/ftp.vsftpd

Pam认证配置文件

/var/log/vsftpd.log

vsftpd日志文件

 

 

 

3 vsftpd数据库定义

定义

说明

Mysql主机地址

127.0.0.1

Mysql主机端口

3306

vsftpd认证数据库名称

vsftpd

vsftpd数据库连接账号

vsftpd

vsftpd数据库连接密码

vsftpd

认证信息表

users(name,passwd,stat)

认证log

LoginLog

 

2.1 vsftpd安装                                                                  

1.       路径准备

[root@rac1 opt]# mkdir  -p /opt/vsftpd/users

[root@rac1 opt]# mkdir  -p /opt/vsftpd/users/pub

[root@rac1 opt]# mkdir  -p /opt/vsftpd/empty

 

2.       检查账号

使用finger命令检查账号vsftpdftpanoftp是否存在,若是存在,可以考虑使用另外的名称替换他们,或者使用usermod命令对这些账号的homeshell进行修改。

 

3.       建立、修改账号

# groupadd vsftpd

# useradd vsftpd -d /opt/vsftpd/empty -s /sbin/nologin -g vsftpd

# usermod  -d /opt/vsftpd/users ftp

# groupadd anoftp

# useradd anoftp -d /opt/vsftpd/users/pub -s /sbin/nologin -g anoftp

# touch  /opt/vsftpd/users/pub/hello_anonymous.txt

 

4.       下载编译vsftpd

http://vsftpd.beasts.org/下载最新的vsftpd源码包。

 

# tar xzf vsftpd-2.1.0.tar.gz

# cd vsftpd-2.1.0

# make && make install

# cp vsftpd.conf /etc/

# echo "ftp_username=anoftp" >>/etc/vsftpd.conf

 

vsftpd 将会被安装到/user/local/sbin/vsftpd,默认只允许anonymous用户登陆。


 

5.       测试vsftpd

直接在终端上执行vsftpd命令

再到另一个终端上使用ftp访问

2.2 pam_mysql安装                                                          

pam_mysql使用源码编译形式,需要系统安装有pam-develmysql

1.       检查、安装pam-devel

2.       下载编译pam_mysql

http://pam-mysql.sourceforge.net/下载最新的pam-mysql

注意:若是系统安装有cyrus-sasl-devel,似乎当前版本(pam-mysql 0.7RC1)在使用MD5加密时会有问题,即使指定了—with-openssl参数

 

2.3 pam_mysql vsftpd联调                                         

1.       以管理员身份登陆mysql,执行以下sql脚本

create database vsftpd;

use vsftpd;

grant select,insert on vsftpd.* to vsftpd@127.0.0.1 IDENTIFIED BY 'vsftpd';

 

CREATE TABLE `loginLog` (                                                         

            `id` int(10) unsigned NOT NULL auto_increment,                                 

            `userName` varchar(50) default NULL COMMENT '用户登陆名',                 

            `message` varchar(100) default NULL COMMENT '登陆pam认证信息',           

            `pid` int(10) unsigned default NULL COMMENT '使用pam认证的进程id',      

            `host` varchar(20) default NULL,                                               

            `rhost` varchar(20) default NULL,                                               

            `logtime` timestamp NOT NULL COMMENT '记录时间', 

            UNIQUE KEY `id` (`id`)                                                         

          ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

 

CREATE TABLE `users` (                

          `name` varchar(50) default NULL,   

          `passwd` varchar(64) default NULL, 

          `stat` smallint(6) default '0'     

        ) ENGINE=MyISAM DEFAULT CHARSET=utf8  ;

 

insert into users values ('vftp',password('vftp'),0);

 


 

2.       建立pam控制文件

使用mysqlpassword()函数进行密码加密。更多pam_mysql参数请查看pam_mysql源码包中的README文件。

cat >/etc/pam.d/ftp.vsftpd <<EOF

auth       required      /usr/lib/security/pam_mysql.so   user=vsftpd passwd=vsftpd  host=127.0.0.1 db=vsftpd table=users usercolumn=name passwdcolumn=passwd statcolumn=stat crypt=mysql sqllog=true logtable=loginLog logmsgcolumn=message logusercolumn=userName logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=logtime verbose=1

 

account    required      /usr/lib/security/pam_mysql.so   user=vsftpd passwd=vsftpd  host=127.0.0.1 db=vsftpd table=users usercolumn=name passwdcolumn=passwd statcolumn=stat crypt=mysql sqllog=true logtable=loginLog logmsgcolumn=message logusercolumn=userName logpidcolumn=pid loghostcolumn=host logrhostcolumn=rhost logtimecolumn=logtime verbose=1

 

EOF

 

3.       编辑/etc/vsftpd.conf配置文件

vsftpd源码包中有个EXAMPLE目录,里面提供了很多配置的例子,很值得参考。

# 使用vsftp自己的日记记录器,如果开启syslog_enable,则使用syslog

dual_log_enable=YES

# syslog_enable=YES

 

# 用户连接到vsftpd后,会创建独立的进程,nopriv_user指定进程的运行者

# 选择一个独立、低权限的账号有助于安全

nopriv_user=vsftpd

 

# 使用pam做用户认证,配置文件在/etc/pam.d/ftp.vsftpd

pam_service_name=ftp.vsftpd

 

# 对于local user,登陆后强制chrootlocal_root指定的目录,注意单独指定local_root 还是不够的

# local_root只能让用户登陆后进入这个目录,但是用户还是可以切换到其他目录,导致不安全

chroot_local_user=YES

local_root=/opt/vsftpd/users

ftpd_banner=Welcome to toybox FTP service.

 

# 允许匿名用户访问,匿名用户会被映射成一个local user

# ftp_username参数指定,默认是账号是ftp

ftp_username=anoftp

anonymous_enable=YES

 

# 对于匿名用户,登陆后强制chrootanon_root指定的目录

anon_root=/opt/vsftpd/users/pub

# anon_mkdir_write_enable=YES

# anon_other_write_enable=YES

# anon_upload_enable=YES

anon_world_readable_only=YES

 

# 允许使用local user账号登陆(使用virtual user模式必须启用)

local_enable=YES

 

# 将所有的非匿名用户都映射到guest user(使用virtual user模式必须启用)

# 注意guest user是一个local user, 由参数guest_username 指定

guest_enable=YES

guest_username=ftp

 

# 允许写操作,但匿名用户的权限还得由另外其他参数具体指定

# virtual_use_local_privs 参数指定virtual user是否具有local user的权限

write_enable=YES

virtual_use_local_privs=YES

 

 

# 其他设置

async_abor_enable=YES

 

# Performance

max_clients=20

max_per_ip=4

 

# 每个连接单进程模式,如果vsftp需要处理大量的用户,可以使用这个模式

# 但是这会降低安全,因为默认情况下每个连接使用两个进程处理

# one_process_model=YES

 

# 用户在idle_session_timeout内没有输入ftp命令,则进入空闲超时

idle_session_timeout=120

# 如果在data_connection_timeout内没有数据传输,则进入超时

data_connection_timeout=300

 

# 使用被动模式(PASV)时,等待用户连接的时间

accept_timeout=60

# 使用主动模式(PORT)时,服务器连接等待时间

connect_timeout=60

# 匿名用户最大传送速率

# anon_max_rate=50000

 

4.       测试vsftpd

直接在终端上执行vsftpd命令

再到另一个终端上使用ftp访问

5.       关于调试

Syslog的日志会打在/var/log/message

vsftpd专属日志会打在/var/log/vsftpd.log

注意pam_mysqlvsftpd都有日志选项,尤其是pam_mysql,启用日志选项后可以看到更多详细的信息,方便调试。以下是监控日志的一种方法:

#tail –f /var/log/message /var/log/vsftpd.log

 

三、vsftpd服务自启动脚本                           

#!/bin/bash

#

#       /etc/rc.d/init.d/vsftpd

#

# Starts the vsftpd daemon

#

# chkconfig: 345 95 5

# description: Runs commands scheduled by the vsftpd command vsftpd the time /

#    specified when vsftpd was run, and runs batch commands when the load /

#    average is low enough.

# processname: vsftpd

 

RETVAL=0

prog=/usr/local/sbin/vsftpd

lockfile=/var/lock/subsys/vsftpd

 

test -x $prog || exit 0

# source function library

. /etc/rc.d/init.d/functions

 

start() {

    # Start daemons.

    if [ -n "`/sbin/pidof $prog`" ]; then

            echo -n $"$prog :already running"

            success

            echo

            return 0

    fi

    echo

    echo -n $"Starting $prog: "

 

    $prog &

    RETVAL=$?

    [ "$RETVAL" = 0 ] && success || failure

    [ "$RETVAL" = 0 ] && touch $lockfile

    echo

}

 

stop() {

 

    if [ -n "`/sbin/pidof $prog`" ] ; then

        echo -n "Shutting down $prog"

        killproc "$prog"

        RETVAL=$?

        [ "$RETVAL" = 0 ] && rm -f $lockfile

        [ "$RETVAL" = 0 ] && success

        echo

       else

           echo $"$prog no running!"

       fi

    echo

 

}

 

check_status() {

        echo -n "Checking Daemon "

        status $prog

              RETVAL=$?

        echo

}

restart() {

       stop

       start

}

 

# See how we were called.

case "$1" in

  start)

       start

       ;;

  stop)

       stop

       ;;

  status)

       check_status

       ;;

  restart|reload)

       restart

       ;;

  *)

       echo "Usage: $0 {start|stop|status|restart|reload}"

       exit 1

esac

exit $RETVAL

 

 

原创粉丝点击