廣播系統的安全與應對方案

此文主要介紹了本公司核心廣播系統面對的各種安全問題以及採用的解決方案。注意此文只包含了數據安全的討論,對於 ddos 等導致服務不穩定的阻斷式攻擊並不再討論之列(因爲阻斷式攻擊的防禦完全可以獨立分析與部署)!

我們先把可能遇到的問題大概分類如下:

服務軟件bug

服務軟件是整個系統的核心,它運行在服務器上,它如果被黑客攻陷不但廣播系統會被完全掌控而且服務器以及服務器所在的區域網路都將面對巨大的安全挑戰。

服務軟件最致命的bug在我看來有兩個:

  1. sql注入
  2. 緩衝區溢出

sql注入漏洞可能會導致數據被黑客竊取,並且一些數據庫(例如 MS SQL)的不當設置還會導致黑客直接獲取到 remote shell 進而完成掌控服務器計算機。對此的解決方案要求程序員嚴格的把控SQL相關代碼,絕不使用手動組合的動態SQL語句,而是使用數據庫提供的 Parameter API 來組合SQL語句。

任何緩衝區溢出漏洞基本上都等於一個 remote shell,這必須完全避免爲此的解決方案是儘量不使用類似 c/c++ 之類能夠直接操縱內存的語言,而是使用 golang/java 之類由語言本身對內存寫入提供了保護的安全語言編寫服務軟件(golang/java 如果調用的 c 代碼存在問題依然可能出現緩衝區溢出漏洞)。本公司的核心服務代碼大部分選擇了使用 golang 開發。

當然對代碼的有效測試是所有軟件都必不可少的環節,此處不再贅述!

使用 docker 部署服務軟件

即使再小心,服務軟件也可能存在bug,爲此我們應該儘量減小出現問題時造成的危害,爲此我們公司推薦使用 docker 來部署服務軟件。

  1. 首先我們公司的軟件按照功能模塊劃分爲了各個微服務,從而減少某個模塊代碼出現問題的機率(越簡單的代碼越安全)
  2. 我們將每個微服務都獨立部署到一個docker容器中,並且爲此容器設置了最小可用權限。

現在即使某個微服務出現了問題,它也不會危害到其它服務,並且即使黑客獲取到了 remote shell 它的 shell 也只有這個容器中的最小可用權限,它很難逃離容器或提升root權限對宿主系統發出攻擊。

並且因爲所有服務都運行在 docker 中,所以宿主機幾乎不會安裝docker之外的任何軟體,依據代碼越少越安全的基本推論,所以宿主機也因此受益它幾乎沒有安裝什麼軟體(代碼)所以它存在漏洞的可能性也降低!

網路數據的監聽與冒充

無論是發佈廣播的用戶還是接收廣播的硬件設備它們都使用網路與服務器通信,網路傳輸主要存在兩個安全問題:

  1. 數據被監聽,例如連接咖啡廳的wifi,所有網路數據都經過咖啡廳的路由設備,這些路由設備的實際控制人可以看到所有傳輸的數據
  2. 黑客可以冒充成服務器發動中間人攻擊,然後接收客戶端發來的敏感信息

http 也受到這兩個層面的打擊,於是出現了 https ,https 在 http 上使用了一個 tls 的傳輸層來負責數據安全和服務器認證。世界上絕大部分的服務都安全的運行在 https 上並且最好的程序員都在優化着 https 爲此我們公司也選擇了直接使用 tls 來解決上述兩個問題。

tls 客戶端會首先與服務器溝通獲取服務器的證書,客戶端會對證書進行驗證,由於證書採用了RSA的非對稱加密,所以只要服務器方不泄漏自己的證書黑客就無法僞造成服務器,這直接解決了冒充服務器的問題(中間人攻擊)。在證書驗證有效並且協商好加密算法後,服務器和客戶端會使用對稱加密算法加密所有傳輸的數據,因爲對稱加密算法的密鑰是由RSA加密後傳輸的,所以中間設備也無法獲取到正確的密鑰從而只能看到加密後的傳輸數據而無法獲取傳輸的真實內容。

tls 的唯一需要注意的就是選擇一個高加密強度的證書,以及禁用掉一些tls中存在安全漏洞的歷史算法,這需要在實際部署項目時去落實!

h2 httpadapter

另外值得一提的是,我們公司項目的對外標準接口是 http,無論客戶端軟件還是硬件設備都可以使用 http 訪問,並且我們的服務都支持了 http2 從而能夠高效的提供服務!

此外對於一些嵌入式設備不支持 http 或 http2 可以訪問 httpadapter 接口,httpadapter 是我們公司研發的一個標準協議,它比http更簡單以方便嵌入式設備能夠支持,但比 http1.1高效比 http2 差很多。它會按照固定工作模式代理客戶端去訪問 http 接口。

有了 httpadapter 現在服務器可以毫無負擔的選擇最新的 http 技術而不用擔心嵌入式的訪問問題。採用 http 服務器作爲硬件的服務接口,不但可以簡化服務器代碼也能讓針對硬件與一般用戶的服務代碼能夠更加統一以及容易測試!同樣越簡單的代碼造就了越安全的系統!

用戶密碼泄漏,訪問憑證被竊取

