Linux下FTP虛擬帳號環境部署記錄 (vsftpd)

 

1、FTP協議的兩種工做方式
port方式:主動模式
port(主動)方式的鏈接過程是:客戶端向服務器的FTP端口(默認是21)發送鏈接請求,服務器接受鏈接,創建一條命令鏈路。當須要傳送數據時,服務器從20端口向客戶端的空閒端口發送鏈接請求,創建一條數據鏈路來傳送數據。[即當須要傳送數據時,客戶端在命令鏈路上用PORT命令告訴服務器"我打開了***X端口,你過來鏈接我"。因而服務器從20端口向客戶端的***X端口發送鏈接請求,創建一條數據鏈路來傳送數據。]
pasv方式:被動模式
pasv(被動)方式的鏈接過程是:客戶端向服務器的FTP端口(默認是21)發送鏈接請求,服務器接受鏈接,創建一條命令鏈路。當須要傳送數據時,客戶端向服務器的空閒端口發送鏈接請求,創建一條數據鏈路來傳送數據。[即當須要傳送數據時,服務器在命令鏈路上用PASV命令告訴客戶端"我打開了***X端口,你過來鏈接我"。因而客戶端向服務器的***X端口發送鏈接請求,創建一條數據鏈 路來傳送數據。]node

FTP是僅基於tcp的服務,不支持udp。FTP使用2個端口,一個數據端口和一個命令端口(也可叫作控制端口)。一般來講這兩個端口是21(命令端口)和20(數據端口)。但FTP工做方式的不一樣,數據端口並不老是20,這就是主動與被動FTP的最大不一樣之處。mysql

主動模式的FTP工做流程:客戶端從一個任意的非特權端口N(N>1024)鏈接到FTP服務器的命令端口,也就是21端口。而後客戶端開始監聽端口N+1,併發送FTP命令"portN+1"到FTP服務器。接着服務器會從它本身的數據端口(20)鏈接到客戶端指定的數據端口(N+1)。針對FTP服務器前面的防火牆來講,必須容許如下通信才能支持主動方式FTP:
1)任何大於1024的端口到FTP服務器的21端口。(客戶端初始化的鏈接)
2)FTP服務器的21端口到大於1024的端口。(服務器響應客戶端的控制端口)
3)FTP服務器的20端口到大於1024的端口。(服務器端初始化數據鏈接到客戶端的數據端口)
4)大於1024端口到FTP服務器的20端口(客戶端發送ACK響應到服務器的數據端口)linux

被動模式的FTP工做流程 (有效解決了服務器發起到客戶的鏈接問題) 當客戶端通知服務器它處於被動模式時才啓用。在被動方式FTP中,命令鏈接和數據鏈接都由客戶端發起,這樣就能夠解決從服務器到客戶端的數據端口的入方向鏈接被防火牆過濾掉的問題。當開啓一個FTP鏈接時,客戶端打開兩個任意的非特權本地端口(N>1024和N+1)。第一個端口鏈接服務器的21端口,但與主動方式的FTP不一樣,客戶端不會提交PORT命令並容許服務器來回連它的數據端口,而是提交PASV命令。這樣作的結果是服務器會開啓一個任意的非特權端口(P>1024),併發送PORTP命令給客戶端。而後客戶端發起從本地端口N+1到服務器的端口P的鏈接用來傳送數據。對於服務器端的防火牆來講,必須容許下面的通信才能支持被動方式的FTP:
1)從任何大於1024的端口到服務器的21端口(客戶端初始化的鏈接)
2)服務器的21端口到任何大於1024的端口(服務器響應到客戶端的控制端口的鏈接)
3)從任何大於1024端口到服務器的大於1024端口(客戶端初始化數據鏈接到服務器指定的任意端口)
4)服務器的大於1024端口到遠程的大於1024的端口(服務器發送ACK響應和數據到客戶端的數據端口)web

主動FTP:
命令鏈接:客戶端>1024端口  --> 服務器 21端口
數據鏈接:客戶端>1024端口 <-- 服務器 20端口sql

被動FTP:
命令鏈接:客戶端>1024端口 --> 服務器 21端口
數據鏈接:客戶端>1024端口 --> 服務器>1023端口shell

主動與被動FTP優缺點:
主動FTP對FTP服務器的管理有利,但對客戶端的管理不利。由於FTP服務器企圖與客戶端的高位隨機端口創建鏈接,而這個端口頗有可能被客戶端的防火牆阻塞掉。
被動FTP對FTP客戶端的管理有利,但對服務器端的管理不利。由於客戶端要與服務器端創建兩個鏈接,其中一個連到一個高位隨機端口,而這個端口頗有可能被服務器端的防火牆阻塞掉。數據庫

隨着WWW的普遍流行,許多人習慣用web瀏覽器做爲FTP客戶端。大多數瀏覽器只在訪問ftp://這樣的URL時才支持被動模式。這究竟是好仍是壞取決於服務器和防火牆的配置。一般狀況下會選用被動模式的FTP。apache

2、FTP登陸的用戶類型
FTP的用戶有三種類型:匿名用戶、系統用戶、虛擬用戶
匿名登陸:在登陸FTP時使用默認的用戶名,通常是ftp或anonymous。
本地用戶登陸:使用系統用戶登陸,在/etc/passwd中。
虛擬用戶登陸:這是FTP專有用戶,有兩種方式實現虛擬用戶,本地數據文件和數據庫服務器。vim

