[Docker] 使用 Docker 建置 FTP(SFTP) 環境
這次案子有需要使用 .net core 存取 FTP 的功能,且又要求 FTP 要分三種登入方式
- 使用帳號密碼登入 FTP Server
- 使用帳號密碼登入 SFTP Server
- 使用 SSH 金鑰登入 SFTP Server
為了 開發環境 需要,最快方法就是使用容器產生這三種 FTP 的環境。 今天就要來說明,怎麼使用 Docker 產生這三種 FTP 環境。
使用工具說明
此篇會說明使用 pure-ftpd 建立 FTP 環境,atmoz/sftp 建立 SFTP 環境。 使用 FileZilla FTP 工具測試連線,以及使用 OpenSSH 工具產生 SSH 金鑰。
建立 FTP Server
根據 pure-ftpd 的說明,只要執行下面的指令,你的 FTP Server 就跑起來囉。
- bash
| 1 | $ docker run -d --name ftpd_server -p 23:21 -p 30010-30019:30010-30019 -e "FTP_PASSIVE_PORTS=30010:30019" -e FTP_USER_HOME=/home/miles -e FTP_USER_NAME=miles -e FTP_USER_PASS=123456 -e "PUBLICHOST=localhost" stilliard/pure-ftpd | 
參數說明
| 參數 | 說明 | 
|---|---|
| -p 23:21 | 使用 host 23 port 連線到容器的 21 port。 而 21 port 是 FTP 預設的連接 port 。 | 
| -e "FTP_PASSIVE_PORTS=30010:30019" | stilliard/pure-ftpd 預設使用 30000-30009port 做資料傳輸,如果要使用預設以外的 port 做資料傳輸,則一定要設定FTP_PASSIVE_PORTS環境變數,此案例我改使用30010-30019port 做資料傳輸。 | 
| -p 30010-30019:30010-30019 | 這邊要特別注意的是,host 的 port 一定要跟容器設定的資料傳輸的 port 一樣,否則是無法正常運作。 以我的例子,因為資料傳輸的 port 是 30010-30019,所以這裡也是使用 host port30010-30019作對應。 | 
| -e FTP_USER_NAME=miles | 使用者的帳號。 | 
| -e FTP_USER_PASS=123456 | 使用者的密碼。 | 
| -e FTP_USER_HOME=/home/miles | 登入使用者存取的資料夾,home 的子目錄一定要是使用者帳號的名稱,否則會有權限無法存取的問題。 以我的例子,使用者帳號是 miles,所以我要設定資料夾路徑是/home/miles。 | 
| -e "PUBLICHOST=localhost" | 我是本地開發使用,沒有要提供其他電腦存取,則可以設定為 PUBLICHOST=localhost。 如果此 FTP Server 要給其他電腦使用的話,一定要設定為 host 的對外 IP,以我電腦 IP192.168.2.103為例,所以就要設定PUBLICHOST=192.168.2.103。 | 
作者有提供 docker-compose 範例: https://github.com/stilliard/docker-pure-ftpd/blob/master/docker-compose.yml
啟用 FTP Server 後,成功連線圖
建立 SFTP Server,使用帳號密碼登入
根據 atmoz/sftp 的說明,只要執行下面的指令,你的 SFTP Server 就跑起來囉,SSH 金鑰預設都會自動產生。
- bash
| 1 | $ docker run -p 2223:22 -d atmoz/sftp miles:123456:::upload | 
參數說明
| 參數 | 說明 | 
|---|---|
| -p 2223:22 | 使用 host 2223 port 連線到容器的 22 port。 而 22 port 是 SFTP 預設的連接 port | 
| miles:123456:::upload | 這是設定帳號、權限、資料夾的指令格式,格式是 帳號:密碼:uid:gid:子資料夾 。 子資料夾會建立在 /home 資料夾底下,這一定要設定,因為建立的使用者沒辦法在 /home 資料夾底下寫檔案,預設情況下,只能在此子資料夾寫檔案。 | 
啟用 SFTP Server 後,成功連線圖
建立 SFTP Server,使用 SSH 金鑰登入
使用 SSH 金鑰登入會稍微麻煩一點,我把步驟拆解如下
- 產生一組 public/private SSH 金鑰
- 寫一個 Dockerfile 將 public key 複製到 atmoz/sftp 的指定資料夾底下,並使用 docker build產生新的 Image
- 執行步驟 2 建立的 Image 與 使用 FileZilla 加 SSH 金鑰連線
1. 建立 public/private SSH 金鑰
atmoz/sftp 裡面有提到建立 SSH 金鑰,可以使用 OpenSSH 的 ssh-keygen 指令。 而我這邊使用 RSA 加密演算法 產生金鑰。
- bash
| 1 | $ ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key | 
指令執行完就會產生一對 public/private key 了
這邊要注意的是 Enter passphrase (empty for no passphrase):,這是在建立金鑰的時候會問你要不要輸入 private key 的密碼,如果有設定的話,在使用 private key 登入的時候會請你輸入 private key 的密碼,如果保留空白的話,則不會要求輸入密碼。
2. 將 public key 放到容器裡面
atmoz/sftp 裡面有提到說,要把 public key 放在 /home/{username}/.ssh/keys/ 底下,而我的 username 是 miles ,所以會放在 /home/miles/.ssh/keys/ 底下,為了完成這件事情,我會建立一個 Dockerfile 做兩件事情
- 先把 /home/miles/.ssh/keys/資料夾建立出來
- 將剛剛產生的 public key ssh_host_rsa_key.pub複製到/home/miles/.ssh/keys/
- Dockerfile
| 1 | FROM atmoz/sftp | 
寫好 Dockerfile 後,只要執行 $ docker build . -t mysftp 就可以把 Image 建立好,如下圖
3. Run Image 與使用金鑰連線
執行下方指令,將容器執行起來1
docker run -p 2223:22 -d mysftp miles::::upload
可以注意我使用 miles::::upload 當作參數,這代表我使用者 miles 沒有設密碼,這是為了強迫使用者 miles 使用 private key 登入。
再到 FileZilla 的 setting 加入剛剛產生的 private key
設定完後,就可以成功使用 SSH 金鑰登入了。
使用 Docker-Compose
最後附上寫好的 Docker-Compose ,只要將專案 clone 下來,執行 $ docker-compose up ,此篇說明的三種 FTP Server 就都會執行起來了。







 
                         
                         
                        