== 第 12 組組員 * B01902003 林子傑 * B01902062 藍挺瑋 * B01902090 許伯駒 * B01902110 程鼎元 == 摘要 設計依據應用層 (Application Layer) 傳輸協定與其欄位內容進行網路位置轉換 (NAT) 的程式。 == 動機 網路位置轉換 (NAT) 在區域網路中還蠻有用的,因為可以在共用 Public IP 地址的情況下讓許多電腦可以透過該 Public IP 對外連線,而且對於 client 來說各種常見的操作 (如上網、BBS、收發 email 等等) 都很透明。但是對於許多伺服器應用或其他較特殊的應用 (例如架設網站、使用 FTP、使用 P2P 軟體) 則需要對 Router 進行設定才能讓外部的連線可以正常連上想要的網站。 舉例來說,若該區域網路內有十台電腦分別負責十個不同的網站 (HTTP/HTTPS),且對外共用同一個 IP 地址,並希望使用獨立的網址。基於安全性考量,現有的解決方案為: . *在 NAT server 設定,將這十個網站分別對應到不同的 port。* + - *優點*:設定方便,但缺點為帶有 port 的 URL 時常令人覺得奇怪,且在某些應用程式上支援度不佳。 + - *缺點*:易導致嚴重的安全性問題,由 HTTP 的實作定義,同一網址不同的 port 所存取的 Cookies 是共用相同的一份,這會導致沒辦法妥善的管理。 . *透過 proxy server 辨認 host 欄位,然後內部再 reverse proxy 到各網站。* + - *優點*:有現成軟體。 - *缺點*:Proxy server 的負載很大,對於大量傳輸資料的連線需要相當多的資源處理封包的暫存區,此外也會導致對真正負責網頁的主機,取得的 IP 位置預設為該 proxy server 的位置。雖然可以藉由修改 HTTP server 來硬改來源 IP,但對不同的 HTTP 伺服器均要特別設計欄位儲存原始 IP 資訊,既麻煩又對後面的機器而言不透明也不太合理,還不如直接在 Router 中處理 Host 欄位去決定將封包轉送予伺服器。 . *使用 IPv6。* - *優點*:真正解決 IP address 數量不夠的問題,也不再需要 NAT。 - *缺點*:目前多數人還沒有辦法存取 IPv6 網路,設定與申請透過 IPv4 傳送 IPv6 封包的 tunnel 又不太方便,使得能連上網站的人很少。 == 目標 讓共用一個 public IP 的多臺伺服器,能不用透過難懂、難記的 port number 區分即能對外開放上線。我們希望只修改 router 中的 NAT server,而不修改後端伺服器使用的軟體,並對後方的伺服器透明,如同沒有這個特別的 router 存在。我們的主要目標是 HTTP 和 HTTPS,如果有時間,我們也希望能支援其他常用的協定,包含一些平常不會修改 port number 的協定。 == 可能實作方法 修改現有作業系統的 NAT 功能,例如 Linux iptables 或是 FreeBSD natd,讓它能分析應用層的協定。由於並不是每個協定都有額外的欄位可用於辨識不同的主機,且每個協定都需要分別實作,因此我們會從最常見、常用的協定開始,例如:HTTP、DNS、SSH。目前我們還不太確定會實作在 kernel mode 還是 user mode,但我們希望架構中能允許 user mode plugin (類似檔案系統中 fuse 的想法),以方便利用現有的函式庫來加速開發 (例如 libssh2)。然而目前 fuse 的做法經常導致較高的 CPU 使用量,對於較舊的機器帶來顯著的效能影響,較新的機器也無法充分發揮運算能力。因此我們還是希望大部分的功能及常用的通訊協定能在 kernel mode 處理,以節省 CPU 在 kernel 和 user 模式間切換所花費的時間。 == 針對 HTTPS 的解決方法 由於 HTTPS 在連線開始時貌似會先送出 Host name 請求憑證,因此我們可以據此辨認 Host name。 == 可能參考資料 我們猜測 Linux iptables 中已有分析 FTP 封包的程式 (用於處理 FTP passive mode 動態允許額外 port 通過),我們可能可以參考這段程式的寫法來做我們的 application layer NAT。 還有另一個稱為 sslh 的 user mode daemon,可藉由 regular expression 分辨不同的application layer 通訊協定,再轉送資料到正確的位置,可用來在同一個 port 上執行不同的服務。我們可能可以參考 sslh 分辨與轉送的方法。 == 可能遇到問題 對於使用 SSL 或其他有加密的協定,我們可能無法直接從封包中取得我們想要的資訊,例如 host 名稱或 user 名稱,此時我們可能必須取得 NAT 後方機器的 private key,或是用類似中間人攻擊的方式才能達成。然而其實大多對外提供的服務均以 HTTP/HTTPS 呈現,因此不必過於擔心此問題。事實上同一 NAT 後方的機器通常是可信任的,共用 private key 並不會造成太大問題。