LWN:擴(kuò)展內(nèi)核里的TLS支持!
關(guān)注了就能看到更多這么棒的文章哦~
Extending in-kernel TLS support
By Jonathan Corbet
April 25, 2022
DeepL assisted translation
https://lwn.net/Articles/892216/
內(nèi)核在 2017 年 9 月推出的 4.13 版本中就支持了 TLS 協(xié)議。但這個支持是不完整的,因?yàn)樗鼪]有給內(nèi)核提供一種方法來自己發(fā)起 TLS 連接。而是需要用戶空間創(chuàng)建一個 socket,并在將 socket 交給內(nèi)核之前執(zhí)行 TLS 握手,然后內(nèi)核可以使用 TLS 來傳輸數(shù)據(jù)。Chuck Lever 提出了一組 patch,可能可以改變這種情況了,盡管仍然需要用戶空間來做些事情。
眾所周知,TLS 是用來在網(wǎng)絡(luò)上傳輸加密數(shù)據(jù)的。別的不用說,至少 HTTPS 鏈接背后依賴的協(xié)議就是 TLS。當(dāng)前,網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)有很大一部分是以這種方式加密的。在建立了連接之后,把數(shù)據(jù)加密發(fā)送到另一端的工作是相對比較簡單的,對收到的數(shù)據(jù)進(jìn)行解密也是如此。然而,建立連接的過程很復(fù)雜,其中還涉及到算法協(xié)商以及為一端或兩端來提供(provision)和驗(yàn)證(verification)公共密鑰。
在內(nèi)核中支持 TLS 的話會有一些好處,包括性能會有小幅提升,并且可以使用 socket filter 來過濾了。不過,TLS session 的建立過程并不太關(guān)注性能,而且由于這個過程很復(fù)雜,可能會導(dǎo)致更多的 bug 以及安全問題。因此,當(dāng)人們給內(nèi)核添加 TLS 支持時,主要專注在數(shù)據(jù)傳輸方面,而將建立 session 的困難留給了用戶空間。這就是內(nèi)核的 TLS 支持在過去幾年中的工作方式。
這個解決方案是有效的,但有時如果內(nèi)核能夠自己啟動 TLS session 的話會很有好處。因此引出了 Lever 的 patch。這個 patch set 仍然沒有將 TLS 握手引入內(nèi)核,盡管最終還是希望能實(shí)現(xiàn)這個理想目標(biāo)的:
從長遠(yuǎn)來看,我們傾向于在內(nèi)核中實(shí)現(xiàn) TLS 握手。然而,這還需要很長的時間,而且有些人希望在沒有充分理由的情況下就不要去增加 Linux 內(nèi)核的 "攻擊面" 了。因此我們也同時創(chuàng)建了一個原型來實(shí)現(xiàn)握手,它會去調(diào)用到用戶空間,而實(shí)際的握手工作就可以由現(xiàn)成的 TLS 庫實(shí)現(xiàn)來完成。
這個設(shè)計(jì)要求在有可能需要內(nèi)核啟動 TLS 連接的情況下(具體來說就是所有的 network namespace 里面)運(yùn)行一個特殊的用戶空間進(jìn)程。該進(jìn)程將使用新增的 AF_TLSH("TLS helper")address-family type 來創(chuàng)建一個 socket,然后監(jiān)聽該 socket。當(dāng)內(nèi)核需要建立一個 TLS session 時,listen() 調(diào)用就會返回一個已經(jīng)連接上的 TCP socket;然后該進(jìn)程可以與遠(yuǎn)端的對方來交流從而建立好 session。如果協(xié)商成功就可以使用帶有新增的 SOL_TLS 選項(xiàng)的 setockopt() 調(diào)用來配置新建立的 session。關(guān)閉 socket 后就會把它返還給內(nèi)核。
在內(nèi)核里面,會有一個新函數(shù)在最開始 TCP 連接建立后就被調(diào)用:
int tls_client_hello_x509(struct socket *sock, void (*done)(void *data, int status),
void *data, const char *priorities, key_serial_t peerid,
key_serial_t cert);
這個調(diào)用會試圖把 sock 傳遞給 helper 進(jìn)程。成功的話就會返回 0;此時仍在進(jìn)行協(xié)商。等到 session 設(shè)置成功(或失?。┲?,done() 這個回調(diào)函數(shù)就會被調(diào)用,并給出此操作的結(jié)果。如果得到的是一個成功的狀態(tài),那么內(nèi)核就應(yīng)該能夠通過 socket 來使用 TLS 進(jìn)行通信了。還有 tls_client_hello_psk() 函數(shù),它可以在有 pre-shared key 密鑰存在的情況下用來共享。
有人會問,為什么需要這個功能?其中之一的用途就是在 TLS 上實(shí)現(xiàn)遠(yuǎn)程過程調(diào)用(RPC)協(xié)議,這已經(jīng)有了相關(guān)的后續(xù) patch set。這樣就可以用來在加密連接之上實(shí)現(xiàn) NFS 文件系統(tǒng)協(xié)議了。Lever 說,未來人們可能還有興趣使用這一功能來在 QUIC 連接之上支持 SMB 文件系統(tǒng)協(xié)議,當(dāng)然,前提是內(nèi)核在這幾年確實(shí)支持了 QUIC 的話。
對 TLS patch 的反應(yīng)相對平靜,只有 Hannes Reinecke 的一組 Reviewed-by 標(biāo)簽,他也是其中一個 patch 的作者。相反,RPC-over-TLS patch 則遇到了一些來自 Trond Myklebust 的不同意見,他是內(nèi)核 NFS 客戶端的維護(hù)者。他認(rèn)為這些 setup 工作可以完全在用戶空間由 mount.nfs 工具完成。Lever 回應(yīng)說,在有些情況下,我們認(rèn)為內(nèi)核需要決定是否應(yīng)該使用 TLS。討論結(jié)束時仍然沒有得出結(jié)論,所以這個話題很可能會在 5 月初的 Linux Storage, Filesystem, and Memory-Management Summit 上繼續(xù)討論。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。
長按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開源社區(qū)的各種新近言論~
