pureftpd    vsftpd

pureftpd: 实操

<?php
echo "md5".md5("123456"); #得到crypt密码字符串
echo "\n";
echo "cypt".crypt("123456"); #得到crypt密码字符串

#可在mysql提示符下,打开pureftp所用的数据库,执行以下语句,向用户表中添加一条记录(添加一个pureftp用户账号):

#mysql> insert into ftp_users (User,Password,Uid,Gid,Dir,QuotaSize,QuotaFiles,status,create_date) values ("wu2","$1$0it4h/cX$uRT3uVaqb8m9agAPf9LcL1",4000,4000,"/var/ftp/wu2",200,100,0,curdate());
?>

pureftpd实操:        返回

建立基于虚拟用户的FTP服务器,并根据以下要求配置FTP服务器:

1.配置FTP匿名用户的主目录为/var/ftp

2.建立一个名为abc,口令为xyz的FTP账户.设置该账户的文件配额为1000个;磁盘配额为20MB;下载带宽限制为500KB/S。

3.设置FTP服务器同时登录到FTP服务器的最大连接数为100;每个IP最大链接数为3;用户空闲时间限值为5分钟

在FTP客户端连接并测试FTP服务器的上述设置

vsftpd: VSFTPD的文件结构    vsftpd启动模式    实操    站点支持匿名写目录    使站点支持本地用户访问   禁止部分用户访问FTP服务    目录访问控制    提示信息    虚拟用户的配置    PAM    配置安全的匿名访问服务    配置基于IP的虚拟FTP服务器

VSFTPD的文件结构         返回

VSFTPD的文件结构是很简洁的,主要包括:   

/usr/sbin/vsftpd ---- VSFTPD的主程序
/etc/rc.d/init.d/vsftpd ---- 启动脚本   
/etc/vsftpd/vsftpd.conf ---- 主配置文件   
/etc/pam.d/vsftpd ---- PAM认证文件   
/etc/vsftpd.ftpusers ---- 禁止使用VSFTPD的用户列表文件   
/etc/vsftpd.user_list ---- 禁止或允许使用VSFTPD的用户列表文件   
/var/ftp ---- 匿名用户主目录   
/var/ftp/pub ---- 匿名用户的下载目录   
此外,还有一些说明文档和手册文件。
此外VSFTPD的好志文件位于/etc/logrotate.d/vsftpd.log。

vsftpd启动模式            返回

默认的启动模式,也是最常用的模式,可以满足大部分需要。

如果说在RHL9上,您还希望使用Xinetd启动VSFTPD的运行方式,那么首先要将vsftpd.conf配置文件中的listen参数值改为NO。其次,生成一个/etc/xinetd.d/vsftpd文件,内容如下:   

service vsftpd
{   
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/vsftpd
port = 21   
log_on_success += PID HOST DURATION   
log_on_failure += HOST   
}   
通过修改disable值为no或yes,并重新启动xinetd,从而启动或停止VSFTPD

实操            返回

  1. 建立FTP站点,使该站点支持匿名访问,同时设置FTP站点的欢迎消息,匿名登录后,除显示匿名用户主目录外,还有虚拟目录,并且有的目录只提供上传、有的目录只提供下载;
  2. 使该站点支持本地用户访问,并禁止部分用户访问。
  3. 要能通过域名访问ftp站点,并将ftp站点链接到个人站点上。

站点支持匿名写目录            返回

使站点支持本地用户访问            返回

禁止部分用户访问FTP服务            返回

说明:使FTP服务器本地用户中部分能够访问FTP服务器,另外一部分用户不能访问FTP服务器。

1. 编辑vsftpd主配置文件

#vi /etc/vsftpd/vsftpd.conf  

userlist_enable=YES 启用用户列表吗?是

userlist_deny=YES 拒绝用户列表中的用户访问吗?是

userlist_file=/etc/vsftpd.user_list 用户列表文件是/etc/vsftpd.userlist

2. … 编辑用户列表文件

在/etc/vsftpd.user_list中编辑要拒绝用户列表,每个用户占用一行

