January 13, 2009

libsslwrap : 通透地對網路傳輸加上 SSL 保護

最近研究網路傳輸的機制時,想到 Kenichi Kourai 教授在 2001 年設計過一個相當精巧的函式庫 [libsslwrap],可通透地 (transparently) 對 TCP/IP 網路傳輸過程中,加上 SSL 安全連線的保護,更重要的是,不需要對原本的網路應用程式作原始程式碼修改、重新編譯等處理。libsslwrap 運用 UNIX/ELF 執行檔的動態連結機制,透過設定 LD_PRELOAD 環境變數,預先載入 libsslwrap 提供的函式庫,將原本的 connect, accept, write, read, send, recv 等系統呼叫,予以攔截轉包到支援 SSL 的實做,如此一來,即可達到通透處理的目標。

實務上,仍有一些限制,詳情可參閱原始程式套件中的 "README" 檔案,不過就一般的操作,應已足夠。本文將以 telnet 連線為例,說明 libsslwrap 的使用。首先,當然是編譯 libsslwrap,不過,要注意的是,原本的程式無法在 gcc-4.3 下編譯,所以筆者準備一個修正 [libsslwrap-gcc43-build.patch],編譯的環境應該要有 OpenSSL 的開發套件,比方說 Debian/Ubuntu 的 libssl-dev 套件。為了方便後續的說明,給定筆者偏好的 PREFIX:
make PREFIX=/tmp/libsslwrap
make install
建構過程,程式會提醒您建立 SSL certification 資訊,依序填入即可。

既然要探討 telnet 連線,我們就該準備必要的套件,像是 telnet 與 telnetd,很容易地安裝:
# apt-get install telnet telnetd
透過 Wireshark 可視覺化地觀察網路封包的傳輸狀況,因為筆者的實做環境都在本地端 (localhost),所以僅觀察 lo interface,如下圖所示:

在 "lo" 那一列按下 "Start" 按鈕,即可監控本地端的網路封包。telnetd (telnet daemon) 可透過 inetd 執行,假設系統啟動時已有 telnetd 服務,那麼我們直接透過 telnet 連線:
# telnet localhost
參考的終端機執行畫面如下:
telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Ubuntu jaunty (development branch)
後面就是要求登入的訊息,這裡忽略。上面的訊息中,"Ubuntu jaunty" 也就是筆者使用的環境 Ubuntu 9.04 的開發版本,代號為 "jaunty"。因為是明碼傳輸,所以我們可在 Wireshark 觀察往返的網路封包內容,如下圖所示:

上圖的下方視窗中,可見到 "Ubuntu jaunty" 的字樣出現於 Telnet Data,當然啦,繼續等待的話,還能見到登入的帳號與密碼內文,對於其他的網路傳輸協定,如 FTP,也有類似的情況,網路封包的內容一目了然。若系統無法更動為 SSH 或 SFTP (FTP over SSH) 的話,libsslwrap 就能派上用場。
咱們回頭看 libsslwrap。編譯 libsslwrap 後,應該可在 src/ 目錄見到 libsslwrap.so 這個動態函式庫被建立,並且在 make install 後,/tmp/libsslwrap/bin/ 目錄下多了一個名為 sslwrap 的 script,其內容相當單純,就是在執行程式前,透過 LD_PRELOAD 環境變數的設定,預先載入 libsslwrap.so。為了作比較,筆者在稍候即將啟動的 telnetd,要求透過不同的 port (預設 port number 為 22),比方說 port 10023,這可透過 "-debug" 參數達成,也就是說,我們可以這樣啟動 telnet daemon:
# /tmp/libsslwrap/bin/sslwrap /usr/sbin/in.telnetd -debug 10023
當此行指令被執行後,終端機會輸出一個簡短的訊息:"preload",表示 libsslwrap.so 已成功將原本的 connect, accept, write, read, send, recv 等系統呼叫,予以攔截轉包到支援 SSL 的實做,一旦筆者嘗試連線,即可見其端倪。當然,既然 server 端透過 sslwrap 去執行,client 端也要,所以連線指令如下:
# /tmp/libsslwrap/bin/sslwrap telnet localhost 10023
表示欲透過 telnet 連線到 localhost 的 port 10023,此時,Wireshark 的封包就大異於之前純粹的 telnet 連線狀況,參考的輸出如下圖:

這過程包含了 SSL 的 cert 與通訊,以及 (轉包的) telnet 資料傳輸等動作,而封包內容也不再是人眼可識別的明碼了。這表示,libsslwrap 通透地對網路傳輸加上 SSL 保護,不失為一個解決方案。
由 jserv 發表於 January 13, 2009 02:28 PM
迴響

现在的回复好多了!
这个东西真诱人,mark

邱焜 發表於 January 13, 2009 04:08 PM

用途似乎類似 stunnel

但 implement 方式差異很大

OuTian 發表於 January 13, 2009 10:02 PM

如果只是為了傳輸安全, 我個人比較偏好用 OpenSSH 轉 port, 一來不用額外安裝套件, 二來也可以轉到同區段的其他伺服器.

Lu, Jye 發表於 January 14, 2009 11:22 AM
發表迴響









記住我的資訊?