標籤:saas paas aws
雲端服務已經成為現代人生活的一部分。手機中的照片會自動同步到雲中;你的郵件內容儲存在雲中;辦公軟體運行在雲中;你的健康資料會即時上傳到雲中;你每天的生活軌跡消耗的卡路裡也會上傳到雲中;雲端服務也會逐漸象交電費、交水費一樣被福士接受,這是科技進步的必然。
雲端服務安全嗎?這個被反覆問過的問題,也被回答了很多次。我僅僅作為一個軟體工程師,談談自己在安全方面的一點嘗試。供借鑒。
大的安全話題包括很多個方面,資料可靠嗎?資料是否被偷窺、篡改?
資料不丟的這個基本要求可以說已經很好了,AWS的S3已經達到11個9的持久性,存一份遺囑在S3上,估計比儲存在銀行保險柜中還要可靠(不容易丟,但是否被偷窺,這個就不好說了)。有人會反問一個問題,那比特幣丟失的為啥那麼多呢?儲存比特幣的數位憑證,不僅僅要不丟,而且要不被偷,如果比特幣認證檔案儲存在S3上,估計小偷就多了。這方面不做深入的討論。
資料的保密性問題,不被偷窺,不被篡改等。這個問題的本質在於是否有技術手段來保障安全,如果沒有就只能基於信任機制了。比如你使用銀行的服務,你只有信任他,相信他不會偷你的錢。但如果有技術做保障的數字貨幣的機制,那麼你就不需要被迫的信任哪個人或機構,你只要相信科學就可以了。或許在不遠的未來,數字貨幣會取代銀行。而現階段的雲端服務在資料保密性方面還處在基於信任的階段。
當你開啟一個線上軟體(qq郵箱,tower.im等等),你就已經開始使用SAAS提供的服務了,你大部分的資料也都將儲存在SAAS服務商那裡。你信任你的SAAS服務商嗎?
SAAS服務商開發的線上軟體,也通常運行在更基礎的PAAS服務商提供的服務上。比如資料庫服務RDS,虛擬機器主機服務EC2、ECS,檔案儲存體服務S3、OSS等等。作為一個SAAS的開發工程師,你信任PAAS服務商嗎?
信任SAAS的問題。如果有一種端到端的技術,在瀏覽器這一端實現加密解密,那麼就不用擔心SAAS偷資料。例如自己生產資料,自己消費資料(比如拍照上傳只給自己看),這個容易實現。用一個儲存在本地的對稱金鑰完成加密解密就可以了。但如果是涉及到2個人蔘與的動作,比如郵件,一個人發送,一個人接收,做到端到端加密,這要用非對稱密碼技術。但如果是多人蔘與的動作,比如線上協助類的服務,一個人提交的內容要多個人讀的情境,要實現端到端的加密估計就更複雜了。 如果SAAS服務商無法提供一個令你滿意的技術方案, 你唯一的選擇就是信任他或者不信任他, 沒有更好的辦法。
信任PAAS的問題,是否有一個技術手段來擺脫信任呢? PAAS提供基礎服務,儲存資料,儲存檔案,提供計算能力等,SAAS儲存在PAAS中的資料,也只允許SAAS自己訪問,在這種情境下,就可以使用對稱金鑰的加密技術。SAAS 儲存一個 AES256 的隨機密鑰,所有SAAS伺服器共用密鑰。SAAS收到使用者提交的資料用AES256加密,然後儲存到PAAS中。SAAS讀取PAAS的資料,解密後在返回給使用者。
瀏覽器使用者 ---- SAAS 工程代碼 -- AES 密鑰 ----- PAAS 資料庫
我們現在討論,代碼、密鑰、資料庫單個泄漏,或者任意2個泄漏,或者這3個都泄漏,資料是否安全?
資料庫敏感欄位用AES加密後,即使被拖庫(只泄漏資料庫),也是不可解密的。AES-256的密碼強度理論上是不可破解的。——這樣改造後拖庫是安全的。
資料庫加密的方法很好,問題是密鑰本身如何保護 ? 寫在代碼中是不合適的。因為代碼,程式員是可以看到的。提交到github中,也有可能代碼泄漏。編譯後的二進位代碼,逆向也是可以破解這類固定密碼。所以AES-256密鑰不能放在源碼中。AES-256密鑰,應寫在設定檔中 keyconf,並且這個設定檔不作為工程項目的一部分,只在作業系統的配置目錄中(例如/etc) 下存放。只有營運人員可以訪問這個檔案,所有SAAS伺服器上這個檔案一致,就完成加密解密。——這樣改造後,源碼和資料同時泄漏(密鑰不泄漏),也是安全的。
密鑰資訊儲存在設定檔中,這個營運人員能看到,一旦伺服器被非法登入,也容易泄漏。應對這種風險有一種做法,在工程代碼中儲存一對非對稱金鑰RSA,用public key把原始的 AES祕密金鑰加密一次,加密後的KEYFile 作為設定檔儲存在 /etc 目錄下。在SAAS啟動服務的時候,用自己的private key 解密這個 KEYFile,得到最原始的AES-256 。 —— 這樣改造後,AES密鑰(RSA處理後的)和資料庫同時泄漏(源碼不泄漏,RSA不泄漏),也是安全的。
在考慮一種極端的情況, 原始碼泄漏,密鑰也泄漏,資料庫也泄漏,資料還安全嗎? 從源碼中可有取到RSA的私密金鑰,用這個私密金鑰可以解密AES-256對稱金鑰, 用這個AES-256密鑰就可以解密資料庫。 針對這種情況,也有一種辦法。通常情況下,KEYFile是不需要長期保留在伺服器上的,這個檔案只在啟動服務的時候有用,如果啟動完成後,解密後的AES-256儲存在進程的記憶體中,這個KEYFile檔案就不在需要了。辦法就是,把KEYFile 用口令再加密一次產生KEYFileSsl,產生環境只保留KEYFileSsl 這個檔案。啟動服務是通過一個啟動指令碼來完成,指令碼在執行時,提示輸入口令, 口令正確的情況下,先解密得到 KEYFile ,然後正常啟動服務, 服務啟動後,指令碼立刻刪除 KEYFile。 —— 這樣改造後,源碼泄漏,同時KEYFileSsl泄漏,同時拖庫,也是安全的(因為沒有啟動口令)。
上面的做法有2個缺點,一個是,啟動需要口令,這導致服務意外crash後,無法自動拉起。口令永遠不要記錄在任何指令碼中。另一個缺點是,AES-256的原始密鑰,是儲存在服務進程的記憶體中的,如果生產環境的主機被劫持了,駭客是有辦法通過分析記憶體來擷取密鑰的(這個有點難,但有這個可能)。針對這個漏洞,AWS的最佳實務是,禁止生產環境主機上一切shell登入(AWS的這個做法值得推薦的。AWS的虛擬機器EC2 建議採用禁止登入的模式,任何開發人員、任何營運人員都不能登入到生產環境的主機。EC2的初始化,環境的部署都是自動化完成的,沒有人為的幹預,也在一定程度上防範了偷資料的情況。)。
提高PAAS安全性的一點嘗試