FTP虛擬用戶是FTP服務器的專有用戶,使用虛擬用戶帳號能夠提供集中管理的FTP根目錄,方便了管理員的管理,同時將用於FTP登陸的用戶名、密碼與系統用戶帳號區別開,進一步加強了FTP服務器的安全性。某種意義上來講,匿名用戶也是系統用戶,只是系統用戶的一個映射。公開的FTP都不會使用系統用戶做爲FTP賬號,而更多的採用了虛擬用戶,這樣能保證系統的安全性。windows

使用虛擬用戶登陸FTP服務器,能夠避免使用操做系統賬號做爲FTP用戶帶來的一些安全問題,也便於經過數據庫或其它程序來進行管理。虛擬用戶的特色是隻能訪問服務器爲其提供的FTP服務,而不能訪問系統的其它資源。因此,若是想讓用戶對FTP服務器站內具備寫權限,但又不容許訪問系統其它資源,可使用虛擬用戶來提升系統的安全性。

在VSFTP中,認證這些虛擬用戶使用的是單獨的口令庫文件(pam_userdb),由可插入認證模塊(PAM)認證。使用這種方式更加安全,而且配置更加靈活。基本流程:FTP用戶訪問->PAM配置文件(由vsftpd.conf中pam_service_name指定)->PAM論證->區別用戶讀取配置文件(由vsftpd.conf中user_config_dir指定配置文件路徑,文件名即用戶名)。有兩種方式創建FTP的虛擬用戶,分別是:本地數據文件方式、數據庫服務器(MySQL)方式

3、FTP虛擬用戶環境部署記錄
下面記錄在CentOS6版本下采用本地數據文件方式部署FTP虛擬帳號登錄環境的過程及其中遇到的問題:

1)yum安裝vsftpd
[root@i-f658wfj6 ~]# yum install -y vsftpd
[root@i-f658wfj6 ~]# yum install -y db4
          
[root@cms_web vsftpd]# pwd
/etc/vsftpd
          
2)配置vsftpd(將vsftpd.conf文件備份,而後將配置內容直接粘貼下面內容)
[root@cms_web vsftpd]# cat vsftpd.conf|grep -v "^#"
anonymous_enable=NO        # 不容許匿名帳號訪問
local_enable=YES           # 本地用戶能夠訪問(採用虛擬帳號訪問時,這個參數也要開啓(虛擬帳號要寄宿本地帳號),雖然開啓可是本地帳號是不能夠登錄的)
write_enable=YES           # 可寫可上傳。這個參數是全局配置,不然上傳和下載都會報錯550!
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
xferlog_std_format=YES
ascii_upload_enable=YES
ascii_download_enable=YES
ftpd_banner=Welcome to FTP service   # 登錄FTP時顯示的歡迎信息
listen=YES
chroot_local_user=NO           # 限制全部的本地用戶在自家目錄,即用戶登錄系統後鎖定在自家目錄。虛擬主機配置下,在下面兩個chroot配置後,這個參數必須爲NO,不然登錄FTP後還能夠訪問其餘目錄!
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list  # 指定不能離開家目錄的用戶列表文件,一行一個用戶。使用此方法時必須chroot_local_user=NO。說明這個列表裏面的用戶登錄ftp後都只能訪問其主目錄,其餘目錄都不能訪問!
pam_service_name=vsftpd        # 指定PAM配置文件,即下面的/etc/pam.d/vsftpd文件要和這裏指定的一致。
userlist_enable=YES
tcp_wrappers=YES
virtual_use_local_privs=YES    # 這個參數必定要加上,虛擬用戶和本地用戶有相同的權限;不然ftp連上後不能上傳,報錯550權限拒絕!
guest_enable=YES               # 啓用虛擬用戶
guest_username=nobody          # 將虛擬用戶映射爲本地nobody用戶(前提是local_enable=YES)
user_config_dir=/etc/vsftpd/vuser_conf      # 指定不一樣虛擬用戶配置文件的存放路徑
          
connect_from_port_20=YES       # 經過20端口傳輸數據
listen_port=2021               # 監聽的ftp端口
pasv_min_port=40001            # 分配給ftp帳號的最小端口。被動模式下的配置
pasv_max_port=40100            # 分配給ftp帳號的最大端口。每一個帳號分配一個端口,即最大容許100個ftp帳號鏈接。
max_clients=150                # 客戶端的最大鏈接數
accept_timeout=5
connect_timeout=1
max_per_ip=5                   # 每一個ip最大鏈接數
          
=============================================================================================
舒適提示:
上面的ftp是被動模式下的配置,配置後須要在iptables防火牆開通ftp訪問
[root@cms_web vsftpd]# cat /etc/sysconfig/iptables
............
-A INPUT -s 10.68.250.13 -m state --state NEW -m tcp -p tcp --dport 2021 -j ACCEPT
-A INPUT -s 10.68.250.13 -m state --state NEW -m tcp -p tcp --dport 40001:40100 -j ACCEPT
..........
============================================================================================
          
設置登錄ftp的虛擬帳號文件(格式依次是:第一行是帳戶名,次行是該帳號的密碼;即奇數行是帳戶名,偶數行是對應上一行的帳戶密碼)。
這個虛擬帳號是不須要手動建立的,它不是真實存在於系統中的,即/etc/passwd文件裏沒有的,它是藉助於宿主帳號nobody。
[root@cms_web vsftpd]# cat vuser_passwd.txt
hqsbcms
hqsbcms_2016@huanqiu.com
          
生成虛擬用戶口令認證的db文件(該文件設定600權限),這是本地數據庫文件
[root@cms_web vsftpd]# db_load -T -t hash -f /etc/vsftpd/vuser_passwd.txt /etc/vsftpd/vuser_passwd.db
[root@cms_web vsftpd]# chmod 600 /etc/vsftpd/vuser_passwd.db
          
