PEP 546 – Backport ssl.MemoryBIO 和 ssl.SSLObject 到 Python 2.7
- 作者:
- Victor Stinner <vstinner at python.org>, Cory Benfield <cory at lukasa.co.uk>
- BDFL 委託:
- Benjamin Peterson <benjamin at python.org>
- 狀態:
- 已拒絕
- 型別:
- 標準跟蹤
- 建立日期:
- 2017年5月30日
- Python 版本:
- 2.7
- 釋出歷史:
- 2017年5月23日
- 決議:
- Python-Dev 訊息
摘要
將 Python 3 中的 ssl.MemoryBIO 和 ssl.SSLObject 類 backport 到 Python 2.7,以增強 Python 2.7 的整體安全性。
拒絕通知
此 PEP 已被拒絕,請參閱 Withdraw PEP 546? Backport ssl.MemoryBIO and ssl.SSLObject to Python 2.7 的討論以瞭解原因。
基本原理
雖然 Python 2.7 即將結束支援(計劃於 2020 年),但它仍在生產系統中使用,Python 社群仍對其安全性負責。此 PEP 將有助於促進 PEP 543 在所有支援的 Python 版本中的未來採用,從而提高 Python 2 和 Python 3 使用者安全性。
此 PEP **不** 提議對 backport 新功能到 Python 2.7 進行普遍豁免 - 任何提議 backport 的新功能仍需要獨立證明其合理性。特別是,需要解釋為什麼依賴於 Python 包索引上獨立更新的 backport 不是一個可接受的解決方案。
PEP 543
PEP 543 定義了一個新的 Python TLS API,它將透過允許 Python 應用程式訪問 Windows 和 macOS 上的原生 TLS 實現,而不是使用 OpenSSL,來增強 Python 的安全性。其副作用是它允許訪問系統信任儲存和系統管理員本地安裝的證書,使 Python 應用程式能夠使用“公司證書”,而無需修改每個應用程式,從而正確驗證 TLS 證書(而不是忽略或繞過 TLS 證書驗證)。
出於實際原因,Cory Benfield 希望首先為 PEP 543 實現一個類似 ssl.MemoryBIO 和 ssl.SSLObject 的無 I/O 類,並在此基礎上提供一個使用套接字或檔案描述符的第二個類。這種設計將有助於構建程式碼以支援更多後端,簡化測試和審計,以及實現。稍後,可能會新增使用套接字或檔案描述符的最佳化類以提高效能。
雖然 PEP 543 定義了一個 API,但只有當它附帶至少一個完整且良好的實現時,該 PEP 才有意義。理想情況下,第一個實現將基於 Python 標準庫的 ssl 模組,因為該模組預設隨所有使用者分發,並且可以在沒有更具針對性的實現時用作備用實現。
如果未執行此 backport,唯一可用的基礎實現將是 pyOpenSSL。然而,這存在問題,因為它會與 pip 互動,而 pip 是隨所有受支援版本的 CPython 分發的。
requests, pip 和 ensurepip
目前有計劃研究將 Requests 遷移到更面向事件迴圈的模型。Requests 團隊目前不認為可以放棄對 Python 2.7 的支援,因此這樣做將需要使用 Twisted 或 Tornado,或者編寫自己的非同步抽象。
對於非同步程式碼,MemoryBIO 與使用包裝套接字相比具有顯著優勢。它減少了必須進行的緩衝量,可以在基於 IOCP 的反應器以及基於 select/poll 的反應器上工作,並且還大大簡化了反應器和實現程式碼。因此,Requests 不願使用基於包裝套接字實現的方案。在沒有 backport 到 Python 2.7 的情況下,Requests 被要求使用與 Twisted 相同的解決方案:即,強制依賴 pyOpenSSL。
出於實際原因,pip 程式必須嵌入其所有依賴項:即,它不能依賴於任何其他安裝方法。由於 pip 依賴於 requests,這意味著它必須嵌入 pyOpenSSL 的副本。這將導致安裝 pip 時出現顯著的可用性問題。目前,pip 不支援嵌入必須在每個平臺上編譯的 C 擴充套件,因此需要 C 編譯器。
自 Python 2.7.9 起,Python 就嵌入了 pip 的副本,用於預設安裝以及透過新的 ensurepip 模組在虛擬環境中使用。如果 pip 最終捆綁 PyOpenSSL,那麼 CPython 將會捆綁 PyOpenSSL。只有 backport ssl.MemoryBIO 和 ssl.SSLObject 才能避免嵌入 pyOpenSSL 的需要,並解決引導問題(python -> ensurepip -> pip -> requests -> MemoryBIO)。
這種情況比 PEP 543 採用的障礙問題要小,因為 Requests 自然不必在放棄對 Python 2.7 支援之前就遷移到事件迴圈模型。然而,只要它繼續支援 Python 2,它就會使 Requests(和 pip)在同時支援 asyncio 以及 async 和 await 關鍵字時變得痛苦。
其他好處
採納此 PEP 將帶來其他一些較小的生態系統效益。例如,Twisted 將能夠減少對第三方 C 擴充套件的依賴。此外,PyOpenSSL 開發團隊希望淘汰該模組,此 backport 將使他們能夠以一種優雅的方式做到這一點,而不會讓他們的使用者陷入困境。
所有這些零星的好處,雖然微小,但也為更廣泛的 Python 生態系統帶來了價值。
關注點
人們對這個 backport 存在一些擔憂。
舊的 Python 2 怎麼辦?
世界上許多 Python 2 使用者跟不上 Python 2 的釋出節奏。這通常是因為他們使用的是未跟上 Python 2 次要版本釋出的 LTS 版本。這些使用者將無法使用 MemoryBIO,因此關注 Python 2 相容性的專案可能無法在他們的大多數使用者系統上依賴 MemoryBIO 的存在。
這種擔憂是合理的。它有多關鍵取決於當前 Python 2 使用者遷移到 Python 3 的可能性,或者他們只是嘗試使用最新版本的 Python 2。換句話說,總有一天庫會想要放棄 Python 2 支援:問題只在於,在他們放棄支援之前,他們的 Python 2 使用者中是否有很大一部分已經遷移到包含此 backport 的 Python 2 版本。
最終,此 PEP 的作者認為此 backport 的負擔足夠小,值得在考慮此擔憂後進行 backport。如果事實證明遷移到較新的 2.7 版本過於緩慢,那麼這項工作的價值將很小,但如果遷移到較新的 2.7 版本是合理的,那麼將獲得巨大的價值。
更改
將 MemoryBIO 和 SSLObject 類新增到 Python 2.7 的 ssl 模組中。
程式碼將從 master 分支(Python 3)進行 backport 和改編。
此 backport 還顯著減小了 _ssl 模組在 Python 2/Python 3 之間的差異,這使得維護更加容易。
連結
- PEP 543
- [backport] ssl.MemoryBIO: Alex Gaynor 編寫的此 PEP 的實現(第一個版本寫於 2014 年 10 月)
- PEP 466
討論
- [Python-Dev] Backport ssl.MemoryBIO on Python 2.7? (2017 年 5 月)
版權
本文件已置於公共領域。
來源: https://github.com/python/peps/blob/main/peps/pep-0546.rst
最後修改: 2025-02-01 08:59:27 GMT