Arch Linux ARM 安裝與設定 FTP 伺服器 for vsftpd

如何在 Arch Linux ARM 裡安裝 vsftpd 這個 FTP 伺服器,並設定允許使用者登入、上傳的環境,以及如何限制使用者無法離開家目錄,及解說 umask 檔案預設權限與 chroot 限制。


以下流程將使用「一般使用者」而非 root 來操作系統,如無法使用 sudo 指令,請參考 安裝與設定 Arch Linux for Raspberry Pi 2
使用 pacman -S 指令安裝套件發生失敗或錯誤時,請先執行 pacman -Sy 更新套件列表資料

基本概念

umask 檔案預設權限

這是在新建目錄或檔案時的預設權限。

umask 的分數是「預設值需要減掉的權限」,而新建目錄或檔案的預設權限值如下:

  • 新建「檔案」:檔案沒有可執行(x)的權限,也就是說只有 rw 這兩個,所以預設權限值為 666 → -rw-rw-rw-
  • 新建「目錄」:因為 x 權限與是否可進入此目錄有關,也就是所有權限均開放,所以預設權限值為 777 → drwxrwxrwx

假設 umask = 022,所以:

  • 新建「檔案」的權限為 666 – 022 = 644
  • 新建「目錄」的權限為 777 – 002 = 755

chroot 限制

為了阻步使用者進入 Linux 系統的其他目錄,也就是將使用者限制在自己的家目錄底下,這樣登入 FTP 後,就無法切換至 Linux 系統的其它目錄了,這種環境就是 chroot 限制,來加強「安全性」。

安裝

使用以下指令安裝 vsftpd 這套 FTP(檔案傳輸協定)伺服器:

[smalljacky@alarmpi ~]$ sudo pacman -S vsftpd

啟動 vsftpd,並設定開機自動啟動:

[smalljacky@alarmpi ~]$ sudo systemctl start vsftpd.service
[smalljacky@alarmpi ~]$ sudo systemctl enable vsftpd.service

測試

使用預設啟用的 anonymous(匿名)測試,先切換至 anonymous 的家目錄,在新增一個 ftptest 檔案,然後使用 ftp 指令 – 連線至 vsftpd 伺服器:

anonymous 的家目錄在 /srv/ftp/,且無上傳權限,並啟用 chroot(將使用者限制在家目錄)
[smalljacky@alarmpi ~]$ cd /srv/ftp/
[smalljacky@alarmpi ftp]$ sudo touch ftptest
[smalljacky@alarmpi ftp]$ ftp localhost

ftp: connect to address ::1: Connection refused
ftp: Trying 127.0.0.1 ...
Connected to localhost.
220 (vsFTPd 3.0.3)

# 使用者名稱
Name (localhost:smalljacky): anonymous

# 無密碼,直接「ENTER」
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

# 查看伺服器的目錄或檔案
ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rwxrwxrwx    1 0        0               0 Mar 30 21:25 ftptest
226 Directory send OK.

# 結束 ftp
ftp> bye
221 Goodbye.

設定檔

說明

vsftpd 的設定檔在 /etc/vsftpd.conf,以下列出較常用的一些設定:

[smalljacky@alarmpi ~]$ sudo nano /etc/vsftpd.conf

# 是否啟用 anonymous 登入
anonymous_enable=YES

# 允許 /etc/passwd 中的使用者登入,就是允許使用者登入
# 目錄為 /home/使用登名稱
#local_enable=YES

# 允許使用者修改資料
#write_enable=YES

# 新建目錄或檔案時的預設權限
#local_umask=022

# 是否啟用 chroot,將所有使用者限制在家目錄
# YES 啟用;NO 停用(註釋表示 NO)
#chroot_local_user=YES

# 是否啟用指定使用者,如下 chroot_list_file 設定的路徑
# YES 啟用;NO 停用(註釋表示 NO)
#chroot_list_enable=YES

# 限制或排除指定的使用者,取決於 chroot_local_user 的設定
#chroot_list_file=/etc/vsftpd.chroot_list

這裡最難理解的就是 chroot_local_user、chroot_list_enable 這兩個設定了,下表列出它們的組合效果:

chroot_local_user 與 chroot_list_enable 組合效果
chroot_local_user=YES chroot_local_user=NO
chroot_list_enable=YES
  • 啟用 chroot,將所有使用者限制在家目錄
  • 對 chroot_list_file 指定的使用者,停用 chroot
  • 停用 chroot,所有使用者不被限制在家目錄
  • 對 chroot_list_file 指定的使用者,啟用 chroot
chroot_list_enable=NO
  • 啟用 chroot,將所有使用者限制在家目錄
  • 不使用 chroot_list_file 指定的使用者
  • 停用 chroot,所有使用者不被限制在家目錄
  • 不使用 chroot_list_file 指定的使用者