[root@cms_web vsftpd]# cat /etc/vsftpd/chroot_list     # 將虛擬用戶放在這個列表文件裏,說明這些用戶登錄後都只能鎖定到對應主目錄內
hqsbcms
     
[root@cms_web vsftpd]# mkdir vuser_conf                # 此目錄名是在vsftpd.conf配置中指定的,裏面是虛擬用戶配置文件(文件名是虛擬用戶名)
[root@cms_web vsftpd]# cat vuser_conf/hqsbcms
local_root=/hqsb/ftp/          # 指定虛擬帳號登錄後的主目錄,目錄權限要是宿主帳號nobody,這樣就能夠實現帳號映射
write_enable=YES               # 寫權限
anon_umask=022
anon_world_readable_only=NO    # 下載權限(當其餘四項的YES爲NO時,則此帳號登錄FTP後只有可讀和下載權限了)
anon_upload_enable=YES         # 上傳權限
anon_mkdir_write_enable=YES    # 建立目錄權限
anon_other_write_enable=YES    # 刪除和重命名權限
        
[root@bastion-IDC vsftpd]# ll /lib64/security/pam_userdb.so
-rwxr-xr-x. 1 root root 10280 May 11  2016 /lib64/security/pam_userdb.so
[root@cms_web vsftpd]# 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
# 32-bit
#auth required /lib64/security/pam_userdb.so db=/etc/vsftpd/vuser_passwd
#account required /lib64/security/pam_userdb.so db=/etc/vsftpd/vuser_passwd
# 64-bit
auth sufficient /lib64/security/pam_userdb.so db=/etc/vsftpd/vuser_passwd          # 這個vuser_passwd根據的是vuser_passwd.db
account sufficient /lib64/security/pam_userdb.so db=/etc/vsftpd/vuser_passwd       # 這裏64bit系統,必須用sufficient,不然上面vuser_conf目錄下的虛擬主機配置文件無效!
          
[root@bastion-IDC ~]# cat /etc/passwd|grep nobody          # 宿主帳號nobody的信息不用作任何修改,shell類型是否是/sbin/nologin均可以,不影響ftp登錄限制到主目錄下,由於vsfprd裏配置了三個chroot。
nobody:x:99:99:Nobody:/:/sbin/nologin          

[root@cms_web vsftpd]# chown -R nobody.nobody /hqsb/ftp    # 設置虛擬帳號hqsbcms指定的主目錄的權限爲nobody,這樣就能夠映射到宿主帳號nobody
[root@cms_web vsftpd]# chmod -R 700 /hqsb/ftp
          
[root@cms_web vsftpd]# /etc/init.d/vsftpd start
  
[root@bastion-IDC vsftpd]# ll /hqsb/ftp/
total 4
-rwxrwxrwx. 1 nobody nobody    0 Mar 29 12:53 aaa
drwxrwxrwx. 2 nobody nobody 4096 Mar 29 12:53 test

                                                                                                                                                    
vsftpd進程啓動報錯:
starting vsftpd for vsftpd: 500 OOPS: bad bool value in config file for: anonymous_enable

處理辦法:要保證vsftpd.conf文件裏每行的配置後面都不要有空格。
解決:vim編輯/etc/vsftpd/vsftpd.conf文件,在尾行模式下輸入":%s/\s\+$",而後回車便可。

                                                                                                                                                    
vim刪除行首行尾空格和tab的命令以下(非編輯狀態下輸入):
:%s/^\s\+         刪除行首的空格和tab
:%s/\s\+$         刪除行尾的空格和tab

上面兩條命令的解釋:
%s          表示全局搜索
/             爲分隔符。
^            表明行首
\s            表明空格和tab
\+           表明匹配一個或多個
$             匹配行尾
                                                                                                                                                   

問題一在ftp客戶端(好比FileZilla)進行鏈接,發現鏈接失敗,沒法鏈接到服務器!以下(例如*.*.186.5爲上面ftp服務器外網ip)

緣由及解決:因爲上面ftp配置中採用的是被動模式,而客戶端鏈接默認的是主動模式。因此須要手動修改下客戶端的默認配置。修改以下:
依次點擊FileZilla客戶端左上角的"文件"->"站點管理器"->"新建站點"

這樣,就能正常鏈接上FTP服務器了。之後每次鏈接的時候,就依次打開左上角"文件"->"站點管理器"裏以前設置並保存好的站點就行(如上面的185.5-ftp站點)。使用上訴虛擬帳號登錄ftp後,只能登錄到其設置的主目錄/hqsb/ftp下,服務器上的其餘目錄資源都不能訪問!

問題二登錄ftp時出現下面報錯

500 OOPS: cannot change directory:/hqsb/ftp  
Login failed.  
421 Service not available, remote server has closed connection 

解決辦法:一般爲Selinux致使,關閉Selinux便可。

                                                                                                                                                  
須要注意
瀏覽器訪問只支持FTP的被動模式,也就是說只有在FTP配置成被動模式時,才能在遠程瀏覽器裏經過url訪問。好比上面配置後,能夠經過web訪問ftp://111.111.111.115:2021/

                                                                                                                                                               

ftp命令行登陸(ftp或\ftp):
# ftp ip port
# \ftp 111.111.111.115 2021

若是不使用ftp命令,還能夠經過wget命令下載,使用示例以下:
# wget ftp://111.111.111.115:2021/kevin/source_1209-0-1/201801251520-test.tar.gz --ftp-user=kevin --ftp-password=kevin@123

                                                                                                                                                              
FTP數據安全:使用SSL加密傳輸(再也不使用明文傳輸)
按照上面的配置後,FTP鏈接後的數據傳輸嚴格來講是不太安全的,由於是使用明文傳輸。以下截圖,客戶端鏈接過程當中會提示「不安全的服務器,...」

