最近在制作我們系統的發布包時,整理到ftp的時候,發現我們使用的是ssh模式進行文件傳輸的,而不是RFC 959的ftp,於是查了下,發現存在兩種模式的文件傳輸模式,FTP和SSH。
- 第一個RFC的FTP協議發布通過網絡使用FTP協議(由RFC 959或更高版本)的文件傳輸始於1980年,FTP提供上傳,下載和刪除文件,創建和刪除目錄,讀取目錄內容的功能。雖然FTP是非常受歡迎的,它有一些缺點,使其更難使用。主要的缺點是缺乏目錄列表的統一格式(這個問題已經通過引入MLST命令部分解決,但是一些服務器不支持)和輔助連接(DATA連接)的存在。FTP中的安全性通過對RFC 2228中定義的信道加密采用SSL / TLS協議來提供。FTP的安全版本稱為FTPS。
- 在UNIX系統中,另一種安全標准有所提升。它是SSH協議家族的一員,SSH的主要功能是保護遠程shell訪問UNIX系統。后來SSH擴展了文件傳輸協議 - 第一個是SCP(SSH 1.x),然后是SFTP(SSH2)。版本1中的SSH協議已經過時了,而且不安全,我們一般不推薦使用。 因此,SCP不再被使用,然后SFTP卻日益流行。
“SFTP”縮寫經常被誤解是FTP某種安全的類型,人們通常認為是FTPS。另一個(類似的)誤解是SFTP被認為是某種基於SSL的FTP。 而實際上SFTP是“SSH文件傳輸協議”的縮寫。這不是基於SSL的FTP(這在技術上也是可能的,但是非常少見),而是基於SSH的FTP。
SFTP是一種二進制協議,其最新版本在RFC 4253中被標准化。所有命令(請求)被打包為二進制消息,並發送到服務器,服務器使用二進制回復包進行回復。在之后的版本中,SFTP被擴展為不僅僅提供文件上傳/下載操作,還提供一些文件系統操作,例如文件鎖定,符號鏈接創建等。
FTPS和SFTP都使用非對稱算法(RSA,DSA),對稱算法(DES / 3DES,AES,Twhofish等)和密鑰交換算法的組合。對於驗證FTPS(或更准確地說,FTP下的SSL / TLS協議)使用X.509證書,而SFTP(SSH協議)使用SSH密鑰。
X.509證書包括公鑰和有關證書所有者的某些信息。此信息允許另一方驗證證書本身的完整性和證書所有者的真實性。驗證可以通過計算機和在一定程度上由人來完成。 X.509證書具有關聯的私鑰,出於安全原因,通常與證書分開存儲。
SSH密鑰只包含公鑰(相關的私鑰是單獨存儲的)。它不包含有關密鑰所有者的任何信息。 同樣也不包含允許可靠地驗證完整性和真實性的信息。 一些SSH軟件實現使用X.509證書進行身份驗證,但實際上它們不驗證整個證書鏈 - 只使用公鑰(這使得此類身份驗證不完整,類似於SSH密鑰身份驗證)。
以下是兩個協議的優缺點的簡要列表:
FTPS
優點:
- 廣為人知並使用
- 通信可以由人閱讀和理解
- 提供了服務器到服務器文件傳輸的服務
- SSL / TLS具有良好的身份驗證機制(X.509證書功能)
- 在許多互聯網通信框架中都支持內置FTP與SSL / TLS。
缺點:
- 沒有統一的目錄列表格式
- 需要輔助數據通道,這使其難以在防火牆后使用
- 沒有為文件名定義標准字符集(編碼)
- 並非所有FTP服務器都支持SSL / TLS
- 沒有標准的方式來獲取和更改文件和目錄屬性
SFTP
優點:
- 有良好的標准背景,在操作方面具有嚴格的定義
- 只有一個連接(不需要DATA連接)
- 連接始終保持安全
- 統一的目錄列表格式
- 協議包括用於權限和屬性操作,文件鎖定和更多功能的操作
缺點:
- 通信是二進制的,可讀性差
- SSH密鑰更難以管理和驗證
- 標准將某些事物定義為可選或推薦的,這導致某些兼容性問題
- 沒有服務器到服務器副本以及遞歸目錄刪除操作
- 在VCL和.NET框架中不支持內置的SSH / SFTP
- 性能相比FTP要低1/2
如何做出選擇
通常,答案取決於您的目標和要求。 一般來說,SFTP在技術上優於FTPS。 當然,實現對兩個協議的支持是一個好主意,但是它們在概念,支持的命令和許多其他方面是不同的。
當您具有需要從個人設備(智能手機,PDA等)訪問的服務器或具有FTP支持但沒有SSH / SFTP客戶端的某些特定操作系統時,最好使用FTPS。 如果您正在構建自定義安全解決方案,SFTP可能是更好的選擇。
對於客戶端,需求由您計划連接的服務器定義。 當連接到Internet服務器時,SFTP更受歡迎,因為它默認由Linux和UNIX服務器支持。
對於私有主機到主機傳輸,您可以使用SFTP和FTPS。 對於FTPS,您需要搜索一個免費的FTPS客戶端和服務器軟件或購買商業許可證。 對於SFTP支持,您可以安裝OpenSSH軟件包,它提供免費的客戶端和服務器軟件。 對於商業用途,我們建議使用Bitvise SSH服務器。
java客戶端開發工具
在java中,jsch能夠支持ftps和sftp。
在c++中,libssh2能夠支持sftp,ftp可以直接用socket進行通信。
java服務端開發工具
如果實現ftp的服務器端,可以考慮采用Apache FtpServer實現,其支持ssl,如果要在此基礎上實現內存FTP,可以采用嵌入式+jimfs(java的內存文件系統實現),參考https://stackoverflow.com/questions/30394737/in-memory-file-system-in-java,https://stackoverflow.com/questions/31388036/how-to-handle-incoming-files-in-apache-mina-sshd-sftp-server-in-java。要實現SSH協議,可以考慮Apache SSHD或SSHTOOLS。
所以,對大部分情況來說,sftp可能是更合適的方案,它不需要專門安裝vsftpd軟件,能夠同時支持java/c++,省去了軟件發布的麻煩。但是如果傳輸的數據量巨大,那么就要考慮是否采用FTP或FTPS了,它比SFTP的性能要高大約1/2,參見https://stackoverflow.com/questions/8849240/why-when-i-transfer-a-file-through-sftp-it-takes-longer-than-ftp(注:我們在局域網中親自驗證了該場景,千兆網絡的2G文件傳輸,SFTP平均只能達到50多M每秒,直接http/FileZilla)。