#vi /etc/vsftpd.user_list

shutdown

Halt

wu2

目录访问控制             返回

提示信息               返回

虚拟用户的配置             返回

   VSFTPD的本地用户本身是系统的用户,除了可以登录FTP服务器外,还可以登录系统使用其他系统资源,而VSFTPD的虚拟用户则是FTP服务的专 用用户,虚拟用户只能访问FTP服务器资源。对于只需要通过FTP对系统有读写权限,而不需要其他系统资源的用户或情况来说,采用虚拟用户方式是很适合 的。VSFTPD的虚拟用户采用单独的用户名/口令保存方式,与系统账号(passwd/shadow)分离,这大大增强了系统的安全 性。VSFTPD可以采用数据库文件来保存用户/口令,如hash;也可以将用户/口令保存在数据库服务器中,如MySQL等。VSFTPD验证虚拟用户,则采用PAM方式。由于虚拟用户的用户名/口令被单独保存,因此在验证时,VSFTPD需要用一个系统用户的身份来读取数据库文件或数据库服务器以完 成验证,这就是guest用户,这正如同匿名用户也需要有一个系统用户ftp一样。当然,guest用户也可以被认为是用于映射虚拟用户。   配置虚拟用户分为几部分:guest用户的创建、用户/口令的保存、PAM认证配置、vsftpd.conf文件设置等。具体的配置方法,参考下面小节。注:在后面的例子中,假定存在虚拟用户xiaotong和xiaowang。

1. 为虚拟用户创建一个系统用户

  在系统中添加vsftpdguest用户,作为虚拟用户在系统中的代表。

  #useradd vsftpdguest

  当虚拟用户登录后,所在的位置为vsftpdguest的主目录/home/vsftpdguest。如果要让虚拟用户登录到/var/ftp等其他目录,修改vsftpdguest的 主目录即可。

2. 配置文件的设置

    在vsftpd.conf配置文件中,加入以下两行参数:   
   

    guest_enable=YES   
    guest_username=vsftpdguest

    上面两行分别表示允许虚拟用户、及虚拟用户映射(对应)的系统用户名称。

    接下来,重新启动vsftpd服务

    #service vsftpd restart

3. 新建MySQL数据库保存虚拟用户

   本节介绍如何将虚拟用户的用户名和口令保存在MySQL的数据库中。这主要分二个部分,一是将用户和口令保存在数据库,二是设置相应的PAM认证。为了 方便论述,做如下假定:数据库vsftpdvu,表users,字段name和passwd用于保存虚拟用户的用户名和口令;为了安全,只授权 vsftpdguest读vsftpdvu数据库的users表。

  1)、虚拟用户的用户名/口令的保存。这部分在MySQL数据库中完成。首先,创建数据库vsftpdvu以及表users,并插入虚拟用户xiaotong、xiaowang。执行以下命令:   

    #mysql -u root -p   
    mysql>create database vu;   
    mysql>use vu;   
    mysql>create table users(name char(16) binary,passwd char(128) binary);   
    mysql>insert into users (name,passwd) values ('xiaotong','qqmywife');   
    mysql>insert into users (name,passwd) values ('xiaowang','ttmywife');
    mysql>insert into users (name,passwd) values ('xiaowu','123456'));
   
  然后,授权vsftpdguest只能读vsftpdvu数据库的users表。执行以下命令:
   
    mysql>grant select on vu.users to honey@localhost identified by '888888';   
    mysql>quit

  如果要验证刚才的操作是否成功可以执行下面命令:   
    #mysql -u honey -p888888 vu   
    mysql>select * from users;   
    如果成功,将会列出xiaotong、xiaowang、xiaowu和他们的密码。

4. 安装PAM认证包

