netdev 第一天:IPsec!

netdev 第一天:IPsec!

編譯自: https://jvns.ca/blog/2018/07/11/netdev-day-1--ipsec/

嗨!和去年一樣,今年我又參加了 netdev 會議 。( 這裡 是我上一年所做的筆記)。

在今天的會議中,我學到了很多有關 IPsec 的知識,所以下面我將介紹它們!其中 Sowmini Varadhan 和 Paul Wouters 做了一場關於 IPsec 的專題研討會。本文中的錯誤 100% 都是我的錯 :)。

什麼是 IPsec?

IPsec 是一個用來加密 IP 包的協議。某些 VPN 已經是通過使用 IPsec 來實現的。直到今天我才真正意識到 VPN 使用了不只一種協議,原來我以為 VPN 只是一個通用術語,指的是“你的數據包將被加密,然後通過另一臺服務器去發送“。VPN 可以使用一系列不同的協議(OpenVPN、PPTP、SSTP、IPsec 等)以不同的方式來實現。

為什麼 IPsec 和其他的 VPN 協議如此不同呢?(或者說,為什麼在本次 netdev 會議會有 IPsec 的教程,而不是其他的協議呢?)我的理解是有 2 點使得它如此不同:

  • 它是一個 IETF 標準,例如可以在文檔 RFC 6071 等中查到(你知道 IETF 是制定 RFC 標準的組織嗎?我也是直到今天才知道的!)。
  • 它在 Linux 內核中被實現了(所以這才是為什麼本次 netdev 會議中有關於它的教程,因為 netdev 是一個跟 Linux 內核網絡有關的會議 :))。

IPsec 是如何工作的?

假如說你的筆記本正使用 IPsec 來加密數據包並通過另一臺設備來發送它們,那這是怎麼工作的呢?對於 IPsec 來說,它有 2 個部分:一個是用戶空間部分,另一個是內核空間部分。

IPsec 的用戶空間部分負責密鑰的交換,使用名為 IKE ( 網絡密鑰傳輸(internet key exchange))的協議。總的來說,當你打開一個 VPN 連接的時候,你需要與 VPN 服務器通信,並且和它協商使用一個密鑰來進行加密。

IPsec 的內核部分負責數據包的實際加密工作 —— 一旦使用 IKE 生成了一個密鑰,IPsec 的用戶空間部分便會告訴內核使用哪個密鑰來進行加密。然後內核便會使用該密鑰來加密數據包!

安全策略以及安全關聯

(LCTT 譯註:security association 我翻譯為安全關聯, 參考自 https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E9%97%9C%E8%81%AF )

IPSec 的內核部分有兩個數據庫:安全策略數據庫(SPD)和安全關聯數據庫(SAD)。

安全策略數據庫包含 IP 範圍和用於該範圍的數據包需要執行的操作(對其執行 IPsec、丟棄數據包、讓數據包通過)。對於這點我有點迷糊,因為針對不同 IP 範圍的數據包所採取的規則已經在路由表(sudo ip route list)中使用過,但顯然你也可以設定 IPsec 規則,但它們位於不同的地方!

而在我眼中,安全關聯數據庫存放有用於各種不同 IP 的加密密鑰。

查看這些數據庫的方式卻是非常不直觀的,需要使用一個名為 ip xfrm 的命令,至於 xfrm 是什麼意思呢?我也不知道!

