Very Secure FTP Daemon

出自 Arch Linux 中文维基

vsftpd (「Very Secure FTP Daemon「) 是一個為 UNIX 類系統開發的輕量,穩定和安全的 FTP 伺服器端。

安裝[編輯 | 編輯原始碼]

安裝 vsftpd 然後 啟動/啟用 vsftpd.service 守護程序。

使用 xinetd 監視和控制 vsftpd 連接,請參見 #使用 xinetd

配置[編輯 | 編輯原始碼]

vsftpd 的大多數配置都可以通過編輯 /etc/vsftpd.conf 文件實現。 該文件本身自帶大量注釋說明,所以這一章節只就一些重要的配置予以說明。有關所有可用選項和文檔,請參閱 vsftpd.conf(5) 手冊頁。默認情況下,由 /srv/ftp 提供文件。

允許的連接 /etc/hosts.allow

# 允许所有连接
vsftpd: ALL
# IP 地址范围
vsftpd: 10.0.0.0/255.255.255.0

允許上傳[編輯 | 編輯原始碼]

需要將 /etc/vsftpd.conf 中的 write_enable 值設為 YES,以便允許修改文件系統(如上傳):

write_enable=YES

本地用戶登錄[編輯 | 編輯原始碼]

需要修改 /etc/vsftpd.conf 中的如下值,以便允許 /etc/passwd 中的用戶登錄:

local_enable=YES

匿名用戶登錄[編輯 | 編輯原始碼]

以下行控制匿名用戶是否可以登錄。默認情況下,匿名登錄只能從 /srv/ftp 下載:

/etc/vsftpd.conf
...
# 允許匿名 FTP? (當心 - 默認情況下允許除非您將其注釋)。
anonymous_enable=YES
...
# 取消注釋以允許匿名 FTP 用戶上傳文件。
# 只有上述全局寫入被激活,才會有效果。
# 另外,你顯然需要創建 FTP 用戶有寫權限的目錄。
# anon_upload_enable=YES
#
# 如果您希望匿名 FTP 用戶能夠創建新目錄,請取消注釋。
# anon_mkdir_write_enable=YES
...

您也可以添加以下選項(詳見 vsftpd.conf(5)):

/etc/vsftpd.conf
# 匿名登錄不需要密碼
no_anon_password=YES

# 匿名客戶端的最大傳輸速率(以 Bytes/秒 為單位)
anon_max_rate=30000

# 用於匿名登錄的目錄
anon_root=/example/directory/

Chroot 限制[編輯 | 編輯原始碼]

為了阻止用戶離開家目錄,可以設置 chroot 環境。要啟用此功能,請在 /etc/vsftpd.conf 中添加以下行:

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list

chroot_list_file 定義了被 chroot 限制的用戶列表。

對於更嚴格的環境,請指定以下行:

chroot_local_user=YES

這將默認為所有用戶啟用 chroot 環境。 在這種情況下,chroot_list_file 定義了不受 chroot 限制的用戶列表。

限制用戶登錄[編輯 | 編輯原始碼]

可以通過在 /etc/vsftpd.conf 中添加以下兩行來阻止特定用戶登錄FTP伺服器:

userlist_enable=YES
userlist_file=/etc/vsftpd.user_list

userlist_file 文件列出不允許登錄的用戶。

如果您只想允許特定的用戶登錄,請添加以下行:

userlist_deny=NO

此時 userlist_file 文件指定允許登錄的用戶。

限制連接數[編輯 | 編輯原始碼]

可以通過在 /etc/vsftpd.conf 中添加如下信息來限制本地用戶的數據傳輸速率:

local_max_rate=1000000 # 最大数据传输速率(单位: Bytes/秒)
max_clients=50 # 可以同时连接的最大客户端数
max_per_ip=2 # 每个 IP 允许的最大连接数

使用 xinetd[編輯 | 編輯原始碼]

Xinetd 提供增強的監控和控制連接功能。對於基本的可以工作的 vsftpd-server 是不必要的

安裝 vsftpd 將會添加必要的服務文件 /etc/xinetd.d/vsftpd,默認情況下,服務被禁用。