这里我们要用到一个利用mysql进行pam验证的开源项目(http://sourceforge.net/projects/pam-mysql/)。首先从网站下载它的程序包pam_myql-0.5.tar.gz,复制到/root目录中。在编译安装之前,要确保mysql-devel的RPM包已经安装在你的机器上,如果没有请从RHL安装光盘中安装该包。然后,执行以下命令:   

    #tar xvzf pam_mysql-0.7(RC1).tar.gz
   #cd pam_mysql_mysql-0.7(RC1)
    #./configure   
    #make   
    #make install   

    注:make install这一步可能会出现错误,那只好手动将该目录下生成的pam_mysql.o复制到/lib/security目录下。

注:如果在上述操作中,在./configure正常通过,在make时出现错误提示并中止,那么可以试着重新./configure:

./configure --with-openssl

如果你的mysql不是用rhel本身的RPM包安装的,而是通过源代码安装到目录/usr/local/mysql之下的,那么在配置时还要加上如下选项:

./configure --with-openssl --with-mysql=/usr/local/mysql

5. 配置PAM认证文件

接下来,我们要设置vsftpd的PAM验证文件。打开/etc/pam.d/vsftpd文件,加入以下两行内容:    

auth sufficient /usr/lib/security/pam_mysql.so user=honey  passwd=888888 host=localhost db=vu table=users  usercolumn=name passwdcolumn=passwd crypt=0

account sufficient /usr/lib/security/pam_mysql.so  user=honey  passwd=888888 host=localhost db=vu table=users usercolumn=name passwdcolumn=passwd crypt=0

上面涉及到的参数, 只要对应前面数据库的设置就可以明白它们的含义。这里需要说明的是crypt参数,crypt=0,口令以明文方式(不加密)保存在数据库中;crypt =1,口令使用UNIX系统的DES加密方式加密后保存在数据库中;crypt=2,口令经过MySQL的password()函数加密后保存

6.虚拟用户的进一步设置

    1)、虚拟用户的权限配置。

   VSFTPD-1.2.0添加了virtual_use_local_privs参数,当该参数激活(YES)时,虚拟用户使用与本地用户相同的权限。 当此参数关闭(NO)时,虚拟用户使用与匿名用户相同的权限,这也就是VSFTPD-1.2.0之前版本对虚拟用户权限的处理方法。这两者种做法相比,后 者更加严格一些,特别是在有写访问的情形下。默认情况下此参数是关闭的(NO)。下面先介绍virtual_use_local_privs=NO时,即VSFTPD-1.2.0之前版本对虚拟用户权限的配置方法:

      ①控制虚拟用户浏览目录   如果让用户不能浏览目录,但仍可以对文件操作,那么需要执行以下二个步骤:
            A、配置文件中,anon_world_readable_only=YES。
            B、虚拟用户目录的权限改为只能由vsftpdguest操作:   
                # chown vsftpdguest.vsftpdguest /home/vsftpdguest   
                # chmod 700 /home/vsftpdguest   
        ②允许虚拟用户上传文件   write_enable=YES   anon_upload_enable=YES   
        ③允许虚拟用户修改文件名和删除文件   anon_other_write_enable=YES   由于以上选项的设置同样会对匿名用户生效。如果不想匿名用户趁机拥有同样的权限,最好是禁止匿名用户登录。

  在VSFTPD-1.2.0中当virtual_use_local_privs=YES时,只需

    write_enable=YES,虚拟用户就可以就拥有写权限。

    2)、虚拟用户的其他配置

      ①限定虚拟用户在主目录。
        chroot_local_user=NO   
        chroot_list_enable=YES   
        chroot_list_file=/etc/vsftpd.chroot_list   
在/etc/vsftpd.chroot_list文件中加入xiaotong和xiaowang。   或者,chroot_local_user=YES

      ②虚拟用户的个人配置。

  如果想让个别的虚拟用户拥有自己特别的配置,同样可以建立虚拟用户的个人配置文件。在主配置文件中加入:   
    user_config_dir=/etc/vsftpd/vsftpd_user_conf   
    生成/etc/vsftpd/vsftpd_user_conf目录,在该目录下建立与特定虚拟用户同名的文件:   
# mkdir vsftpd_user_conf   
# cd vsftpd_user_conf   
# touch xiaowang   

