vsftpd是在Linux一個較安全的ftp服務,在使用中,發現具備如下特色:mysql
l 支持chrootlinux
l ftp帳號和local user帳號映射機制sql
l 與客戶鏈接的子進程使用低權限帳號運行shell
l 有最大用戶量限制、每用戶鏈接數限制,匿名帳號速率控制數據庫
在安裝測試中發現一些vsftpd獨特的運行機制和概念,在此列舉解釋:安全
一、配置文件,默認的vsftpd配置文件是/etc/vsftpd.conf。若是須要指定另外的路徑,那麼須要在啓動vsftpd時以參數形式指定,如:bash
#/usr/local/sbin/vsftpd /etc/my_vsftpd.conf服務器 |
二、ftp帳號session
1) anonymous user,登錄名爲anonymous、ftp。匿名帳號在登錄到vsftpd後,vsftpd將匿名帳號映射成一個local user,默認是ftp,可在配置文件中指定。async
2) Local user,即linux本機帳號,出於安全考慮,默認的配置文件中,是不容許local user登錄的。
3) Virtual user,虛擬帳號,虛擬帳號和匿名帳號相似,啓用虛擬帳號機制後,用戶使用非匿名帳號都被視爲虛擬帳號,虛擬帳號登錄後,vsftpd將他們映射成一個local user,默認也是ftp,能夠在配置文件中指定。
4) 鏈接子進程帳號,vsftpd爲了防止意外攻擊攻破後,黑客獲得高權限的帳號,因此全部的鏈接子進程都是用一個低權限的帳號運行。默認是nobody,能夠經過配置文件修改。
三、帳號映射
帳號映射的目的在於便於管理,由於svftpd自己是沒有帳號管理機制的。它藉助linux系統自身的帳號管理、權限系統。
匿名用戶、虛擬用戶登錄vsftpd後,其用戶的文件訪問權限被映射到相應的linux帳號(local user)上。
則使用獨立的、低權限的local user實現映射有助於安全。
四、Chroot
l Anonymous user、virtual user、local user登錄後,vsftpd會使用chroot把這些用戶鎖在特定的目錄裏面,防止他們訪問其餘目錄。
l Anonymous user默認狀況下映射到local user後,會chroot到該local user的home目錄下。在配置文件中能夠經過anon_root參數再chroot到該參數指定的目錄。
l local user登錄後,會進入該帳號的home目錄,但若是不經過配置文件強制chroot的話,該帳號能夠轉到其餘目錄(父目錄)。chroot_local_user=YES能夠實現強制chroot
l virtual user須要vsftpd啓動local user支持,並指定guest_enable參數。當啓用virtual user後,全部非anonymous user登錄都被視爲virtual user。對virtual user帳號的管理,vsftpd經常使用的方式是pam_db或者pam_mysql。
這次安裝方案採用vsftpd+pam_mysql進行virtual user驗證,在redhat enterprise 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 |
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命令檢查帳號vsftpd、ftp、anoftp是否存在,如果存在,能夠考慮使用另外的名稱替換他們,或者使用usermod命令對這些帳號的home、shell進行修改。
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訪問
pam_mysql使用源碼編譯形式,須要系統安裝有pam-devel和mysql。
1. 檢查、安裝pam-devel
2. 下載編譯pam_mysql
到http://pam-mysql.sourceforge.net/下載最新的pam-mysql。
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控制文件
使用mysql的password()函數進行密碼加密。更多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,登錄後強制chroot到local_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
# 對於匿名用戶,登錄後強制chroot到anon_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_mysql和vsftpd都有日誌選項,尤爲是pam_mysql,啓用日誌選項後能夠看到更多詳細的信息,方便調試。如下是監控日誌的一種方法:
#tail –f /var/log/message /var/log/vsftpd.log |
#!/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 |