任何系統都需要爲人類服務,它們必須受到人類的控制,通常的做法都是爲授權的人類創建一個綁定的用戶,通過密碼之類的登入驗證後返回一個訪問憑證,用戶使用訪問憑證去訪問系統。在這之間出現的主要問題是:

  1. 過於簡單的密碼容易被黑客猜解
  2. 過於個人特色或規律化的密碼容易被黑客猜解
  3. 用戶直接泄漏了自己的密碼
  4. 使用重放攻擊直接獲取到訪問憑證
  5. 訪問憑證泄漏

前三個問題都是由於密碼泄漏導致的,我們的做法是拒絕用戶創建過於簡單的密碼,同時儘量減小密碼泄漏後造成的危害。這是通過爲不同用戶創建不同的授權範圍來減少損失的,但無論如何一個用戶的密碼泄漏,意味着這個用戶的所有操作權限都被人竊取。得益於手機的普及可以打開我們提供的可選功能,使用手機短信驗證代替密碼的輸入,但如果手機遺失是這個方案存在的安全漏洞!

另外攻擊者可以不需要密碼,它們可以發動重放攻擊,將攔截到的正確請求直接原封不動傳遞給服務器以期望服務器返回登錄後的憑證!通常 tls 的傳輸層直接保護了重複攻擊的無效,但是如果打開一些 tls 效率優化功能,重放攻擊依然可能會成功。爲此我們的解決方案是要求客戶端在登入時傳入當前時間,並且使用當前時間對密碼hash進行撒鹽混系,這保證了即使是相同的密碼每次傳給服務器的請求都不相同,並且服務器會對時間進行驗證對於超過一定時間(比如5分鐘)的數據則返回錯誤。當然在這五分鐘內的重放攻擊依然有效,但通常黑客從攔截到請求並發動重放攻擊的時間會比這個長從而避免大部分問題。撒鹽的另外一個好處是這也可以避免對攔截到的密碼hash進行暴力的反向hash對比(查找已存在的hash快速匹配hash的原值)。如果對安全有較高要求,需要絕對的阻擋重放攻擊,則應該依賴 tls 傳輸層,關閉一些存在危險的特性(例如關閉 0RTT)。

用戶也可能會直接泄漏訪問憑證,我們的做法是減少憑證的有效時間,在我們系統中用戶登入成功後服務器會返回一個 access_token 作爲訪問憑證,它通常有效期只有一個小時,同時返回一個 refresh_token 它通常有效期是七天。access_token 只能用作系統功能的訪問,如果它被泄漏在一個小時內它將自動失效。爲了防止讓用戶頻繁登入,客戶端軟體可以自動使用 refresh_token 來獲取一個新的 access_token,這一切對於用戶來說都是透明的。此外 access_token 和 refresh_token 都是一次性的,並且有效時間也可以依據實際系統需要自行設定。

另外如果用戶感覺密碼或者憑證已經泄漏,應該立刻聯繫管理員並重置自己的密碼。一旦重置密碼所有發出的憑證都將立刻失效!

受控設備的冒充

對於廣播系統,還存在着受控廣播需要和服務器通信,它主要存在兩方面安全問題。

  1. 和服務器間的通信被監聽
  2. 非法設備向服務器冒充頂替爲合法設備

對於問題1,在採用tls作爲傳輸層後就基本解決了。tls會加密數據防止路由設備監聽數據,同時驗證服務器身份保證不會被中間人攻擊從而竊取通信數據。

對於問題2,我們的做法是使用加密算法驗證設備合法,受控設備必須首先向廣播系統請求註冊,一旦註冊成功廣播系統會返回一個訪問憑證供設備與服務器溝通。這和用戶登入很像,其實把受控廣播想象成一個用戶那它們從邏輯上講幾乎就是一樣的。

在我們的系統中廣播註冊分爲了兩步:

  1. 受控廣播請求服務器的 negotiate 接口向服務器協商加密算法,服務器會返回雙方都支持的加密算法+random salt+當前時間,並爲這些信息進行簽名
  2. 客戶端收到 negotiate 返回協商的信息後需要按照要求使用 自己的物理指紋+出廠內置的salt 以及服務器發來的算法+random salt+當前時間 計算一註冊值
  3. 客戶端使用註冊值+negotiate返回的內容請求服務器的 register 接口進行註冊
  4. 服務器首先驗證 negotiate 的協商內容是否被篡改(使用協商結果裏面的簽名驗證)以及是否以及過期(通常是5分鐘),然後使用和步驟2中客戶端相同的步驟計算註冊值,並比較註冊值是否一致來識別是否是合法設備
  5. 如果是合法設備服務器爲設備返回 access_token,此後合法設備使用此 access_token 與服務器溝通

上述方案的關鍵在於:

  1. 服務器與受控設備內置了多種算法,每次使用隨機算法(服務器隨機選取使用 negotiate 返回算法給設備)來生成註冊值,這樣增加了黑客對算法的猜解難度
  2. 客戶端和服務器都內置了一個 salt 用於對註冊值進行撒鹽,這即增加了安全也能保證公司不同客戶的系統不會互相干擾(內置 salt 不同無法互相工作和識別)
  3. 服務器在協商結果中加入了 random salt 保證每次的註冊值都是不同的,加入當前時間防止重放攻擊,爲 negotiate 結果簽名防止協商結果被篡改

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注