這種狀況下,咱們可使用SSL加密傳輸,配置過程以下:

[root@bastion-IDC ~]# mkdir /etc/vsftpd/sslkey
[root@bastion-IDC ~]# cd /etc/vsftpd/sslkey
[root@bastion-IDC sslkey]# openssl req -new -x509 -nodes -out vsftpd.pem -keyout vsftpd.pem
Generating a 2048 bit RSA private key
.........................................................................................+++
...................................+++
writing new private key to 'vsftpd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:huanqiu
Organizational Unit Name (eg, section) []:technology
Common Name (eg, your name or your server's hostname) []:huanqiu
Email Address []:wangshibo@huanqiu.cn

[root@bastion-IDC sslkey]# ls
vsftpd.pem
 
[root@bastion-IDC sslkey]# vim /etc/vsftpd/vsftpd.conf    //在文件最底部添加下面幾行
ssl_enable=YES
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1=YES
ssl_ciphers=HIGH
require_ssl_reuse=NO
force_local_logins_ssl=YES
force_local_data_ssl=YES
rsa_cert_file=/etc/vsftpd/sslkey/vsftpd.pem

[root@bastion-IDC sslkey]# /etc/init.d/vsftpd restart
Shutting down vsftpd:                                      [  OK  ]
Starting vsftpd for vsftpd:                                [  OK  ]

而後再次在客戶端鏈接FTP(注意FTP客戶端配置中的加密類型中要支持"FTP over TLS"),發現就就會創建TLS安裝鏈接了。(鏈接中,會出現是否信任證書的提示,信任便可)

注意:FTP作了SSL加密傳輸後,ftp命令將不能再登錄,FTP瀏覽器方式訪問也會受阻。需使用支持SSL的客戶端來驗證vsftp,這裏還能夠推薦使用flashFXP客戶端,以下:

若是flashFXP客戶端很差用的話,能夠採用lftp工具進行登錄:

# yum install -y lftp
# lftp ip -u username -p 2021

注意:lftp命令能夠支持ssl加密方式的鏈接,ftp命令不支持ssl加密方式的鏈接。
若是遠程客戶機lftp登陸進去操做報錯"Fatal error: Certificate verification: Not trusted"
[root@kevin ~]# lftp 172.16.60.214 -u myftp -p 20021
Password:
lftp myftp@172.16.60.214:~> ls     
ls: Fatal error: Certificate verification: Not trusted
  
[root@kevin ~]# cp /etc/lftp.conf /etc/lftp.conf.bak
[root@kevin ~]# vim /etc/lftp.conf
set ssl:verify-certificate no           #在文本最後添加
  
而後就能夠正常登陸並操做了
[root@kevin ~]# lftp 172.16.60.214 -u myftp -p 20021
Password:
lftp myftp@172.16.60.214:~> ls     
drwxr-xr-x    5 500      500          4096 Aug 27 02:54 OPS
drwxr-xr-x    4 500      500          4096 Jun 18 08:19 DEV
drwxr-xr-x    3 500      500          4096 Mar 29 02:24 XDCF

登錄後執行ls,若是出現一直請求鏈接的狀況,多數是由於pasv的端口範圍在防火牆上沒有配置。ftp協議數據傳輸和命令傳輸是不一樣的端口,這個例子下要開40001~40100端口。

                                                                                                                                                             
添加FTP虛擬帳號

好比添加帳號ops(密碼爲ops@123),指定目錄爲/mnt/ops,操做以下:
[root@bastion-IDC vsftpd]# pwd
/etc/vsftpd
[root@bastion-IDC vsftpd]# cat chroot_list
hqsbcms
ops

[root@bastion-IDC vsftpd]# cat vuser_passwd.txt
hqsbcms
hqsbcms_2016@huanqiu.com
ops
ops@123

[root@bastion-IDC vsftpd]# db_load -T -t hash -f /etc/vsftpd/vuser_passwd.txt /etc/vsftpd/vuser_passwd.db

[root@bastion-IDC vsftpd]# cat vuser_conf/ops
local_root=/mnt/ops/
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES

[root@bastion-IDC vsftpd]# chown -R nobody.nobody /mnt/ops
[root@bastion-IDC vsftpd]# chmod -R 777 /mnt/ops

照此操做就能夠添加FTP虛擬帳號了,每一個虛擬帳號能夠對應一個主目錄,而且限定到只能ftp訪問該主目錄
====================================================================================

若是想讓虛擬帳號ops權限爲只讀以及只能下載(沒有上傳、刪除、重命名、建立文件目錄等寫權限),那麼它的配置修改以下:
[root@bastion-IDC vsftpd]# cat vuser_conf/ops
local_root=/mnt/ops/
write_enable=NO
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO

                                                                                                                                                              
自動添加FTP虛擬帳號的腳本

下面腳本可用於自動添加vsftp虛擬帳號,腳本中的kevin帳號是已經存在的vsftp虛擬帳號,用這個kevin帳號配置拷貝給新帳號,而後再更新配置。

[root@localhost ~]# vim /opt/scripts/AddVirtualFtpUser.sh
#! /bin/sh
#-----------------------------------------------
# Usage:
#        Add a new virtual user for FTP
# Example:
#        AddVirtualFtpUser.sh Syscode(Capital letter) password
#-----------------------------------------------
 
SysCode=$1
Password=$2
 
FTP_User_DB_TXT="/etc/vsftpd/vuser_passwd.txt"
FTP_User_DB="/etc/vsftpd/vuser_passwd.db"
FTP_User_List="/etc/vsftpd/chroot_list"
Virtual_User_Dir="/etc/vsftpd/vuser_conf"
 
if [ $# -ne 2 ];then
        echo "[Error]: Please input correct parameters."
        echo "[Example]: AddVirtualFtpUser.sh kevin password"
        exit 1
fi
 
SysCode=`echo ${SysCode} | tr '[a-z]' '[A-Z]'`
 
echo ${SysCode} >> ${FTP_User_DB_TXT}
echo ${Password} >> ${FTP_User_DB_TXT}
echo ${SysCode} >> ${FTP_User_List}
 
UpdateDB=`db_load -T -t hash -f ${FTP_User_DB_TXT}  ${FTP_User_DB} 2>&1`
if [ $? -ne 0 ];then
   echo ${UpdateDB}
   exit 1
fi

#用以前的虛擬帳號kevin的配置拷貝到新帳號下,而後替換更新
cp "${Virtual_User_Dir}/kevin" "${Virtual_User_Dir}/${SysCode}"
sed -i "s/kevin/${SysCode}/g" "${Virtual_User_Dir}/${SysCode}"
if [ $? -eq 0 ];then
   echo "Success | 0"
else
   echo "Failed | 1"
fi

授予腳本執行權限
[root@localhost ~]# chmod 755 /opt/scripts/AddVirtualFtpUser.sh

好比相加新ftp帳號rubao,密碼爲rubao@123,作法:
[root@localhost ~]# sh /opt/scripts/AddVirtualFtpUser.sh rubao rubao@123

                                                                                                                                                              
Haproxy代理層配置上面Ftp虛擬帳號登錄環境的訪問
下面配置表示本機haproxy的2021端口代理到10.68.250.198(這是後端的ftp服務器)的2021端口(ftp服務端口)。本機的iptables防火牆裏開放2021和40001:40100;而10.68.250.198機器的2021和40001:40100端口要對haproxy代理機開放。

Haproxy配置方法一

[root@mysql-master ~]# cat /etc/haproxy/haproxy.cfg
.......

listen ftp_198 0.0.0.0:2021
mode tcp
option tcplog
balance roundrobin
server 10.68.250.198 10.68.250.198 check port 2021 inter 10s rise 1 fall 2

listen ftp_date_198 0.0.0.0:40001-40100
mode tcp
option tcplog
balance roundrobin
server 10.68.250.198 10.68.250.198 check port 2021 inter 10s rise 1 fall 2

Haproxy配置方法二

[root@mysql-master ~]# cat /etc/haproxy/haproxy.cfg
.......
frontend ftp_198 0.0.0.0:2021                       
   mode tcp
   bind *:2021
   default_backend ftp_server
frontend ftp_date_198 0.0.0.0:40001-40100
   mode tcp
   bind *:40001-40100
   default_backend ftp_server_data
backend ftp_server
   mode tcp
   server ftp 10.68.250.198 check port 2021 inter 10s rise 1 fall 2
backend ftp_server_data
   mode tcp
   server ftp 10.68.250.198 check port 2021 inter 10s rise 1 fall 2

                                                                                                                                                         
附上vsftpd配置參數

################################## 基本設定 #########################################
#接受匿名用戶
anonymous_enable=YES

#匿名用戶login時不詢問口令
no_anon_password=YES

#匿名用戶主目錄
anon_root=(none)

#接受本地用戶
local_enable=YES

#本地用戶主目錄
local_root=(none)

#若是匿名用戶須要密碼,那麼使用banned_email_file裏面的電子郵件地址的用戶不能登陸
deny_email_enable=YES

#僅在沒有pam驗證版本時有用,是否檢查用戶有一個有效的shell來登陸
check_shell=YES

#若啓用此選項,userlist_deny選項才被啓動
userlist_enable=YES

#若爲YES,則userlist_file中的用戶將不能登陸,爲NO則只有userlist_file的用戶能夠登陸
userlist_deny=NO

#若是和chroot_local_user一塊兒開啓,那麼用戶鎖定的目錄來自/etc/passwd每一個用戶指定的目錄(這個不是很清楚,很哪位熟悉的指點一下)
passwd_chroot_enable=NO

#定義匿名登入的使用者名稱。默認值爲ftp。
ftp_username=FTP

################################### 用戶權限控制 ####################################
#能夠上傳(全局控制).
write_enable=YES

#本地用戶上傳文件的umask
local_umask=022

#上傳文件的權限配合umask使用
#file_open_mode=0666

#匿名用戶能夠上傳
anon_upload_enable=NO

#匿名用戶能夠建目錄
anon_mkdir_write_enable=NO

匿名用戶其它的寫權利(更改權限?)
anon_other_write_enable=NO

若是設爲YES,匿名登入者會被容許下載可閱讀的檔案。默認值爲YES。
anon_world_readable_only=YES

#若是開啓,那麼全部非匿名登錄的用戶名都會被切換成guest_username指定的用戶名
#guest_enable=NO

全部匿名上傳的文件的所屬用戶將會被更改爲chown_username
chown_uploads=YES

匿名上傳文件所屬用戶名
chown_username=lightwiter

#若是啓動這項功能,則全部列在chroot_list_file之中的使用者不能更改根目錄
chroot_list_enable=YES

#容許使用"async ABOR"命令,通常不用,容易出問題
async_abor_enable=YES

管控是否可用ASCII 模式上傳。默認值爲NO。
ascii_upload_enable=YES

#管控是否可用ASCII 模式下載。默認值爲NO。
ascii_download_enable=YES

#這個選項必須指定一個空的數據夾且任何登入者都不能有寫入的權限,當vsftpd 不須要file system 的權限時,就會將使用者限制在此數據夾中。默認值爲/usr/share/empty
secure_chroot_dir=/usr/share/empty

############################### 超時設置 ###############################
#空閒鏈接超時
idle_session_timeout=600

#數據傳輸超時
data_connection_timeout=120

#P***S請求超時
ACCEPT_TIMEOUT=60

#PROT模式鏈接超時
connect_timeout=60

############################### 服務器功能選項 #############################
#開啓日記功能
xferlog_enable=YES

#使用標準格式
xferlog_std_format=YES

#當xferlog_std_format關閉且本選項開啓時,記錄全部ftp請求和回覆,當調試比較有用.
#log_ftp_protocol=NO

#容許使用pasv模式
pasv_enable=YES

#關閉安全檢查,當心呀.
#pasv_promiscuous=NO

#容許使用port模式
#port_enable=YES

#關閉安全檢查
#prot_promiscuous

#開啓tcp_wrappers支持
tcp_wrappers=YES

#定義PAM 所使用的名稱,預設爲vsftpd。
pam_service_name=vsftpd

#當服務器運行於最底層時使用的用戶名
nopriv_user=nobody

#使vsftpd在pasv命令回覆時跳轉到指定的IP地址.(服務器聯接跳轉?)
pasv_address=(none)

########################### 服務器性能選項 ###########################
#是否能使用ls -R命令以防止浪費大量的服務器資源。是否容許遞歸查詢。默認爲關閉,以防止遠程用戶形成過量的I/O
ls_recurse_enable=YES

#是否使用單進程模式。這個設定項目比較危險一點~當設定爲YES時,表示每一個創建的連線都會擁有一支process在負責,能夠增長vsftpd的效能。
#不過,除非您的系統比較安全,並且硬體配備比較高,不然容易耗盡系統資源喔!通常建議設定爲NO的啦!
one_process_model=NO

#綁定到listen_port指定的端口,既然都綁定了也就是每時都開着的,就是那個什麼standalone模式
listen=YES

#當使用者登入後使用ls -al 之類的指令查詢該檔案的管理權時,預設會出現擁有者的UID,而不是該檔案擁有者的名稱。
#如果但願出現擁有者的名稱,則將此功能開啓。
text_userdb_names=NO

#顯示目錄清單時是用本地時間仍是GMT時間,能夠經過mdtm命令來達到同樣的效果
use_localtime=NO

#測試平臺優化
#use_sendfile=YES 

########################### 信息類設置  ############################
login時顯示歡迎信息.若是設置了banner_file則此設置無效
ftpd_banner="歡迎登陸kevin的ftp服務"

#容許爲目錄配置顯示信息,顯示每一個目錄下面的message_file文件的內容
dirmessage_enable=YES

#顯示會話狀態信息
#setproctitle_enable=YES

############################ 文件定義 #############################
#定義不能更改用戶主目錄的文件
chroot_list_file=/etc/vsftpd/vsftpd.chroot_list

#定義限制/容許用戶登陸的文件
userlist_file=/etc/vsftpd/vsftpd.user_list

#定義登陸信息文件的位置
banner_file=/etc/vsftpd/banner

#禁止使用的匿名用戶登錄時做爲密碼的電子郵件地址
#若是deny_email_enable=YES時,能夠利用這個設定項目來規定哪一個email address不可登入咱們的vsftpd喔!在上面設定的檔案內,一行輸入一個email address便可!
banned_email_file=/etc/vsftpd.banned_emails

#日誌文件位置
xferlog_file=/var/log/vsftpd.log

#目錄信息文件
#當進入一個新目錄的時候,會查找這個文件並顯示文件裏的內容給遠程用戶。dirmessage_enable需啓用。默認值:.message 
message_file=.message

########################### 目錄定義 #############################
#定義用戶配置文件的目錄
user_config_dir=/etc/vsftpd/userconf

#定義本地用戶登錄的根目錄,注意定義根目錄能夠是相對路徑也能夠是絕對路徑
相對路徑是針對用戶家目錄來講的
local_root=webdisk

#此項設置每一個用戶登錄後其根目錄爲/home/username/webdisk#匿名用戶登錄後的根目錄
anon_root=/var/ftp 

########################## 用戶鏈接選項 ##########################
#可接受的最大client數目
max_clients=100

#每一個ip的最大client數目
max_per_ip=5

#使用標準的20端口來鏈接ftp
connect_from_port_20=YES

#綁定到某個IP,其它IP不能訪問
listen_address=192.168.0.2

#綁定到某個端口
listen_port=2121

#數據傳輸端口
ftp_data_port=2020

#pasv鏈接模式時可使用port 範圍的上界,0 表示任意。默認值爲0。
pasv_max_port=100010

#pasv鏈接模式時可使用port 範圍的下界,0 表示任意。默認值爲0。
pasv_min_port=100050

######################### 數據傳輸選項 ##########################
#匿名用戶的傳輸比率(b/s)
# 這個設定值後面接的數值單位爲bytes/秒,限制anonymous的傳輸速度,若是是0則不限制(由最大頻寬所限制),
# 若是您想讓anonymous僅有30 KB/s的速度,能夠設定『anon_max_rate=30000』
anon_max_rate=51200

#本地用戶的傳輸比率(b/s)
local_max_rate=5120000

#限制anonymous的權限!若是是077則anonymous傳送過來的檔案權限會是-rw
anon_umask=077


重點注意的細節
=============================================================================================================
1》限制vsftpd最大鏈接數和傳輸速率
在FTP服務器的管理中,不管對本地用戶仍是匿名用戶,對於FTP服務器資源的使用都須要進行控控制,避免因爲負擔過大形成FTP服務器運行異常,
能夠添加如下配置項對FTP客戶機使用FTP服務器資源進行控制:

max_client設置項 
用於設置FTP服務器所容許的最大客戶端鏈接數,值爲0時表示不限制。
例如max_client=100表示FTP服務器的全部客戶端最大鏈接數不超過100個。

max_per_ip設置項 
用於設置對於同一IP地址容許的最大客戶端鏈接數,值爲0時表示不限制。
例如max_per_ip=5表示同一IP地址的FTP客戶機與FTP服務器創建的最大鏈接數不超過5個。

local_max_rate設置項 
用於設置本地用戶的最大傳輸速率,單位爲B/s,值爲0時表示不限制。
例如local_max_rate=500000表示FTP服務器的本地用戶最大傳輸速率設置爲500KB/s.

anon_max_rate設置項 
用於設置匿名用戶的最大傳輸速率,單位爲B/s,值爲0表示不限制。
例如ano_max_rate=200000,表示FTP服務器的匿名用戶最大傳輸速率設置爲200KB/s.

=============================================================================================================
2》指定用戶的權限設置

vsftpd.user_list文件須要與vsftpd.conf文件中的配置項結合來實現對於vsftpd.user_list文件中指定用戶帳號的訪問控制:

a)設置禁止登陸的用戶帳號
當vsftpd.conf配置文件中包括如下設置時,vsftpd.user_list文件中的用戶帳號被禁止進行FTP登陸:
userlist_enable=YES
userlist_deny=YES 

userlist_enable設置項設置使用vsftpd.user_list文件,userlist_deny設置爲YES表示vsftpd.user_list文件用於設置禁止的用戶帳號。

b)設置只容許登陸的用戶帳號
當vsftpd.conf配置文件中包括如下設置時,只有vsftpd.user_list文件中的用戶帳號可以進行FTP登陸:
userlist_enable=YES
userlist_deny=NO 