然后在xiaowang文件中就可以加入专对xiaowang生效的选项设置了。注:如果在个人配置文件中加入chroot_local_user=YES是无效的。

    3)、虚拟用户个人目录设置

  大家可以发现,无论是哪个虚拟用户,登录后所在的目录都是/home/vsftpdguest,即都是guest_username所设置的用户的主目录。下面,介绍如何为每个虚拟用户建立 主目录。一种作法是在虚拟用户的个人配置文件中使用local_root选项指定虚拟用户的主目录。以xiaowang为例,在第上步的基础上,首先/etc/vsftpd/vsftpd_user_conf/xiaowang文件中加入:   
    local_root=/home/xiaowang   
新建xiaowang目录,并将权限设为vsftpdguest:   
    #mkdir xiaowang   
    #chown vsftpdguest.vsftpdguest ./xiaowang

7. 测试

使用xiaotong、xiaowang等用户身份登录ftp服务器,如果登录成功,说明虚拟用户配置成功。

PAM            返回

PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制。它通过提供一些 动态链接库和一套统一的API,将系统提供的服务 和该服务的认证方式分开,使得系统管理 员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于 向系 统中添加新的认证手段。 PAM最初是集成在Solaris中,目前已移植到其它系统中,如Linux、SunOS、HP-UX 9.0等。

一、PAM的结构 PAM的整个框架结构如下图所示:

系统管理员通过PAM配置文件来制定认证策略,即指定什么服务该采用什么样的认证方法;应 用程序开发者通过在服务程序中使用PAM API而实现对认证方法的调用;而PAM服务模块(service module)的开发者则利用PAM SPI(Service Module API)来编写认证模块(主 要是 引出一些函数pam_sm_xxxx( )供libpam调用),将不同的认证机制(比如传统的UNIX认证方 法、Kerberos等)加入到系统中;PAM核 心库(libpam)则读取配置文件,以此为根据将服 务程序和相应的认证方法联系起来。

二、PAM支持的四种管理界面:

1、认证管理(authentication management) 主要是接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密 信息。

2、帐户管理(account management) 主要是检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的 限制等等。

3、密码管理(password management) 主要是用来修改用户的密码。

4、会话管理(session management) 主要是提供对会话的管理和记账(accounting)。

三、PAM的文件:

/usr/lib/libpam.so.* PAM核心库

/etc/pam.conf或者/etc/pam.d/ PAM配置文件

/usr/lib/security/pam_*.so 可动态加载的PAM service module

对于RedHat,其目录不是/usr/lib,而是/lib。

四、PAM的配置:

PAM的配置是通过单个配置文件/etc/pam.conf。RedHat还支持另外一种配置方式,即通过配 置目录/etc/pam.d/,且这种的优先级要高于单个配置文件的方式。

1、使用配置文件/etc/pam.conf

该文件是由如下的行所组成的:

service-name module-type control-flag module-path arguments

service-name 服务的名字,比如telnet、login、ftp等,服务名字“OTHER”代表所有没有 在该文件中明确配置的其它服务。

module-type 模块类型有四种:auth、account、session、password,即对应PAM所支持的 四种管理方式。同一个服务可以调用多个 PAM模块进行认证,这些模块构成一个stack。

control-flag 用来告诉PAM库该如何处理与该服务相关的PAM模块的成功或失败情况。它有四 种可能的 值:required,requisite,sufficient,optional。
    required 表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败结果也不会立即通知用户,而是要等到同一stack 中的所有模块全部执行完毕再将失败结果返回给应用程序。可以认为是一个必要条件。
    requisite 与required类似,该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一stack内的任何模块,而是直接将控制权返回给应用程序。是一个必要条件。注:这种只有RedHat支持,Solaris不支持。
    sufficient 表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack 内的其它模块,但是如果本模块返回失败的话可以 忽略。可以认为是一个充分条件。
    optional表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回值一般被忽略。 对于control-flag,从Linux-PAM-0.63版本起,支持一种新的语法,具体可参看Linux PAM文档。

module-path 用来指明本模块对应的程序文件的路径名,一般采用绝对路径,如果没有给出 绝对路径,默认该文件在目录/usr/lib/security下 面。

