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


 

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

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

主動模式的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響應到服務器的數據端口)

被動模式的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響應和數據到客戶端的數據端口)

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

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

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

隨着WWW的廣泛流行,許多人習慣用web瀏覽器作為FTP客戶端。大多數瀏覽器只在訪問ftp://這樣的URL時才支持被動模式。這到底是好還是壞取決於服務器和防火牆的配置。通常情況下會選用被動模式的FTP。

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

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

使用虛擬用戶登錄FTP服務器,可以避免使用操作系統帳號作為FTP用戶帶來的一些安全問題,也便於通過數據庫或其它程序來進行管理。虛擬用戶的特點是只能訪問服務器為其提供的FTP服務,而不能訪問系統的其它資源。所以,如果想讓用戶對FTP服務器站內具有寫權限,但又不允許訪問系統其它資源,可以使用虛擬用戶來提高系統的安全性。

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

三、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上出現文件損壞的情況。

                                                                                                                                            
FTP日常操作命令

ftp> ascii       # 設定以ASCII方式傳送文件(缺省值) 。
ftp> bell        # 每完成一次文件傳送,報警提示。 
ftp> binary      # 設定以二進制方式傳送文件。 
ftp> bye         # 終止主機FTP進程,並退出FTP管理方式。 
ftp> case        # 當為ON時,用MGET命令拷貝的文件名到本地機器中,全部轉換為小寫字母。 
ftp> cd          # 同UNIX的CD命令。 
ftp> cdup        # 返回上一級目錄。(同理:ftp> cd 。。/)
ftp> chmod       # 改變遠端主機的文件權限。 
ftp> close       # 終止遠端的FTP進程,返回到FTP命令狀態, 所有的宏定義都被刪除。 
ftp> delete      # 刪除遠端主機中的文件。 
ftp> dir [remote-directory] [local-file]    # 列出當前遠端主機目錄中的文件。如果有本地文件,就將結果寫至本地文件。 
ftp> get [remote-file] [local-file]         # 從遠端主機中傳送至本地主機中。 
ftp> help [command]                         # 輸出命令的解釋。 
ftp> lcd                                    # 改變當前本地主機的工作目錄,如果缺省,就轉到當前用戶的HOME目錄。 
ftp> ls [remote-directory] [local-file]     # 同DIR。列出當前遠端主機目錄中的文件。如果有本地文件,就將結果寫至本地文件
ftp> macdef                                 # 定義宏命令。 
ftp> mdelete [remote-files]                 # 刪除一批文件。 
ftp> mget [remote-files]                    # 從遠端主機接收一批文件至本地主機。 
ftp> mkdir directory-name                   # 在遠端主機中建立目錄。 
ftp> mput local-files                       # 將本地主機中一批文件傳送至遠端主機。 
ftp> open host [port]                       # 重新建立一個新的連接。 
ftp> prompt                                 # 交互提示模式。 
ftp> put local-file [remote-file]           # 將本地一個文件傳送至遠端主機中。 
ftp> pwd                                    # 列出當前遠端主機目錄。 
ftp> quit                                   # 同BYE。即終止主機FTP進程,並退出FTP管理方式。 
ftp> recv remote-file [local-file]          # 同GET。從遠端主機中傳送至本地主機中。
ftp> rename [from] [to]                     # 改變遠端主機中的文件名。 
ftp> rmdir directory-name                   # 刪除遠端主機中的目錄。 
ftp> send local-file [remote-file]          # 同PUT。將本地一個文件傳送至遠端主機中。
ftp> status                                 # 顯示當前FTP的狀態。 
ftp> system                                 # 顯示遠端主機系統類型。 
ftp> user user-name [password] [account]    # 重新以別的用戶名登錄遠端主機。 
ftp> ? [command]                            # 同HELP。 [command]指定需要幫助的命令名稱。如果沒有指定 command,ftp 將顯示全部命令的列表。
ftp> !                                      # 從 ftp 子系統退出到外殼。 

1)關閉FTP連接
ftp> bye
ftp> exit
ftp> quit

2)下載文件
ftp> get readme.txt  # 下載 readme.txt 文件
ftp> mget *.txt      # 下載

3)上傳文件
ftp> put /path/readme.txt   # 上傳 readme.txt 文件
ftp> mput *.txt             # 可以上傳多個文件

4)狀態碼
•230 - 登錄成功
•200 - 命令執行成功
•150 - 文件狀態正常,開啟數據連接端口
•250 - 目錄切換操作完成
•226 - 關閉數據連接端口,請求的文件操作成功


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM