【💊 Python的解憂錦囊】當websockets遇到自簽證書的伺服端時

【💊 Python的解憂錦囊】當websockets遇到自簽證書的伺服端時

更新於 發佈於 閱讀時間約 4 分鐘
raw-image


前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。

Server端

我們的Server端套用了FastAPI框架, 以這樣的寫法載入SSL憑證:

    uvicorn.run(
app,
host='0.0.0.0',
port=int(args.port),
ssl_keyfile=args.ssl_keyfile,
ssl_certfile=args.ssl_certfile,
)

Client端

您可能會透過「【Prompt Engineering 提示工程】Ep.1 什麼是Prompt Engineering?」的技巧去詢問AI問題, 但直觀的會得到這樣的答案:

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.load_verify_locations('/path/to/your/certificate.pem')
async with websockets.connect(
'wss://your.websocket.server',
ssl=ssl_context,
) as websocket:
...

這很正確沒錯, 確實在生產環境使用這種標準方式非常安全, 但麻煩的是還需要這個憑證檔(.pem), 有時候我們在其他臺主機想要快速連線, 又不希望帶上憑證檔時該怎麼辦呢?

這時候聰明的我們可能會這樣問ChatGPT, 請問「如果我不想用pem連線, 而是希望用insecure」, 那麼它可能回答我們這樣的問題:

async with websockets.connect(
'ws://your.websocket.server', # 使用 ws://,而不是 wss://
ssl=False, # 关闭 SSL/TLS 连接的证书验证
) as websocket:
...

這看起來很合理對吧! 但別忘了開頭有提到我們的伺服器是以SSL方式架設, 這跑下去肯定會 💣 , 果不其然發生了這樣的錯誤…

connect() received a ssl argument for a ws:// URI, use a wss:// URI to enable TLS

不死心的我們加了點變化, 強制在URL用wss連線, 結果…

 did not receive a valid HTTP response

!!! 難道沒招了嗎? 不不不, 既然我們的https都有insecure的連線方式了, 難道websocket沒有嗎? 這不可能, 沒關係, 我知道您現在也非常納悶為什麼 ssl=False沒有用, 就讓我們來分享一下正確的使用方式吧!

🌟 本章精華重點

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

async with websockets.connect(
'wss://your.websocket.server',
ssl=ssl_context,
) as websocket:
...

結語

我們學會與AI合作固然是好事, 但它給的答案並不能完全信任, 在這之前我們還是得具有獨立思考的能力, AI僅是輔助我們快速思考的工具, 最終驗證與決策還是要回歸自身, 因此得到答案後也應一步步驗證再進行分享, 避免垃圾近、垃圾出的狀況導致誤解, 造成錯誤的結果。

avatar-img
阿Han的沙龍
127會員
281內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言
avatar-img
留言分享你的想法!
阿Han的沙龍 的其他內容
🤔 簡單且靜態就足夠了? 相信我們在開發Python應用程式的過程中, 常常會借用Enum來定義我們可能的選項, 就像顏色紅、綠、黃會有這樣的結構: class Color(str, Enum): RED = 'red' GREED = 'green' YELLOW = 'yel
當我們的系統發展到一定程度時, 難免會面臨到正式上線的問題, 要如何讓維運更加簡易呢? 尤其隨著複雜的客製化配置的出現時, 我們應該如何有效的管理, 甚至驗證配置是否如預期資料型態、格式…, 而正好 pydantic 可以滿足這樣的需求, 就讓我們來看看怎麼使用吧! 需安裝的套件 pip i
要如何使用unicorn啟動多個FastAPI服務, 歡迎參考我們的「【💊 Python的解憂錦囊 - FastAPI】如何啟動多個Workers」。 當我們試著設計帶入模組化時… 我們在「【💊 Python的解憂錦囊 - FastAPI】使用 lifespan 來共享資料與管理生命週期
🤔 簡單且靜態就足夠了? 相信我們在開發Python應用程式的過程中, 常常會借用Enum來定義我們可能的選項, 就像顏色紅、綠、黃會有這樣的結構: class Color(str, Enum): RED = 'red' GREED = 'green' YELLOW = 'yel
當我們的系統發展到一定程度時, 難免會面臨到正式上線的問題, 要如何讓維運更加簡易呢? 尤其隨著複雜的客製化配置的出現時, 我們應該如何有效的管理, 甚至驗證配置是否如預期資料型態、格式…, 而正好 pydantic 可以滿足這樣的需求, 就讓我們來看看怎麼使用吧! 需安裝的套件 pip i
要如何使用unicorn啟動多個FastAPI服務, 歡迎參考我們的「【💊 Python的解憂錦囊 - FastAPI】如何啟動多個Workers」。 當我們試著設計帶入模組化時… 我們在「【💊 Python的解憂錦囊 - FastAPI】使用 lifespan 來共享資料與管理生命週期