arguments 是用来传递给该模块的参数。一般来说每个模块的参数都不相同,可以由该模块 的开发者自己定义,但是也有以下几个共同 的参数:
    debug 该模块应当用syslog( )将调试信息写入到系统日志文件中。 no_warn 表明该模块不应把警告信息发送给应用程序。
    use_first_pass 表明该模块不能提示用户输入密码,而应使用前一个模块从用户那里 得到的密码。
    try_first_pass 表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该密码验证不通过,再提示用户输入新的密码。
    use_mapped_pass 该模块不能提示用户输入密码,而是使用映射过的密码。
    expose_account 允许该模块显示用户的帐号名等信息,一般只能在安全的环境下使用 ,因为泄漏用户名会对安全造成一定程度的威胁。

2、使用配置目录/etc/pam.d/(只适用于RedHat Linux)

该目录下的每个文件的名字对应服务名,例如ftp服务对应文件/etc/pam.d/ftp。如果名为xxxx的服务所对应的配置文件/etc/pam.d/xxxx不存 在,则该服务将使用默认的配置文件/etc/pam.d/other。每个文件由如下格式的文本行所构成: module-type control-flag module-path arguments 每个字段的含义和/etc/pam.conf中的相同。

3、配置的例子

例一:用/etc/pam.conf配置默认的认证方式。 下面的例子将拒绝所有没有在/etc/pam.conf中明确配置的服务。OTHER代表没有明确配置的 其它所有服务,pam_deny模块的作用只是简单地拒绝通过认证。

    OTHER auth required /usr/lib/security/pam_deny.so
    OTHER account required /usr/lib/security/pam_deny.so
    OTHER password required /usr/lib/security/pam_deny.so
    OTHER session required /usr/lib/security/pam_deny.so

例二:通过/etc/pam.d/rsh文件配置rsh服务的认证方式。 rsh服务认证用户时,先使用/etc/hosts.equiv和.rhosts文件的认证方式,然后再根据/etc/nologin文件的存在与否来判断是否允许该用户使用 rsh,最后使用password database来认证用户。

auth required /lib/security/pam_rhosts_auth.so
auth required /lib/security/pam_nologin.so
account required /lib/security/pam_pwdb.so
session required /lib/security/pam_pwdb.so

例三:通过/etc/pam.conf配置ftpd的认证方式。 下面是ftpd服务利用PAM模块进行用户认证的三个步骤。首先用pam_ftp模块检查当前用户是 否为匿名用户,如果是匿名用户,则 sufficient控制标志表明无需再进行后面的认证步骤, 直接通过认证;否则继续使用pam_unix_auth模块来进行标准的unix认证,即用/etc/passwd和/etc/shadow进行认证;通过了pam_unix_auth模块的认证之后,还要继续用pam_listfile模块来检查该用户是否出现在文件/etc/ftpusers中,如果是则该用户被deny掉。

    ftpd auth sufficient /usr/lib/security/pam_ftp.so
    ftpd auth required /usr/lib/security/pam_unix_auth.so use_first_pass
    ftpd auth required /usr/lib/security/pam_listfile.so  onerr=succeed item=user sense=deny file=/etc/ftpusers

五、密码映射(password-mapping)

密码映射允许用户在不同的认证机制下使用不同的密码,其中有一个主密码(primary pass word),其它密码为次密码(secondary passwords,可能有多个)。主密码用来对次密码进行加密。在主密码认证通过后,认证模块利用主密码将加密过的次密码(也称为 mapped password)解密,并对次密码进行认证。 注:如果使用了一次性密码的机制,就不使用密码映射。 所有服务模块必须支持如下4个映射选项(在第四部分已经简单解释过):

1、use_first_pass

这个选项指示本模块不能提示用户输入密码,而是使用已有的密码,即从第一个向用户提示 输入密码的模块那里取得密码,并对该密码进 行认证。

2、try_first_pass

这个选项指示本模块首先尝试使用已有的密码,即从第一个向用户提示输入密码的模块那里 取得密码,并对该密码进行认证。如果密码认 证失败,则再提示用户输入密码。