userlist_enable設置項設置使用vsftpd.user_list文件,
userlist _deny設置爲NO表示vsftpd.usre_list文件用於設置只容許登陸的用戶帳號,文件中未包括的用戶帳號被禁止FTP登陸。

userlist_deny和userlist_enable選項限制用戶登陸FTP服務器

注意:使用userlist_deny選項和user_list文件一塊兒能有效阻止root,apache,www等系統用戶登陸FTP服務器,從而保證FTP服務器的分級安全性。

如下是兩個選項的具體表現形式和兩種搭配使用方式的效果:
Userlist_enable=YES   表示:Ftpusers中用戶容許訪問;User_list中用戶容許訪問
Userlist_enable=NO    表示:Ftpusers中用戶禁止訪問;User_list中用戶容許訪問
Userlist_deny=YES     表示:Ftpusers中用戶禁止訪問(登陸時能夠看到密碼輸入提示,但仍沒法訪問);User_list 中用戶禁止訪問
Userlist_deny=NO      表示:Ftpusers中用戶禁止訪問;User_list中用戶容許訪問

Userlist_enable=YES 而且 Userlist_deny=YES  表示:Ftpusers中用戶禁止訪問;User_list中用戶禁止訪問(登陸時不會出現密碼提示,直接被服務器拒絕)
Userlist_enable=YES 而且 Userlist_deny=NO   表示:Ftpusers中用戶禁止訪問;User_list中用戶容許訪問

                                                                                                                                                         
FTP/LFTP在Shell腳本中的用法

