Stack Overflow上部署HTTPS:長路盡頭
Python部落(python.freelycode.com)組織翻譯,禁止轉載,歡迎轉發。
註:本文共分五部分,其他四部分在今日推送的其他文章中。
今天,我們在Stack Overflow上默認部署了HTTPS。 所有流量現在都被重定向到https://,Google鏈接將在接下來的幾周內更改。 激活這個功能真的是如翻轉開關一樣簡單(功能標誌),但為做到這一點已經花了好幾年的時間。 到目前為止,HTTPS是所有問答網站的默認設置。
過去兩個月,我們一直在Stack Exchange網路中推出HTTPS。 Stack Overflow是最後一個站點,並且是迄今為止最大的站點。 這對我們而言是一個巨大的里程碑,但決不是最終的結果。 還有更多的工作要做,我們將會介紹。 但終點已近在眼前,萬歲!
友好提醒:這是漫長的旅程的故事。 故事很長,所以你會看到滾動條顯示的非常小。 雖然堆棧交換/溢出在我們遇到的問題中並不是唯一的,但兩種問題同時發生卻相當罕見。 我希望您能找到我們的嘗試,磨難,錯誤,勝利,甚至一些開源項目的一些細節,這些項目一直都是有幫助的。 很難將這樣一個錯綜複雜的依賴關係鏈構造成一個按時間順序排列的帖子,所以我將分析一下主題:基礎設施,應用程序代碼,錯誤等。
我認為首先列出使我們的情況有點獨特的問題,是很有幫助的:
我們有數百個域名(很多網站和其他服務)
許多二級域名(stackoverflow.com,stackexchange.com,askubuntu.com等)
許多第4級網域(例如meta.gaming.stackexchange.com)
我們允許用戶提交和嵌入內容(例如圖片和YouTube視頻在帖子中)
我們從一個數據中心提供服務(延遲到單一來源)
我們有廣告(和廣告網路)
我們使用websockets,在任何機器上都有超過500,000活躍連接
我們有DDoSed(代理)
我們有許多網站和應用程序通過HTTP API進行通信(代理問題)
我們痴迷性能(也許有點太多)
由於這篇文章有點瘋狂,為方便起見可以通過下面連接訪問:
開始
快速規格
基礎設施
證書
子元(meta.*.stackexchange.com)
性能:HTTP / 2
HAProxy:提供HTTPS
CDN /代理:快速反擊雲計算延遲
準備代理:客戶端計時
CloudFlare
Railgun
Fastly
全球DNS
測試
應用程序/代碼
準備應用程序
全域登錄
本地HTTPS開發
混合內容
來自用戶
來自我們
重定向(301s)
WebSockets
未知數
錯誤
協議相對URL
API和.internal
301緩存
幫助中心SNAFU
開源
下一步
HSTS預載入
聊天
今天
開始
早在2013年我們就開始考慮在Stack Overflow上部署HTTPS。所以顯而易見的問題是:現在是2017年。這4年時間都在做什麼? 幾乎任何IT項目延遲無非兩個原因:依賴和優先順序。 老實說,Stack Overflow的信息並不像很多其他數據那樣有價值(安全)。 我們不是銀行,我們不是醫院,我們不處理信用卡付款,我們甚至在四分之一的時間內通過HTTP和torrent發布我們的大部分資料庫。 這意味著從安全的角度來看,它並不像其他情況那樣高優先順序。 與大多數相比,我們還有更多的依賴關係,這是部署HTTPS時一些巨大問題的一個非常獨特的組合。 如稍後您會看到的,一些域名問題也是永久性的。
造成問題的最大領域是:
用戶內容(用戶可以上傳圖片或指定網址)
廣告網路(合同和支持)
從單個數據中心託管(延遲)
數百個域,多級(證書)
好的,為什麼要在我們的網站上使用HTTPS? 好吧,數據不是唯一需要安全的事情。 我們擁有通過網路訪問網站的各種級別的版主,開發人員和員工。 我們希望保護他們與網站的通信。 我們希望確保每個用戶的瀏覽歷史。 有些人每天都在恐懼中生活,知道有人會發現他們秘密地喜歡獨處。 谷歌也提升了HTTPS網站的排名(雖然我們不知道多少)。
對了,還有性能。 我們喜歡性能。 我喜歡性能。 你喜歡性能。 我的狗愛性能。 讓我們有一個性能擁抱。 那很好,謝謝。 聽起來不錯吧。
快速說明
有些人只是想要結論,所以在這裡快速問答(我們喜歡Q&A!):
問:你支持哪些協議?
答:TLS 1.0,1.1,1.2(注意:快速有一個TLS 1.0和1.1的棄用計劃)。 TLS 1.3支持即將到來
問:您是否支持SSL v2,v3?
答:不,這些都是壞的,不安全的協議。每個人都應儘快禁用他們。
問:你支持哪些密碼?
答:在CDN,我們使用Fastly的默認套件
答:在我們的負載平衡器,我們使用Mozilla的現代兼容性套件
問:通過HTTPS快速連接到原點?
答:是的,如果CDN請求是HTTPS,則原始請求是HTTPS。
問:你是否支持保密?
答:是的
問:你是否支持HSTS?
答:是的,我們現在正在Q&A網站上升級。一旦完成,我們將其移動到邊緣。
問:您是否支持HPKP?
答:不,我們可能不會。
問:你支持SNI嗎?
答:不,我們有HTTP / 2性能原因的組合通配符證書(詳情如下)。
問:你在哪裡獲得證書?
答:我們使用DigiCert,他們已經很棒了。
問:你是否支持IE 6?
答:遷移到HTTPS讓我們徹底放棄了IE6。 IE 6不支持TLS(默認 - 雖然可以啟用1.0),但是我們不支持SSL。通過301重定向到位,大多數IE6用戶無法再訪問Stack Overflow。當TLS 1.0被刪除時,就真的沒有IE6用戶了。
問:你使用什麼負載均衡器?
答:HAProxy(它在內部使用OpenSSL)。
問:HTTPS的動機是什麼?
答:人們不斷攻擊我們的管理後台地址,如stackoverflow.com/admin.php。
證書
我們來談論證書,因為有很多的錯誤信息。我已經無法統計有多少人在說他安裝了證書並且已經準備好使用HTTPS了。再看一下你的滾動條的小尺寸,如果我同意的話可以猜測一下。我們更喜歡SWAG方法進行猜測。
我們得到的最常見的問題是:「為什麼不使用Let』s Encrypt?
答:因為他們在這裡不適合。Let』s Encrypt正在做一件好事。我希望他們堅持下去。如果您使用的是單一網域或只有少數網域,對於各種場景來說,這是一個很好的選擇。我們根本不是這樣。Stack Exchange有數百個域。Stack Exchange不提供通配符。這兩件事情是相互矛盾的。每次部署新的問答網站(或任何其他服務)時,我們都必須獲得證書(或兩個)。這使部署變得非常複雜,或者a)丟棄非SNI客戶端(大約2%的流量)或者b)需要更多的IP空間。
我們要控制證書的另一個原因是我們需要在本地負載平衡器和CDN /代理提供程序上安裝完全相同的證書。除非我們能夠做到這一點,否則我們無法在所有情況下乾淨地進行故障轉移(遠離代理)。通過HPKP(HTTP公鑰固定)固定證書的任何人都將無法驗證。我們正在評估是否部署HPKP,但是我們已經為以後部署做好了準備。
我很吃驚我們的主要證書包含了所有的帶通配符的主域名。這看起來像下圖這樣:
為什麼這樣做? 好吧,為了公平起見,DigiCert是根據要求為我們做這件事的人。 為什麼每一次變化都要忍受手動合併證書的痛苦? 首先,因為我們想支持儘可能多的人。 這包括不支持SNI的客戶端(例如,從一開始Android 2.3就是一件大事情)。 而且還因為HTTP/2和現實。 我們會很快介紹。
證書:Child Metas(meta.*.stackexchange.com)
Stack Exchange網路的原則之一就是有一個地方可以談論每個問答網站。 我們稱之為「second place」。 例如,meta.gaming.stackexchange.com用來談論有關game.stackexchange.com。 那麼為什麼會這樣呢? 好吧,我們今天的主題不是這個。 我們只關心這個域名。 一共4層。
前面我已經介紹過了,但是我們在哪裡結束了? 首先問題是:* .stackexchange.com覆蓋了games.stackexchange.com(和其他幾百個網站),但並不包括meta.gaming.stackexchange.com。 RFC 6125(第6.4.3節)規定:
客戶端不應嘗試匹配顯示的標識符,其中通配符不應用來匹配除最左邊標籤之外的標籤(例如,不應這樣匹配bar.*.example.net)。
這意味著我們不能像meta.*.stackexchange.com這樣使用通配符。 那麼我們該怎麼辦?
選項1:部署SAN證書
我們需要3個證書(每個限制為100個域),我們需要使用3個IP,我們會使新的站點啟動複雜化(直到該方案被改變)
我們必須在CDN /代理處為這3個定製證書支付費用
我們必須為meta.*方案下的每個子元素都有一個DNS條目
由於DNS的規則,我們實際上必須為每個站點添加DNS條目,使站點啟動和維護複雜化。
選項2:將所有域移動到* .meta.stackexchange.com?
我們有一個痛苦的舉動,但它是一次性,簡化了所有維護和證書
我們必須建立一個全域登錄系統(這裡的細節)
此解決方案還創建了一個includeSubDomains HSTS預載入問題
選項3:我們已經做得夠好了,關閉它們
這一個是最簡單的,但沒有被批准
我們建立了一個全域登錄系統,後來移動了這個子域名(有301s),現在他們正處於新的地方。例如https://gaming.meta.stackexchange.com。在這樣做之後,我們意識到HSTS預載入列表的一個問題有多麼簡單,因為這些域已經存在。我會在近期結束,因為它仍在進行中。請注意,這裡的問題像
meta.pt.stackoverflow.com一樣反映在我們的過程中,但是由於只有4個非英文版本的Stack Overflow存在,所以它們的規模很有限。
哦,這又造成了另一個問題。通過將Cookie移動到頂級域,並依靠子域繼承,我們現在不得不移動域。例如,我們使用SendGrid在我們的新系統中發送電子郵件(現在推出)。從stackoverflow.email發送的鏈接指向sg-links.stackoverflow.email(CNAME指向他們)的鏈接的原因是,您的瀏覽器不會發送任何敏感的Cookie。如果是sg-links.stackoverflow.com(或stackoverflow.com下的任何內容),您的瀏覽器將發送我們的cookies給他們。這是新事物的一個具體例子,但是我們的DNS下還有其他不託管的服務。這些子域中的每一個都必須被移動或退出,以從我們的認證域名下移走,否則我們將把cookies發送到不屬於我們的伺服器。做所有這些工作只是為了防止在最後將cookie泄漏到其他伺服器,那是很丟臉的。
我們試圖在一個實例中通過在一段時間內代理我們的一個Hubspot屬性來解決這個問題,剝離cookie。但不幸的是,Hubspot使用Akamai,它開始將我們的HAProxy實例視為機器人,並以每周幾種方式阻止它。前3次很有趣。所以無論如何,這真的沒有奏效。它變得如此糟糕,我們永遠不會再做。
你可能好奇為什麼我們在https://stackoverflow.blog/上有Stack Overflow Blog?是的,安全。它託管在外部服務上,以便營銷團隊和其他人可以更快地迭代。為了方便這一點,我們需要從cookied的域名中除去。
元子域遇到的上述問題也發生在HSTS,預載入和includeSubDomains指令。但是,我們會看到為什麼以後會變成無實際意義。
性能:HTTP/2
很久以前都會認為HTTPS速度較慢。 以前是的。 但時代在變。 我們不是在單純談論HTTPS了。 我們在談論使用HTTP/2的HTTPS。 雖然HTTP/2不需要加密,但它實際上是有效的。 這是因為大多數瀏覽器需要安全連接才能實現其大部分功能。 您可以一整天爭論規範和規則,但瀏覽器是我們所有人的現實,我希望他們會把它稱為HTTPS/2,並為大家節省了大量時間。 親愛的瀏覽器廠商,還不算太遲。 請聽聽理由,你是我們唯一的希望!
HTTP/2具有很多的性能優勢,特別是有機會在詢問用戶之前向用戶推送資源。 我不會詳細的寫這些好處,Ilya Grigorik已經做了一個非常棒的介紹。 作為一個快速的概述,最大的優化(對我們)包括:
請求/響應復用
伺服器推送
標題壓縮
流優先順序
更少的原始連接
嘿等一下,那個證書怎麼辦?
HTTP/2的一個鮮為人知的功能是,只要滿足某些標準,就可以將內容推送到同一個域中:
來源解析為相同的伺服器IP地址。
來源由相同的TLS證書覆蓋
所以,我們來看看我們目前的DNS:
嘿嘿嘿,那些IP匹配,他們有相同的證書!這意味著我們可以獲得HTTP/2伺服器的所有優勢,而不會對HTTP/1.1用戶造成影響。 HTTP/2得到推送,HTTP/1.1獲得域分片(通過sstatic.net)。我們還沒有部署伺服器推送,但是這一切都在準備中。
所以在性能方面,HTTPS只是一種手段。我還算滿意,我可以說,我們的主要驅動力是性能,而不是網站的安全性。我們希望安全,但是在我們的情況下,單是安全性不足以評判在我們的網路上部署HTTPS所用的時間投資。當您結合上述所有因素時,我們可以證明完成此項工作所需的大量時間和精力。在2013年,HTTP/2並不是很大的事情,但隨著支持的增加而改變,最終也成為我們為HTTPS投入時間的驅動力。
另外值得一提的是,在部署過程中,HTTP/2規模發生了很大變化。網路從SPDY移動到HTTP/2,從NPN到ALPN。我不會覆蓋所有,因為我們在這過程中沒有做任何事情。我們只是看著並受益匪淺,但網路巨人正在推動所有這一切。如果你好奇,Cloudflare可以很好的記錄這些進步。
HAProxy:提供HTTPS
我們在2013年在HAProxy中部署了初始HTTPS支持。為什麼選擇HAProxy?因為我們已經在使用它,並且在2013年(在2014年發布為GA)中添加了1.5版本的支持。我們有一段時間,在HAProxy前面的nginx(你可以在最後一篇博文中看到)。但是更簡單的往往更好,消除了很多conntrack,部署和一般的複雜性問題通常是一個好主意。
我不會在這裡覆蓋很多細節,因為沒有太多的東西要覆蓋。從1.5開始,HAProxy通過OpenSSL本身支持HTTPS,配置很簡單。我們的配置亮點是:
運行4個進程
1專用於HTTP/前端處理
2-4專用於HTTPS協商
HTTPS前端通過抽象命名的套接字連接到HTTP後端。這大大降低了開銷。
每個前端或「層」(我們有4:主,輔,Websockets和dev)具有相應的:443個監聽器。
我們在轉發到網路層以指示連接如何進入時,附加請求標頭(並且將發送 - 發送 - 不錯嘗試)。
我們使用Mozilla推薦的現代兼容性加密套件。注意:這不是我們CDN運行的套件。
HAProxy是一個比較簡單的第一步,它支持:443端點和有效的SSL證書。回想起來,這只是所需努力的一小部分。
上面描述的是邏輯布局...我們將在下面介紹一下這塊:
英文原文:https://nickcraver.com/blog/2017/05/22/https-on-stack-overflow/ 譯者:jianli
※Stack Overflow上部署HTTPS:長路盡頭(五)
※Python中本地時間轉換為UTC(協調世界時)
※使用Python,GeoJSON和GeoPandas開始地理空間分析
※測試Windows Subsystem for Linux
※詭異的Python整數
TAG:Python部落 |