3、use_mapped_pass

这个选项指示本模块不能向用户提示输入密码,而应使用映射过的密码,即利用主密码将加 密过的次密码解密出来并进行认证。

4、try_mapped_pass

这个选项指示本模块首先尝试使用映射过的密码,即利用主密码将加密过的次密码解密出来 并进行认证。如果密码认证失败,则再提示用 户输入密码。

密码映射的例子:

下面是/etc/pam.conf中关于login服务的配置。这里login共有3种认证机制:Kerberos、UNIX和RSA认证,两个required控制标志表明用户必须通过Kerberos认证和UNIX认证才能使用 login服务,optional选项则说明RSA认证是可选的。首先用户输入主密码进行Kerberos认证 ;use_mapped_pass选项指示UNIX认证模块利用主密码将用于UNIX认证的次密码解密出来并对该次密码进行认证;try_first_pass选项 指示RSA认证模块先使用第一个模块(即Kerberos 模块)的密码作为进行认证的密码,当对该密码认证失败时才提示用户输入用于RSA认证的次密码。

login auth required pam_kerb_auth.so debug
login auth required pam_unix_auth.so use_mapped_pass
login auth optional pam_rsa_auth.so try_first_pass

六、PAM API

1、框架API: 任何一个支持PAM的服务程序在进行认证时必须以pam_start( )开始进行初始化,最后以pam _end( )结束以便进行清理工作。

2、认证管理API: pam_authenticate( )对用户名/密码进行认证。 pam_setcred( )用来修改用户的秘密信息。

3、帐户管理API: pam_acct_mgmt( )检查帐户本身是否有权限登录系统、帐户是否过期、帐户是否有登录时间 限制等。

4、密码管理API: pam_chauthtok( )修改用户的密码。

5、会话管理API: 一个会话以pam_open_session( )开始,最后以pam_close_session( )结束。

6、其它:

    pam_get_item( )、pam_set_item( )用来读写PAM事务(transaction)的状态信息。
    pam_get_data( )、pam_set_data( )用来取得和设置PAM模块及会话的相关信息。
    pam_putenv( )、pam_getenv( )、pam_getenvlist( )用来读写环境变量。
    pam_strerror( )返回相关的错误信息。 例子程序(摘自Sun的白皮书):

下面的例子使用PAM API写了一个简单的login服务程序(注:这不是个完整的程序,所以省 略了对pam_close_session的调用)。

#include <security/pam_appl.h>

/* 回调函数 */ static int login_conv(int num_msg, struct pam_message **msg, struct pam_response **response, void *appdata_ptr); struct pam_conv pam_conv = {login_conv, NULL}; pam_handle_t *pamh; /* 进行认证的PAM句柄 */

void main(int argc, char *argv[], char **renvp)
{
/* 初始化,并提供一个回调函数 */
if ((pam_start("login", user_name, &pam_conv, &pamh)) != PAM_SUCCESS)
login_exit(1);
/* 设置一些参数 */
pam_set_item(pamh, PAM_TTY, ttyn);
pam_set_item(pamh, PAM_RHOST, remote_host);

while (!authenticated && retry < MAX_RETRIES)
{
status = pam_authenticate(pamh, 0); /* 密码认证管理,检查用户输入 的密码是否正确 */
authenticated = (status == PAM_SUCCESS);
}

if (status != PAM_SUCCESS)
{
fprintf(stderr,"error: %s\n", pam_strerror(pamh, status));
/* 显示错误原 因 */
login_exit(1);
}

/* 通过了密码认证之后再调用帐户管理API,检查用户帐号是否已经过期 */
if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
{


if (status == PAM_AUTHTOK_EXPIRED)
{
status = pam_chauthtok(pamh, 0);
/* 过期则要求用户更改密码 */
if (status != PAM_SUCCESS)
login_exit(1);
}

}

/* 通过帐户管理检查之后则打开会话 */

if (status = pam_open_session(pamh, 0) != PAM_SUCCESS) login_exit(status);

/* 设置用户组 */

setgid(pwd->pw_gid);

/* * Initialize the supplementary group access list before * pam_setcred because PAM modules might add groups * during the pam_setcred call */

initgroups(user_name, pwd->pw_gid);

status = pam_setcred(pamh, PAM_ESTABLISH_CRED);

if (status != PAM_SUCCESS) login_exit(status);

/* 设置真实的用户ID(或者有效的用户ID)*/

setuid(pwd->pw_uid);

pam_end(pamh, PAM_SUCCESS);

/* PAM事务的结束 */

/* 此处可用来实现与login有关的其它内容 */

}