啟用ftp服務:

service ftp
{
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/vsftpd
        log_on_success  += HOST DURATION
        log_on_failure  += HOST
        disable                 = no
}

如果您將 vsftpd 守護程序設置為以獨立模式運行,而不是啟動 vsftpd 守護程序和 啟用 xinetd.service,請在 /etc/vsftpd.conf 中進行以下更改:

listen=NO

否則連接將失敗:

500 OOPS: could not bind listening IPv4 socket

使用 SSL/TLS 來保護 FTP[編輯 | 編輯原始碼]

本文或本章節的語言、語法或風格需要改進。參考:Help:Style

原因:Do not duplicate OpenSSL#Certificates.(在Talk:Very Secure FTP Daemon討論)

首先,您需要一個 X.509 SSL/TLS 證書才能使用TLS。如果您沒有,可以輕鬆生成如下的自簽名證書:

# cd /etc/ssl/certs
# openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout vsftpd.pem -out vsftpd.pem
# chmod 600 vsftpd.pem

你會被問到關於你公司的問題,等等。由於你的證書不是一個可信任的,所填的內容並不重要,它只會被用於加密。要使用可信證書,您可以從 Let's Encrypt 這樣的證書頒發機構獲得證書。

然後,編輯配置文件:

/etc/vsftpd.conf
ssl_enable=YES

# 如果你接受匿名連接你可能要啟用這個設置
# allow_anon_ssl=NO

# 默認情況下所有非匿名登錄被迫使用 SSL 發送和接收密碼和數據,設置為 NO,以允許不安全的連接
force_local_logins_ssl=NO
force_local_data_ssl=NO

# 選擇你想要的
force_local_logins_ssl=YES

# TLS v1 協議連接是首選,默認情況下啟用此模式,而禁用 SSL v2 和 v3 時,以下設置是默認設置,不需要更改,除非您特別需要 SSL
# ssl_tlsv1=YES
# ssl_sslv2=NO
# ssl_sslv3=NO
# 提供您的證書和私鑰注釋的路徑,它們可以包含在同一個文件中或不同的文件中
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
rsa_private_key_file=/etc/ssl/certs/vsftpd.pem

# 此設置默認設置為 YES,並要求所有數據連接都顯示會話重用,這證明他們知道控制通道的秘密。這種方式更安全,但不受許多 FTP 客戶端的支持,為了更好的兼容性而設置為 NO
require_ssl_reuse=NO

在被動模式下解析主機名[編輯 | 編輯原始碼]

要覆蓋 vsftpd 在被動模式下通過伺服器的主機名發布的 IP 地址,並在啟動時解析 DNS,在 /etc/vsftpd.conf 中增加以下兩行:

pasv_addr_resolve=YES
pasv_address=yourdomain.org
注意:
  • 對於動態DNS,定期更新 pasv_address 並重新啟動伺服器是不必要的,因為它有時可以被讀取。
  • 您可能無法通過 LAN 以被動模式連接,在這種情況下,請嘗試使用主動模式而不是LAN客戶端。

埠配置[編輯 | 編輯原始碼]

可能需要調整默認FTP偵聽埠和被動模式數據埠:

  • 對於暴露於 Web 的 FTP 伺服器,為了減少伺服器受到攻擊的可能性,可以將偵聽埠改為除標準埠 21 以外的埠。
  • 要限制被動模式將打開的埠,可以提供一個範圍。

這些埠配置更改可以使用以下幾行完成:

/etc/vsftpd.conf
listen_port=2211
pasv_min_port=5000
pasv_max_port=5003

配置 iptables[編輯 | 編輯原始碼]

通常,運行FTP守護進程的伺服器受 iptables 防火牆的保護。要允許訪問FTP伺服器,需要打開相應的埠,如:

# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

本文不會提供有關如何設置iptables的任何說明,但這裡是一個例子:Simple stateful firewall