1)從FTP上批量下載文件到本地
[root@Kevin test]# pwd
/tmp/test
[root@Kevin test]# ls
ftp.sh  test.file
  
[root@Kevin test]# cat ftp.sh
#!/bin/sh
ftp -v -n 192.168.10.10 20021 << EOF       # ip,port
user kevinftp ftp1@3$                      # user後面跟的是ftp鏈接的用戶名和密碼
binary                                     # 文件傳輸類型
cd IFS/Pay/iOS/                            # cd是登陸到遠程ftp後的路徑(在ftp根目錄下的cd切換)
lcd /tmp/test/                             # lcd是在本地主機目錄操做的命令
prompt                                     # 取消交互
mget *                                     # mget是批量的下載文件,*表示下載當前ftp目錄下的全部文件,能夠是一個或多個文件,中間使用空格隔開。
bye
EOF                                      
echo "download from ftp successfully"
  
2)從本地向FTP批量上傳文件
[root@Kevin test]# cat ftp.sh
#!/bin/sh
ftp -v -n 192.168.10.10 20021 << EOF  
user kevinftp ftp1@3$
binary
cd IFS/Pay/iOS/             
lcd /tmp/test/                             # 也可使用"lcd ./"表示在本地當前目錄下                          
prompt
mput test.file ftp.sh                      # mput是批量上傳的文件,能夠是一個或多個文件,中間用空格隔開。也可使用*表示上傳本地當前目錄下的全部文件。
bye
EOF                                      
echo "upload to ftp successfully"
  
