[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-30009 port 做資料傳輸,如果要使用預設以外的 port 做資料傳輸,則一定要設定 FTP_PASSIVE_PORTS 環境變數,此案例我改使用 30010-30019 port 做資料傳輸。 |
-p 30010-30019:30010-30019 |
這邊要特別注意的是,host 的 port 一定要跟容器設定的資料傳輸的 port 一樣,否則是無法正常運作。 以我的例子,因為資料傳輸的 port 是 30010-30019 ,所以這裡也是使用 host port 30010-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,以我電腦 IP 192.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 就都會執行起來了。