/* 出错则清理现场并退出 */

static void login_exit(int exit_code)

{

if (pamh) pam_end(pamh, PAM_ABORT);

exit(exit_code);

}

/* 这个回调函数被PAM认证模块调用以便显示错误信息或者或者用来取得用户输入,采用图形界面的服务程序则应使用图形界面来取得 用户输入或显示提示信息*/

int login_conv(int num_msg, struct pam_message **msg, struct pam_response **resp onse, void *appdata_ptr)
{


while (num_msg--)
{

switch (m->msg_style)
{
case PAM_PROMPT_ECHO_OFF:
r->resp = strdup(getpass(m->msg));
break;
case PAM_PROMPT_ECHO_ON:
(void) fputs(m->msg, stdout);
r->resp = malloc(PAM_MAX_RESP_SIZE);
fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
/* add code here to remove \n from fputs */
break;
case PAM_ERROR_MSG:
(void) fputs(m->msg, stderr);
break;
case PAM_TEXT_INFO:
(void) fputs(m->msg, stdout);
break;
default:
log_error();
break;

}

}

return (PAM_SUCCESS);

}

七、PAM SPI

当服务程序(ftpd、telnetd等)调用PAM API函数pam_xxx( )时,由PAM 框架(libpam)根据该服务在/etc/pam.conf文件中的配置调用指 定的PAM模块中对应的SPI函数pam_sm_xxx( )。如下:

API函数的名字为pam_xxx( ),对应的SPI函数的名字为pam_sm_xxx( ),即每个服务模块需要 引出相应的函数以供libpam调用。为方便对照,再列一下。

API 对应的 SPI

帐号管理 pam_acct_mgmt( ) pam_sm_acct_mgmt( )

认证管理 pam_authenticate( ) pam_ sm_authenticate( )

密码管理 pam_chauthtok( ) pam_ sm_chauthtok( )

会话管理 pam_open_session( ) pam_ sm_open_session( )

会话管理 pam_close_session( ) pam_ sm_close_session( )

认证管理 pam_setcred( ) pam_ sm_setcred( )

八、常用的PAM服务模块

下面是Linux提供的PAM模块列表(只是其中一部分):

模块文件 模块功能描述 相关配置文件

pam_access 提供logdaemon风格的登录控制 /etc/security/access.conf

pam_chroot 提供类似chroot命令的功能

pam_cracklib 对密码的强度进行一定的检查 库文件libcrack和字典文件 /usr/lib/cracklib_dict

pam_deny 总是无条件地使认证失败 pam_env 设置或取消环境变量 /etc/security/pam_env.conf

pam_filter 对输入输出流进行过滤 filters

pam_ftp.so 对匿名ftp用户进行认证

pam_group 当用户在指定的终端上请求指定的 /etc/security/group.conf 服务时赋予该用户相应的组权限

pam_issue 在提示用户输入用户名之前显示 /etc/issue /etc/issue文件的内容 pam_krb4 对用户密码进行Kerberos认证 相应的Kerberos库文件 pam_lastlog 在用户登录成功后显示关于 /var/log/lastlog 用户上次登录的信息,并维护 /var/log/lastlog文件。 pam_limits 限制用户会话所能使用的系统资源 /etc/security/limits.conf

pam_listfile 根据指定的某个文件决定是否 例如/etc/ftpusers 允许或禁止提供服务 pam_mail 检查用户的邮箱中是否有新邮件 /var/spool/mail/xxxx

pam_mkhomedir 为用户建立主目录 /etc/skel/

pam_motd 显示/etc/motd文件的内容 /etc/motd