=====================================================================================
lftp在shell中的用法(去掉交互) (ftp登陸的用戶名是kevinftp,密碼是ftp1@3$)
 
[root@Kevin ~]# lftp 192.168.10.10 -u kevinftp -p 20021
Password:
lftp kevinftp@192.168.10.10:~> ls     
drwxr-xr-x    5 500      500          4096 Aug 27 02:54 BOBO
drwxr-xr-x    4 500      500          4096 Jun 18 08:19 GRACE
drwxrwxr-x    4 500      500          4096 Aug 27 03:18 RUBAO
drwxr-xr-x    3 500      500          4096 Mar 29 02:24 XIAOAN
drwxr-xr-x    3 500      500          4096 Mar 28 11:45 HEHUO
  
lftp在命令行裏非交互模式直接登陸使用
[root@Kevin ~]# lftp -c "open 192.168.10.10.20021 ;user kevinftp ftp1@3$;ls;"               
drwxr-xr-x    5 500      500          4096 Aug 27 02:54 BOBO
drwxr-xr-x    4 500      500          4096 Jun 18 08:19 GRACE
drwxrwxr-x    4 500      500          4096 Aug 27 03:18 RUBAO
drwxr-xr-x    3 500      500          4096 Mar 29 02:24 XIAOAN
drwxr-xr-x    3 500      500          4096 Mar 28 11:45 HEHUO
  