有一些內核模塊需要在這裡引用的 iptables 正確的處理 FTP 連接。 其中特別是 nf_conntrack_ftp。這是需要的,因為 FTP 使用給定的 listen_port(默認為21) 僅用於命令,所有的數據傳輸都是通過不同的埠完成的。這些埠由 FTP 守護程序為每個會話隨機選擇(也取決於是使用主動還是被動模式)。要告訴 iptables 應該接受埠上的數據包,需要 nf_conntrack_ftp。要在啟動時自動加載,請在 /etc/modules-load.d 中創建新文件,例如:

# echo nf_conntrack_ftp > /etc/modules-load.d/nf_conntrack_ftp.conf

如果內核 >= 4.7,您需要通過 sysctl 設置 net.netfilter.nf_conntrack_helper = 1,如:

# echo net.netfilter.nf_conntrack_helper=1 > /etc/sysctl.d/70-conntrack.conf

或使用

# iptables -A PREROUTING -t raw -p tcp --dport 21 -j CT --helper ftp

小技巧[編輯 | 編輯原始碼]

虛擬用戶的 PAM 認證[編輯 | 編輯原始碼]

由於 PAM 不再提供 pam_userdb.so 另一個簡單的方法是使用 libpam_pwdfileAUR。但是,本節僅限於解釋如何通過 pam_pwdfile.so 配置 chroot 環境和身份驗證。

在此示例中,我們創建目錄 vsftpd

# mkdir /etc/vsftpd

創建和存儲用戶名和密碼的一個選擇是使用 Apache 的生成器 htpasswd:

# htpasswd -c /etc/vsftpd/.passwd

上述命令的一個問題是 vsftpd 可能無法讀取生成的 MD5 散列密碼。如果使用 -d 開關運行相同的命令,則使用 crypt() 加密,vsftpd 的密碼變得可讀,但其缺點是安全性較低,密碼限制為8個字符。 Openssl 可用於使用算法1生成基於 MD5 的 BSD 密碼:

# openssl passwd -1

無論那個解決方案 /etc/vsftpd/.passwd 應該如下所示:

username1:hashed_password1
username2:hashed_password2
...

接下來,您需要使用 pam_pwdfile.so 和生成的 /etc/vsftpd/.passwd 文件創建 PAM 服務。在本例中,我們為 vsftpd 創建了一個 PAM 策略,其中包含以下內容:

/etc/pam.d/vsftpd
auth required pam_pwdfile.so pwdfile /etc/vsftpd/.passwd
account required pam_permit.so

現在是為虛擬用戶創建一個 home 的時候了。在示例中,決定用 /srv/ftp 為虛擬用戶託管數據,這也反映了 Arch 的默認目錄結構。首先創建 virtual 用戶並使 /srv/ftp 成為它的 home:

# useradd -d /srv/ftp virtual

讓 virtual 成為所有者

# chown virtual:virtual /srv/ftp

一個基本的沒有私人文件夾配置的 /etc/vsftpd,默認的虛擬用戶的 home 文件夾:

# 指向正确的 PAM 服务文件
pam_service_name=vsftpd
write_enable=YES
hide_ids=YES
listen=YES
connect_from_port_20=YES
anonymous_enable=NO
local_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
chroot_local_user=YES
guest_enable=YES
guest_username=virtual
virtual_use_local_privs=YES

您自己的設置可能不需要一些參數。如果您希望 chroot 環境可寫,您將需要將以下內容添加到配置文件中:

allow_writeable_chroot = YES

否則 vsftpd 的默認安全設置會抱怨,如果它檢測到 chroot 是可寫的。

Start vsftpd.service

您現在應該可以使用存儲在 /etc/vsftpd/.passwd 中的任何用戶和密碼從FTP客戶端登錄。

為虛擬用戶創建私有目錄[編輯 | 編輯原始碼]

首先創建用戶文件夾

# mkdir /srv/ftp/user1
# mkdir /srv/ftp/user2
# chown virtual:virtual /srv/ftp/user?/

隨後, 在 /etc/vsftpd.conf 增加如下行:

local_root=/srv/ftp/$USER
user_sub_token=$USER

問題解決[編輯 | 編輯原始碼]

vsftpd: Error 500 with kernel 4.18+[編輯 | 編輯原始碼]