案例設定

現在有一需求如下:

  1. anonymous 不可登入
  2. 所有使用者都可登入並上傳資料
  3. 僅 smalljacky 使用者,不被限制在家目錄
  4. 新建資料的預設權限:
    • 檔案:644
    • 目錄:755

編輯設定檔:

[smalljacky@alarmpi ~]$ sudo nano /etc/vsftpd.conf

#anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list

設定排除 smalljacky 使用者,停用 chroot:

[smalljacky@alarmpi ~]$ sudo nano /etc/vsftpd.chroot_list

# 一行一個使用者
smalljacky

重新載入設定檔,這樣剛才的設定才能生效:

[smalljacky@alarmpi ~]$ sudo systemctl reload vsftpd.service

停用 chroot 的使用者測試

使用 smalljacky 使用者登入測試,先新增一個 ftptest 檔案,然後使用 ftp 指令 – 連線至 vsftpd 伺服器:

因為在自己的家目錄,所以沒有權限問題,就不需 sudo 指令,即可新增檔案
[smalljacky@alarmpi ~]$ touch ftptest
[smalljacky@alarmpi ~]$ ftp localhost

ftp: connect to address ::1: Connection refused
ftp: Trying 127.0.0.1 ...
Connected to localhost.
220 (vsFTPd 3.0.3)

# 使用者名稱
Name (localhost:smalljacky): smalljacky

# 密碼
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

# 查看目前所在目錄
ftp> pwd
257 "/home/smalljacky" is the current directory

# 查看伺服器的目錄或檔案
ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rwxrwxrwx    1 0        0               0 Mar 30 21:25 ftptest
226 Directory send OK.

# 變更到上一層目錄
ftp> cdup
250 Directory successfully changed.

ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwx------    2 1000     1000         4096 Mar 30 19:19 alarm
drwx------    2 1001     1001         4096 Mar 31 22:44 smalljacky
226 Directory send OK.

# 變更到指定目錄
ftp> cd smalljacky
250 Directory successfully changed.
ftp> pwd
257 "/home/smalljacky" is the current directory

# 結束 ftp
ftp> bye
221 Goodbye.

啟用 chroot 的使用者測試

使用 alarm 使用者登入測試,使用 ftp 指令 – 連線至 vsftpd 伺服器:

[smalljacky@alarmpi ~]$ ftp localhost

ftp: connect to address ::1: Connection refused
ftp: Trying 127.0.0.1 ...
Connected to localhost.localdomain.
220 (vsFTPd 3.0.3)

# 使用者名稱
Name (localhost:smalljacky): alarm

# 密碼
331 Please specify the password.
Password:

# 登入失敗
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
ftp: Login failed.
421 Service not available, remote server has closed connection

# 結束 ftp
ftp> bye

不是已經允許所有使用者登入了嗎?上述登入失敗的說明為“啟用 chroot 環境,使用者的 root(就是家)目錄,不可以有寫入(w)的權限”。

沒有寫入權限不就無法修改檔案了?沒辦法這是 vsftpd 的設計,目前唯一的解法就是取消家目錄的寫入權限,並新增一個目錄,且給予可讀、寫和執行的權限,這裡我新增一個 ftp 的目錄名稱:


[smalljacky@alarmpi ~]$ sudo ls -ald /home/alarm               # 查看目錄權限
drwx------ 2 alarm alarm 4096 Mar 31 03:19 /home/alarm
[smalljacky@alarmpi ~]$ sudo chmod 500 /home/alarm             # 取消寫入(w)的權限
[smalljacky@alarmpi ~]$ sudo ls -ald /home/alarm
dr-x------ 2 alarm alarm 4096 Mar 31 03:19 /home/alarm
[smalljacky@alarmpi ~]$ sudo mkdir -m 700 /home/alarm/ftp      # 新建目錄
[smalljacky@alarmpi ~]$ sudo chown alarm:alarm /home/alarm/ftp # 變更擁有者:群組
[smalljacky@alarmpi ~]$ sudo ls -ald /home/alarm/ftp
drwx------ 2 alarm alarm 4096 Apr  2 13:42 /home/alarm/ftp

再次使用 alarm 使用者登入測試:

[smalljacky@alarmpi ~]$ ftp localhost

ftp: connect to address ::1: Connection refused
ftp: Trying 127.0.0.1 ...
Connected to localhost.localdomain.
220 (vsFTPd 3.0.3)

# 使用者名稱
Name (localhost:smalljacky): alarm

# 密碼
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

# 變更到 ftp 這個目錄
ftp> cd ftp
250 Directory successfully changed.

# 查看目前所在目錄
ftp> pwd
257 "/ftp" is the current directory

# 結束 ftp
ftp> bye
221 Goodbye.

發表迴響