上傳a.log和a.txt文件(put)
[root@Kevin ~]# lftp -c "open 192.168.10.10.20021 ;user kevinftp ftp1@3$;put a.log;put a.txt;" >/dev/null 2>&1
[root@Kevin ~]# lftp -c "open 192.168.10.10.20021 ;user kevinftp ftp1@3$;ls;"
drwxr-xr-x    5 500      500          4096 Aug 27 02:54 BOBO
drwxr-xr-x    4 500      500          4096 Jun 18 08:19 GRACE
drwxrwxr-x    4 500      500          4096 Aug 27 03:18 RUBAO
-rw-r--r--    1 500      500        231498 Aug 30 10:28 a.log
-rw-r--r--    1 500      500           906 Aug 30 10:28 a.txt
drwxr-xr-x    3 500      500          4096 Mar 29 02:24 XIAOAN
drwxr-xr-x    3 500      500          4096 Mar 28 11:45 HEHUO
  
刪除(rm)(注意:ftp登陸後的刪除命令是delete,lftp登陸後的刪除命令是rm)
[root@Kevin ~]# lftp -c "open 192.168.10.10.20021 ;user kevinftp ftp1@3$;rm -f a.log;rm -f a.txt;" >/dev/null 2>&1            
[root@Kevin ~]# lftp -c "open 192.168.10.10.20021 ;user kevinftp ftp1@3$;ls;"
drwxr-xr-x    5 500      500          4096 Aug 27 02:54 BOBO
drwxr-xr-x    4 500      500          4096 Jun 18 08:19 GRACE
drwxrwxr-x    4 500      500          4096 Aug 27 03:18 RUBAO
drwxr-xr-x    3 500      500          4096 Mar 29 02:24 XIAOAN
drwxr-xr-x    3 500      500          4096 Mar 28 11:45 HEHUO
  
下載(get)
[root@Kevin ~]# lftp -c "open 192.168.10.10.20021 ;user kevinftp ftp1@3$;get a.log;get a.txt;" >/dev/null 2>&1

                                                                                                                                                                         
FTP登陸後操做出現227錯誤

部署了FTP的PASV的被動模式,遠程客戶機鏈接ftp後進行操做,一直出現227錯誤,以下:

[root@Kevin ~]# ftp 192.168.10.10 20021
Connected to 192.168.10.10 (192.168.10.10).
220 Welcome to aiops FTPs service.PLS use Passive mode.
Name (192.168.10.10:root): mpsftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). 
就一直卡在這裏了.......

這裏就要分析下FTP的兩種工做模式,PORT主動模式和PASV被動模式 (文章開頭已經詳細介紹了)
參考並嘗試網上解決辦法都很差使,最後無奈將被動模式改成主動模式,並將ftp端口給位默認的21端口,問題得已解決。

須要修改的配置以下:
[root@Kevin ~]# cat /etc/vsftpd/vsftpd.conf
........
#修改FTP監聽端口
#listen_port=20021
listen_port=21

#使用被動模式,指定數據端口及安全檢查(被動模式配置都註釋了)
#pasv_enable=YES
#pasv_min_port=40001
#pasv_max_port=40100
#pasv_promiscuous=NO
#max_clients=150
#accept_timeout=5
#connect_timeout=1
#max_per_ip=5

最後重啓ftp服務
[root@Kevin ~]# /etc/init.d/vsftpd restart

再次鏈接ftp進行操做就能夠了(默認鏈接的就是21端口)
[root@Kevin ~]# ftp 192.168.10.10
Connected to 192.168.10.10 (192.168.10.10).
220 Welcome to aiops FTPs service.PLS use Passive mode.
Name (192.168.10.10:root): mpsftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode   (10,4,87,254,216,234).
150 Here comes the directory listing.
drwxr-xr-x    5 500      500          4096 Aug 27 02:54 BOBO
drwxr-xr-x    4 500      500          4096 Jun 18 08:19 GRACE
drwxrwxr-x    4 500      500          4096 Aug 27 03:18 RUBAO
drwxr-xr-x    3 500      500          4096 Mar 29 02:24 XIAOAN
drwxr-xr-x    3 500      500          4096 Mar 28 11:45 HEHUO
226 Directory send OK.
ftp>

                                                                                                                                            
FTP上傳文件先後大小改變
1)對比文件上傳先後的MD5值("md5sum filename"),MD5值不同,則文件確定是有變化的了。
2) "\ftp ip port"登陸ftp後,在使用put/get命令進行上傳/下載操做前,先輸入"binary",即將傳輸模式設爲二進制(默認是ASCII方式傳輸),這樣能夠防止windows下的文件傳到linux上出現文件損壞的狀況。

相關文章
相關標籤/搜索