seccomp 在 vsftpd 中默認激活,這導致某些內核版本出現兼容性問題。這已經修復了,你可以在 Red Hat Bugzilla#845980 中看到,但在較新的內核中仍然可能導致問題。

如果在列出目錄時遇到故障,將其添加到 /etc/vsftpd.conf

seccomp_sandbox=NO

vsftpd: refusing to run with writable root inside chroot()[編輯 | 編輯原始碼]

從 vsftpd 2.3.5 開始,用戶被鎖定的 chroot 目錄不可寫。這是為了防止安全漏洞。

允許上傳的安全方法是保持 chroot 啟用,並配置您的 FTP 目錄。

local_root=/srv/ftp/user
# mkdir -p /srv/ftp/user/upload
#
# chmod 550 /srv/ftp/user
# chmod 750 /srv/ftp/user/upload

如果你必須這麼做:

您可以將其放入您的 /etc/vsftpd.conf 以解決此安全性增強(自vsftpd 3.0.0;來自 Fixing 500 OOPS: vsftpd: refusing to run with writable root inside chroot ()):

allow_writeable_chroot=YES

FileZilla Client: GnuTLS error -8 -15 -110 when connecting via SSL[編輯 | 編輯原始碼]

vsftpd 嘗試在 SSL 會話中顯示純文本錯誤消息。為了進行調試,暫時禁用加密,您將看到正確的錯誤消息。[1] [2]

Often these errors can be solved by adding[3]: seccomp_sandbox=NO

vsftpd.service fails to run on boot[編輯 | 編輯原始碼]

如果您啟用了 vsftpd.service,並且無法在啟動時運行,請確保它已在服務文件中設置為在 network.target 之後加載:

/usr/lib/systemd/system/vsftpd.service
[Unit]
Description=vsftpd daemon
After=network.target

Passive mode replies with the local IP address to a remote connection[編輯 | 編輯原始碼]

如果 vsftpd 將本地地址返回給遠程連接,如:

227 Entering Passive Mode (192,168,0,19,192,27).

It may be that the FTP server is behind a NAT router and while some devices monitor FTP connections and dynamically replace the IP address specification for packets containing the PASV response, some do not. 可能是 FTP 伺服器位於 NAT 路由器後面,而有些設備會監視 FTP 連接並動態替換包含 PASV 響應的數據包的 IP 地址規範,但有些設備卻不會。

使用以下命令在 vsftpd 配置中指示外部IP位址:

 pasv_address=externalIPaddress

或者可選地:

pasv_addr_resolve=YES
pasv_address=my.domain.name

如果在更改後無法進行內部連接,則可能需要運行 2 個 vsftpd,一個用於內部連接,一個用於外部連接。

提示:要找出 NAT 路由器是否攔截 PASV 響應並用外部 IP 替換內部 IP,可以在 TLS 模式下檢查客戶端的伺服器響應。加密的數據包不能被路由器識別並且未被修改。

ipv6 only fails with: 500 OOPS: run two copies of vsftpd for IPv4 and IPv6[編輯 | 編輯原始碼]

你很有可能已經注釋了這一行

# When "listen" directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
#listen=YES
#
# This directive enables listening on IPv6 sockets. To listen on IPv4 and IPv6
# sockets, you must run two copies of vsftpd with two configuration files.
# Make sure, that one of the listen options is commented !!
listen_ipv6=YES

而不是設置

# When "listen" directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
listen=NO

vsftpd 連接在使用 nis 的機器上失敗: yp_bind_client_create_v2: RPC: Unable to send[編輯 | 編輯原始碼]

as mentioned on the vsftpd faq page, "...built-in sandboxing uses network isolation on Linux. This may be interfering with any module that needs to use the network to perform operations or lookups" 正如在 vsftpd fap 頁面上提到的那樣,「...內置沙盒使用 linux 上的網絡隔離可能會干擾任何需要使用網絡執行操作或查找的模塊」

將這個未公開的行添加到你的 /etc/vsftpd.conf

isolate_network=NO

更多資源[編輯 | 編輯原始碼]