架個 FTP 伺服器-vsftpd
緣起
筆者最原先安裝 wordpress 時,一開頭 wordpress 便是顯示中文的,且 wordpress 能完成下載外掛或外觀主題而不需再透過 ftp server 來上傳到本地端。但後來使用 virtualbox 做架站全記錄,wordpress 的安裝卻跑出英文界面,且本地端需架有 ftp server 讓 wordpress 能上傳外掛到本地端。因此,筆者揣度後,決定要裝 ftp server 。又接著。。。筆者花了相當多的時間搞 ftp server 後,終於也了解到上述問題的原因為何了。因此,總結,會安裝 vsftp server 。不過,它不僅將無助於 wordpress 的使用,還會造成問題筆者尚無法解決(其實裝它只是備而不用,但有備無患)。也會在之後安裝 wordpress 的文章中交待上述問題的成因與解決。
安排
ftp server 所管理的使用者,與本地端系統上的使用者無異。只差別在從 ftp 登入的使用者僅能使用有限的命令,其主要是操作檔案的上傳下載或其相關。以及限制只有哪些本地端的使用者才能使用此服務。因此,為有別於系統內的使用者,我們通常會創建新的使用者,開放給有上傳下載檔案需求的對象。例如 wordpress 需從線上下載外掛上傳到我們的系統內以進行安裝,我們便建立一個 wordpress 專屬的使用者 ftp_wordpress。因此,筆者先建立一個 allftpusers 家目錄為根,讓每個 ftp user 的家目錄都建立集中在 allftpusers 目錄底下。此外建立一個共有的群,目的是讓所有 ftp user 都能存取彼此的檔案;即有如此簡便的管理方式:群外,群內唯讀,及群內可寫。
步驟
sudo apt update
sudo mkdir /home/allftpusers
# 建立一個共同的群 ftps
sudo groupadd ftps
# 我們創建兩個使用者以測試
sudo useradd -m -d /home/allftpusers/ftp_wordpress -s /sbin/nologin ftp_wordpress
sudo useradd -m -d /home/allftpusers/ftp_wp -s /sbin/nologin ftp_wp
# 刪掉既存的檔案
sudo find /home/allftpusers -type f -exec rm {} \;
# vsftpd 規定使用者的家目錄必須是唯讀的;拿掉 w 位元
sudo chmod u-w /home/allftpusers/ftp_wordpress
sudo chmod u-w /home/allftpusers/ftp_wp
# 將新建的使用者加入同一群(視實際狀況而定加不加入)
sudo usermod -a -G ftps ftp_wordpress
sudo usermod -a -G ftps ftp_wp
# 上傳的地方可說是已對外開放,其不僅要嚴謹的安全性也要適度的開放性,故筆者打算設定每個 ftp user 都可共享群 ftps 的權限。故將相關人加入此群
sudo usermod -a -G ftps www-data
# 更改 /home/allftpusers 底下的群擁有者為 ftps
sudo chown -R :ftps /home/allftpusers
# 更改 /home/allftpusers 底下的目錄的模式,群衡為 ftps
sudo chmod -R g+s /home/allftpusers
# 再來將 /sbin/nologin 加入 /etc/shells
# 先切換成 root,改完再退出
sudo -i
echo "/sbin/nologin" >> /etc/shells
exit
# 最後設定兩位使用者的密碼
sudo passwd ftp_wordpress
sudo passwd ftp_wp
# 開始安裝 vsftp server
sudo apt install vsftpd
所安裝的版本是 vsftpd: version 3.0.3
修改組態檔 /etc/vsftpd.conf,更動到的地方最前頭會標記 <<M>>>>>>>>及更改後的設定值
備註:基本技能,將下所有設定複製下來存成一個檔案,再與 /etc/vsftpd.conf 做比對,查看所修改到的地方以自行判斷套用。比對的工具“Meld”簡單易用請自行安裝。
# Example config file /etc/vsftpd.conf
#
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.
#
# READ THIS: This example file is NOT an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
# capabilities.
#
#
# Run standalone? vsftpd can run either from an inetd or as a standalone
# daemon started from an initscript.
listen=NO
#
# This directive enables listening on IPv6 sockets. By default, listening
# on the IPv6 "any" address (::) will accept connections from both IPv6
# and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
# sockets. If you want that (perhaps because you want to listen on specific
# addresses) then you must run two copies of vsftpd with two configuration
# files.
listen_ipv6=YES
#
# Allow anonymous FTP? (Disabled by default).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
<<M>>>>>>>>write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
<<M>>>>>>>>local_umask=022
#
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=YES
#
# If enabled, vsftpd will display directory listings with the time
# in your local time zone. The default is to display GMT. The
# times returned by the MDTM FTP command are also affected by this
# option.
use_localtime=YES
#
# Activate logging of uploads/downloads.
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES
#
# If you want, you can arrange for uploaded anonymous files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown
# below.
#xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
#xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a unique user which the
# ftp server can use as a totally isolated and unprivileged user.
#nopriv_user=ftpsecure
#
# Enable this and the server will recognise asynchronous ABOR requests. Not
# recommended for security (the code is non-trivial). Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore
# the request. Turn on the below options to have the server actually do ASCII
# mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
# predicted this attack and has always been safe, reporting the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#ascii_upload_enable=YES
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
#ftpd_banner=Welcome to blah FTP service.
#
# You may specify a file of disallowed anonymous e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
#deny_email_enable=YES
# (default follows)
#banned_email_file=/etc/vsftpd.banned_emails
#
# You may restrict local users to their home directories. See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.
<<M>>>>>>>>chroot_local_user=YES
#
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
#chroot_local_user=YES
#chroot_list_enable=YES
# (default follows)
#chroot_list_file=/etc/vsftpd.chroot_list
#
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
# Customization
#
# Some of vsftpd's settings don't fit the filesystem layout by
# default.
#
# This option should be the name of a directory which is empty. Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd/empty
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
#
# Uncomment this to indicate that vsftpd use a utf8 filesystem.
<<M>>>>>>>>utf8_filesystem=YES
<<M>>>>>>>>
# 以下片段都是新增
pasv_enable=Yes
pasv_min_port=10000
pasv_max_port=11000
user_sub_token=$USER
local_root=/home/allftpusers/$USER
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO
# Allow virtual users to use the same privileges as local users
virtual_use_local_privs=YES
# Setup the virtual users config folder
user_config_dir=/home/allftpusers/userconfig
#anon_upload_enable=YES
#anon_mkdir_write_enable=YES
chmod_enable=YES
chown_upload_mode=0777
file_open_mode=0777
接著建立 /etc/vsftpd.userlist,並將兩位使用者加入。即,可使用 ftp server 的使用者名單
- sudo -i
- echo ftp_wordpress >> /etc/vsftpd.userlist
- echo ftp_wp >> /etc/vsftpd.userlist
- exit
再來在 /home/allftpusers/ 建立存放使用者組態的目錄 userconfig。並建立以使用者名為名的組態檔
- sudo mkdir /home/allftpusers/userconfig
- sudo touch /home/allftpusers/userconfig/ftp_wordpress
- sudo touch /home/allftpusers/userconfig/ftp_wp
我們只在其中之一加入組態,以比對與沒有組態的執行差異。編輯並加入:
local_root=/var/web/wordpress
write_enable=YES
- sudo gedit /home/allftpusers/userconfig/ftp_wordpress
備註:若按筆者的文章一步一步做過來,那麼 /var/web/wordpress 目錄是還沒建立的。而且請記得,ftp 的家目錄是必須所有人唯讀的。所以,於此,我們先行一步下載解開 wordpress。
- cd /var/web
- sudo wget https://wordpress.org/latest.tar.gz
- sudo tar -zxvf latest.tar.gz
- sudo chmod a-w wordpress
最後一步,先前有提到,使用者的家目錄是唯讀的,這是 vsftpd 的規劃。故我們要有讀寫的能力,就需在家目錄下再創建新目錄,擁有者是使用者,才行。我們就預設一個 uploads 目錄。
- sudo mkdir /home/allftpusers/ftp_wordpress/uploads
- sudo mkdir /home/allftpusers/ftp_wp/uploads
- sudo chown ftp_wordpress /home/allftpusers/ftp_wordpress/uploads
- sudo chown ftp_wp /home/allftpusers/ftp_wp/uploads
TIPS: Linux 是無所不能的。。。能讓使用者隨心所欲,想要什麼樣的功能都有,為何敢這樣講?因為您想要的功能,前人已經想要過,並且也在這自由開放的 Linux 國度裏將它實現出來了:我們此時想要看看在 allftpusers 目錄底下的配置情形有個簡便的 tool , tree
- sudo apt install tree
- tree
- tree -pug
我們從圖中可看出,使用者登入自己的家目錄後,cd 到 uploads 下便可在此寫入檔案或建目錄了。此外,群的權限都不可寫,要可寫必須由管理員開啟,或是 vsftpd 是否有提供給使用者開啟的命令就請自行谷歌了。
以上就完成了 vsftp server 的設定了。接下來個別登入
- sudo systemctl restart vsftpd.service
- sudo systemctl status vsftpd.service
- ftp localhost
我們分別以本地端的管理者 ken,和 ftp_wordpress,ftp_wp 三位使用者登入看看,會發覺 ken 是無法登入的,就如我們在允許清單 vsftpd.userlist 中的設定。
按照本文的例子,我們會發現 ftp_wordpress 登入到 /var/web/wordpress 底下,而 ftp_wp 則是到自己的家目錄下。因此,視實際需求來設定 /home/allftpusers/userconfig 下的組態檔
最後,我們還需檢查建立目錄,上傳檔案,其權限是不是就如我們設定的。權限的運用有興趣者可再谷歌深入研究。
再回到主題:wordpress 能否使用 vsftpd 而不發生問題?其結論似乎避免不掉。當上傳一個外掛,權限方,擁有者是 ftp 使用者,群是 ftps,且 www-data 在該群內。若把群設為可寫,則 wordpress/www-data 能存取讀寫外掛無虞。但是,外掛或外觀都是壓縮檔,解開後的所有檔案,擁有者仍是 ftp 使用者,且權限都將呈現 r w – r – – r – – 所以仍然對 www-data 沒有幫助。基於此之下是否有解法,筆者當前未知請見諒。筆者按:vsftpd 是有可設定任何使用者上傳檔案後,自動將檔案的擁有者改成其他人,因此若使用者能自動改成 www-data 則一切迎刃而解。不過筆者試過試不出來,社群上也一堆人遇到 vsftpd 同樣問題。有興趣者可自行尋解。
補充
筆者在後面的文章會啟用防火牆,一旦啟用,且 ftp 是走 passive mode,那麼 ftp 傳輸將會被擋掉。解決的方式是不走 passive mode。或者參考以下第一條連結。這屬進階,筆者也看不懂XD,所以請自行摸索。
- 參考資料
- http://www.study-area.org/linux/servers/linux_nat.htm#ftp
- https://www.howtoing.com/ubuntu-vsftpd
- https://www.jianshu.com/p/91c7d4a115e0
- https://blog.miniasp.com/post/2012/08/13/Secure-vsFTPd-with-chroot-and-multiple-user-access-permission-tips
- https://www.ryadel.com/en/vsftpd-configure-different-home-folder-each-user-specific-directory/
- https://tosbourn.com/changing-upload-permissions-in-vsftpd/
- https://linux.die.net/man/5/vsftpd.conf
- http://vsftpd.beasts.org/vsftpd_conf.html
- https://blog.xuite.net/rockmansyz/twblog/115534782-%28%E8%BD%89%E8%BC%89%29+vsftp%E5%8A%9F%E8%83%BD%E8%A9%B3%E7%B4%B0%E9%85%8D%E7%BD%AE
- https://serverfault.com/questions/201305/default-owner-permissions-of-created-files-via-vsftpd
發佈留言