pam_nologin 根据/etc/nologin文件的存在与否 /etc/nologin 来决定用户认证是否成功 pam_permit 总是无条件地使认证成功

pam_pwdb 作为pam_unix_xxxx模块的一个替代。/etc/pwdb.conf 使用Password Database通用接口 进行认证。 pam_radius 提供远程身份验证拨入用户服务 (RADIUS)的认证

pam_rhosts_auth 利用文件~/.rhosts和 /etc/hosts.equiv和~/.rhosts /etc/hosts.equiv对用户进行认证。 pam_rootok 检查用户是否为超级用户,如果 是超级用户则无条件地通过认证。

pam_securetty 提供标准的Unix securetty检查 /etc/securetty

pam_time 提供基于时间的控制,比如限制 /etc/security/time.conf 用户只能在某个时间段内才能登录 pam_unix 提供标准的Unix认证 /etc/passwd和 /etc/shadow

pam_userdb 利用Berkeley DB数据库来检查 Berkeley DB 用户/密码

pam_warn 利用syslog( )记录一条告警信息

pam_wheel 只允许wheel组的用户有超级用户 的存取权限

配置安全的匿名访问服务        返回

#vi /etc/vsftpd/vsftpd.conf

配置基于IP的虚拟FTP服务器        返回

完成任务的步骤:

1. 配置虚拟IP地址

2. 建立虚拟FTP服务器目录及本地用户

3. 建立虚拟FTP服务器的配置文件

4. 重新启动vsftpd

1. 配置虚拟IP地址

2. 建立虚拟FTP服务器目录及本地用户

3. 建立虚拟FTP服务器的配置文件

4. 重新启动vsftpd

为用户设置不同的访问权限

有时,需要对不同的ftp用户设置不同的访问ftp服务器的权限。 实现的方法就是新建多个用户,使它们具有相同的主目录(该目录也是ftp服务器目录的一个子目录)。 为这些用户设置对它们共同的主目录的访问权限。

FTP两种工作模式:

主动模式(Active FTP)和被动模式(Passive FTP)

在主动模式下,FTP客户端随机开启一个大于1024的端口 N 向服务器的21号端口发起连接,然后开放N+1号端口进行监听,并向服务器发出PORT N+1命令。服务器接收到命令后,会用其本地的FTP数据端口(通常是20)来连接客户端指定的端口N+1,进行数据传输。

在被动模式下,FTP库户端随机开启一个大于1024的端口 N 向服务器的21号端口发起连接,同时会开启N+1号端口。然后向服务器发送PASV命令,通知服务器自己处于被动模式。服务器收到命令后,会开放一个大于1024的端口P进行监听,然后用PORT P命令通知客户端,自己的数据端口是P。客户端收到命令后,会通过N+1号端口连接服务器的端口P,然后在两个端口之间进行数据传输。

总的来说,主动模式的FTP是指服务器主动连接客户端的数据端口,被动模式的FTP是指服务器被动地等待客户端连接自己的数据端口。被动模式的FTP通常用在处于防火墙之后的FTP客户访问外界FTP服务器的情况,因为在这种情况下,防火墙通常配置为不允许外界访问防火墙之后主机,而只允许由防火墙之后的主机发起的连接请求通过。因此,在这种情况下不能使用主动模式的FTP传输,而被动模式的FTP可以良好的工作;

在vsftp配置文件中,与上述两种模相关的配置指令是:

pasv_enable
Set to NO if you want to disallow the PASV method of obtaining a data connection.
Default: YES


pasv_promiscuous
Set to YES if you want to disable the PASV security check that ensures the data connection originates from the same IP address as the control connection. Only enable if you know what you are doing! The only legitimate use for this is in some form of secure tunnelling scheme, or perhaps to facilitate FXP support.
Default: NO


port_enable
Set to NO if you want to disallow the PORT method of obtaining a data connection.
Default: YES


port_promiscuous
Set to YES if you want to disable the PORT security check that ensures that outgoing data connections can only connect to the client. Only enable if you know what you are doing!
Default: NO