(LCTT 譯註:我在 https://www.allacronyms.com/XFMR/Transformer 上查到 xfmr 是 Transformer 的簡寫,又根據 man7 上的簡介, 我認為這個說法可信。)

# security policy database

$ sudo ip xfrm policy

$ sudo ip x p

# security association database

$ sudo ip xfrm state

$ sudo ip x s

為什麼 IPsec 被實現在 Linux 內核中而 TLS 沒有?

對於 TLS 和 IPsec 來說,當打開一個連接時,它們都需要做密鑰交換(使用 Diffie-Hellman 或者其他算法)。基於某些可能很明顯但我現在還沒有理解(??)的原因,在內核中人們並不想做密鑰的交換。

IPsec 更容易在內核實現的原因是使用 IPsec 你可以更少頻率地協商密鑰的交換(對於每個你想通過 VPN 來連接的 IP 只需要一次),並且 IPsec 會話存活得更長。所以對於用戶空間來說,使用 IPsec 來做密鑰交換、密鑰的獲取和將密鑰傳遞給內核將更容易,內核得到密鑰後將使用該密鑰來處理每個 IP 數據包。

而對於 TLS 來說,則存在一些問題:

a. 當你每打開一個 TLS 連接時,每次你都要做新的密鑰交換,並且 TLS 連接存活時間較短。 b. 當你需要開始做加密時,使用 IPsec 沒有一個自然的協議邊界,你只需要加密給定 IP 範圍內的每個 IP 包即可,但如果使用 TLS,你需要查看 TCP 流,辨別 TCP 包是否是一個數據包,然後決定是否加密它。

實際上有一個補丁用於 在 Linux 內核中實現 TLS ,它讓用戶空間做密鑰交換,然後傳給內核密鑰,所以很明顯,使用 TLS 不是不可能的,但它是一個新事物,並且我認為相比使用 IPsec,使用 TLS 更加複雜。

使用什麼軟件來實現 IPsec 呢?

據我所知有 Libreswan 和 Strongswan 兩個軟件。今天的教程關注的是 libreswan。

有些讓人迷糊的是,儘管 Libreswan 和 Strongswan 是不同的程序包,但它們都會安裝一個名為 ipsec 的二進制文件來管理 IPsec 連接,並且這兩個 ipsec 二進制文件並不是相同的程序(儘管它們擔任同樣的角色)。

在上面的“IPsec 如何工作”部分,我已經描述了 Strongswan 和 Libreswan 做了什麼 —— 使用 IKE 做密鑰交換,並告訴內核有關如何使用密鑰來做加密。

VPN 不是隻能使用 IPsec 來實現!

在本文的開頭我說“IPsec 是一個 VPN 協議”,這是對的,但你並不必須使用 IPsec 來實現 VPN!實際上有兩種方式來使用 IPsec:

  1. “傳輸模式”,其中 IP 表頭沒有改變,只有 IP 數據包的內容被加密。這種模式有點類似於使用 TLS —— 你直接告訴服務器你正在通信(而不是通過一個 VPN 服務器或其他設備),只有 IP 包裡的內容被加密。
  2. ”隧道模式“,其中 IP 表頭和它的內容都被加密了,並且被封裝進另一個 UDP 包內。這個模式被 VPN 所使用 —— 你獲取你正傳送給一個秘密網站的包,然後加密它,並將它送給你的 VPN 服務器,然後 VPN 服務器再傳送給你。

投機的 IPsec

今天我學到了 IPsec “傳輸模式”的一個有趣應用,它叫做 “投機的 IPsec”(通過它,你可以通過開啟一個 IPsec 連接來直接和你要通信的主機連接,而不是通過其他的中介服務器),現在已經有一個“投機的 IPsec” 服務器了,它位於 http://oe.libreswan.org/ 。

我認為當你在你的電腦上設定好 libreswan 和 unbound DNS 程序後,當你連接到 http://oe.libreswan.org 時,主要發生瞭如下的幾件事:

  1. unbound 做一次 DNS 查詢來獲取 oe.libreswan.org (dig ipseckey oe.libreswan.org) 的 IPSECKEY 記錄,以便獲取到公鑰來用於該網站(這需要 DNSSEC 是安全的,並且當我獲得足夠多這方面的知識後,我將用另一篇文章來說明它。假如你想看到相關的結果,並且如果你只是使用 dig 命令來運行此次 DNS 查詢的話,它也可以工作)。
  2. unbound 將公鑰傳給 libreswan 程序,然後 libreswan 使用它來和運行在 oe.libreswan.org 網站上的 IKE 服務器做一次密鑰交換。
  3. libreswan 完成了密鑰交換,將加密密鑰傳給內核並告訴內核當和 oe.libreswan.org 做通信時使用該密鑰。
  4. 你的連接現在被加密了!即便它是 HTTP 連接!有趣吧!

IPsec 和 TLS 相互借鑑

在今天的教程中聽到一個有趣的花絮是 IPsec 和 TLS 協議實際上總是從對方學習 —— 正如他們說在 TLS 出現前, IPsec 的 IKE 協議有著完美的正向加密,而 IPsec 也從 TLS 那裡學了很多。很高興能聽到不同的網絡協議之間是如何從對方那裡學習並與時俱進的事實!

IPsec 是有趣的!

我已經花了很長時間來學習 TLS,很明顯它是一個超級重要的網絡協議(讓我們來加密網絡吧!:D)。但 IPsec 也是一個很重要的網絡加密協議,它與 TLS 有著不同的角色!很明顯有些移動電話協議(例如 5G/LTE)使用 IPsec 來加密它們的網絡流量!

現在我很高興我知道更多關於 IPsec 的知識!和以前一樣可能本文有些錯誤,但希望不會錯的太多 :)


via: https://jvns.ca/blog/2018/07/11/netdev-day-1--ipsec/

本文由 LCTT 原創編譯, Linux中國 榮譽推出


分享到:


相關文章: