官术网_书友最值得收藏!

3.4 使用TLS保護服務

到目前為止,在遵循本章的示例時,你可能已經意識到,甚至已經被We b瀏覽器警告你訪問的We b服務是不安全的。大多數瀏覽器都會以某種方式提示你正在瀏覽一個使用HTTP而不是HTTPS的網站,可能是一個小圖標,也可能是一個全屏警告,提醒你在訪問網頁之前需要點擊。這是一個很好的提醒,所有的網頁都應該使用安全連接。當部署只能從本地設備訪問的We b服務時,這可能不重要,但在大多數情況下,確實會有用戶從另一臺設備通過互聯網訪問你的We b服務。在這些情況下,你應該為你的用戶提供HTTPS連接,以便他們輸入的數據在傳輸到Web服務器的途中是安全的。網頁瀏覽器顯示的警告也會讓用戶一眼就知道你是否關心他們的隱私。

幸運的是,使用Let's Encrypt(https://letsencrypt.org)提供正式簽名的證書非常容易。Let's Encrypt是由互聯網安全研究小組(Internet Security Research Group,ISRG)運營的一項服務。它旨在為在任何公共領域運行網站的任何人提供受信任的、免費的傳輸層安全(Transport Layer Security,TLS)證書。Let's Encrypt證書的有效期為三個月,這比許多付費提供商提供的證書短得多,因此續訂過程需要自動化,否則你將發現自己每三個月更新一次證書。幸運的是,Let's Encrypt本身提供了很好的選項來自動更新證書,甚至有像Caddy(https://caddyserver.com)這樣的Web服務器對管理員(或SRE)隱藏了證書更新過程。

對于使用OpenShift路由器部署的服務,可以在路由配置中提供TLS證書。在以下示例中,你將首先部署假證書,然后使用Let's Encrypt請求受信任證書。你可以使用非常相似的過程,通過路由提供來自受信任頒發者的自定義證書。

3.4.1 指定TLS證書

在研究Let's Encrypt頒發的證書的自動續期之前,先看一下如何在OpenShift中配置TLS路由:為此,首先為你使用的DNS名稱創建一個自簽名證書。本例在OpenShift Local集群上創建,基域名為apps-crc.testing,因此對于此集群中的路由的域名,不可能生成公開信任的證書。你可以使用任何域名運行此示例,但請注意,自簽名證書只用于幫助你理解該過程,而不能取代你的We b服務的受信任證書。

本章中部署的所有路由都使用相同的域名——platform-arcade.apps-crc.testing,因此你只需要創建并提供一個證書:

要創建自簽名證書,可以使用openssl命令行工具。執行如下命令生成證書:

這將創建一個證書和一個密鑰文件,你可以使用它們來加密服務的流量。為此,使用以下兩個命令重新創建game路由:

?指定路由類型edge,這意味著路由器將處理TLS握手。

?輸入上面生成的兩個文件。

你剛剛指定了用于游戲服務的HTTPS流量的證書和密鑰。現在你可以在路由規范中看到它們:

現在應該可以使用HTTPS方案訪問服務了。打開網頁瀏覽器,檢查是否可以訪問你的服務。在前面的示例中,可以訪問https://platform-arcade.apps-crc.testing/s3e。雖然它現在使用HTTPS,但Web瀏覽器仍然警告你該網頁正在使用自簽名證書。

3.4.2 將流量重定向到TLS路由

在當前配置中,使用HTTP而不是HTTPS方案訪問服務將不再可能。這允許你使用HTTP而不是HTTPS部署第二條路由。你還可以自動將用戶重定向到安全路由,這應該是大多數情況下的首選選項。為此,將insecureEdgeTerminationPolicy設置為Redirect。這個設置有三個不同的選項:

?None:默認配置。此路由只能連接到HTTPS服務。

?Allow:允許HTTP和HTTPS的流量。

?Redirect:在訪問HTTP方案時,Web服務器將客戶端重定向到HTTPS。

要更新此設置,請編輯路由,如下所示:

新的配置也將顯示在oc get route的TERMINATION列中:

現在,你可以使用Web瀏覽器調試工具的網絡部分或curl來測試和觀察重定向的工作流,如下面的清單所示:

?使用-k告訴curl信任自簽名證書,使用-i顯示標頭,使用-L跟蹤重定向。

?第一個響應是302,要求客戶端使用不同的URL執行相同的請求。

?該URL使用HTTPS方案,由使用HTTP方案的原始服務器返回。

?下一個請求被發送到服務器(3)返回的URL,并返回狀態碼200(OK)。

?返回包含游戲的網頁。

將用戶重定向到安全的HTTPS方案是一種很好的實踐,特別對于像游戲平臺這樣直接面向用戶的服務。使用重定向,用戶不需要關心或考慮We b服務使用的方案。例如,用戶不需要擔心輸入http://或https://。

既然你已經為其中一條路由啟用了TLS加密,那么另外兩條路由仍然使用未加密的HTTP。由于它們都共享相同的主機名,因此你可以重用相同的證書,而不需要創建或請求新的證書。

使用以下命令從游戲路由中提取TLS屬性,并將其應用于平臺和highscore路由,或者像之前使用game路由一樣重新創建路由:

現在你應該看到所有的路由都顯示“edge/Redirect”在TERMINATION列,檢查瀏覽器應該顯示你被重定向到正確的方案。由于你仍在使用自簽名證書,因此將出現一個警告。

3.4.3 Let's Encrypt受信任證書

現在你已經知道了如何使用自簽名證書為給定路由配置證書,接下來可以使用相同的過程在路由中使用正式簽名的受信任證書。但是,當證書即將過期時(或者更糟的是,當有人第一次注意到證書已過期時)手動更新證書是一個煩瑣的過程,即使證書的有效期超過90天,就像前面示例中的自簽名證書一樣。假設你的集群服務于多個路由,或者你維護多個集群,并且需要關心所有這些證書。

典型的SRE任務是自動化此過程,這樣你就不必再手動續訂證書了。如果你決定使用Let's Encrypt,那么Let's Encrypt服務本身(自動請求證書)或社區已經提供了許多自動化過程,因為該服務非常流行。

對于OpenShift,你可以使用cert-manager(https://cert-manager.io)為TLS加密流量配置的所有公開服務自動請求證書。

使用Let's Encrypt的cert-manager需要一個具有公共可訪問域名的集群來執行證書續訂。使用OpenShift Local可以,但是很難,所以為了練習這一部分,你應該使用第2章中描述的方法之一部署一個可公開訪問的集群。

要在OpenShift集群上安裝cert-manager,可以使用OperatorHub上提供的cert-manager Operator。

在OpenShift控制臺中打開OperatorHub頁面,搜索cert-manager Operator,選中并單擊Install進行安裝,如圖3-5所示。

圖3-5:從OperatorHub安裝cert-manager Operator

默認選項包括觀察所有要處理的資源的命名空間,這對于這個用例來說很好。

在OpenShift 4.10中,cert-manager Operator處于技術預覽階段,因此在即將到來的OpenShift版本中用法可能會略有不同。

cert-manager當前的一個限制是它只能處理ingress資源,而不能直接處理路由。這是因為cert-manager是為支持所有Kubernetes安裝而構建的,其中入口是默認資源。路由作為OpenShift的一個概念,目前還不被支持。

由于OpenShift也支持ingress資源,并且可以通過路由器公開它們,因此這不是一個問題,但它確實需要你用ingress替換路由。

首先,刪除之前為公開服務而創建的路由:

現在,你需要告訴cert-manager你希望如何向ingress提供證書。它支持許多不同的配置選項,你可以在cert-manager文檔(https://oreil.ly/kY3Sf)中查找這些選項。由于你現在想要使用Let's Encrypt自動更新,你需要將其配置為使用自動證書管理環境(Automatic Certificate Management Environment,ACME)協議。

為此,創建一個ClusterIssuer資源并指定要使用的ACME端點。為了進行實驗,你可以使用Let's Encrypt提供的staging端點。一旦驗證了工作流的工作,你就可以用生產端點替換它,以獲得受信任證書。

創建一個包含以下內容的文件,用Let's Encrypt Staging環境配置ClusterIssuer:

?ingress將引用ClusterIssuer的名稱,以告訴cert-manager使用此配置來獲取證書。

?要使用的ACME目錄的URL。這是Let's Encrypt提供的staging端點。

?配置操作員使用HTTP01挑戰來更新證書。此配置是必需的,因此OpenShift可以通過路由器將挑戰流量路由到證書管理器。

使用oc apply將資源應用到OpenShift集群:

你也可以直接從GitHub倉庫(https://github.com/OperatingOpenShift/s3e)中創建它,其中包含使用以下URL的示例應用程序:

現在創建一個ingress,指示cert-manager使用你創建的ClusterIssuer獲取新證書。下面的ingress配置替換了示例應用中的三條路由:

?該注釋將指示cert-manager使用ClusterIssuer le-staging獲取新證書。

?應用程序可用的主機名。

?引用由游戲平臺組成的不同服務的路徑。以前使用路由公開的每個服務都被替換為此ingress中的路徑。

?與?中指定的主機名相同。這將指示cert-manager證書必需對哪些主機名有效。

使用oc apply創建ingress:

一旦創建,OpenShift路由器將檢測ingress配置并生成路由以公開指定的服務。你需要選擇一個在集群內有效的主機名,與前面使用的主機名相似或相等,這樣路由器才能生成有效的路由。

當在更新過程中運行oc get ingress時,你應該找到一個由cert-manager創建的ingress來執行HTTP01挑戰。OpenShift路由器將通過路由公開這個ingress。使用oc get route來執行這個過程:

你可以在OpenShift控制臺中查看cert-manager Operator頁面的All Instances部分,按照更新過程進行操作,如圖3-6所示。根據資源的類型,一旦所有資源的狀態轉移到Approved、Ready和Valid,你就可以期望完成證書續訂。

圖3-6:列出由cert-manager Operator管理的所有實例

續訂過程完成后,cert-manager將把證書存儲在ingress中指定的密鑰platform-secret中。這使得路由器能夠生成路由資源,最終公開街機游戲平臺的服務:

路由的TLS配置將被ingress中引用的密鑰內容填充。如你所見,路由器再次配置為使用邊緣終止并將請求重定向到HTTPS端點。

使用Curl驗證證書是由Let's Encrypt staging端點生成的,盡管它仍然不是一個受信任證書:

在驗證證書續訂過程是否有效之后,你可以用生產端點替換staging端點。要做到這一點,應用下面的ClusterIssuer,不同之處在于ACME目錄URL:

現在更新ingress中的注釋,告訴cert-manager使用新的ClusterIssuer:

更新過程將再次啟動,更新密鑰,最后更新生成的路由資源中的TLS配置。更新完成后,在瀏覽器中訪問平臺路由的URL將顯示你現在使用的是受信任證書,如圖3-7所示,由瀏覽器URL欄中的盾牌圖標表示。

圖3-7:為示例應用程序使用受信任證書

使用此設置,你可以通過更改ingress對象上的注釋,在staging環境和生產環境之間進行切換,甚至可以在不同的TLS證書提供程序之間進行切換。

要對續訂過程中出現的問題進行故障排除,可以在OpenShift控制臺中列出的cert-manager創建的資源里查找錯誤消息。cert-manager在文檔(https://oreil.ly/4fBY8)中提供了解決此類問題的指南。你可以按照這些步驟來解決最常見的問題。

3.4.4 與服務的加密通信

3.4.3節討論了集群外部的客戶端與集群之間通信的加密。TLS已在路由器上終止(邊緣終止),請求以未加密的方式轉發到We b服務。

在某些情況下,這是可以的,但是在許多情況下,你還希望路由器和OpenShift集群的pod之間的通信是加密的,也就是說,路由器應該使用HTTPS來轉發請求。要實現這一點,你有兩個不同的選擇。你可以不在路由器上進行TLS終止,而是將HTTPS請求轉發給目標服務(透傳,passthrough),或者終止請求并向目標服務發送一個新的HTTPS請求(重加密,reencrypt)。不同終止模式的對比如圖3-8所示。

圖3-8:TLS終止模式的比較

透傳

使用透傳TLS終止模式的服務必須自己處理TLS終止。路由器不解密請求,直接將它們傳遞給接收服務。作為應用程序一部分的某種Web服務器需要接收TLS加密的流量并相應地對其進行解密。這意味著你使用的Web服務必須支持通過HTTPS進行通信,并且你必須向服務提供證書。如果你使用Let's Encrypt的cert-manager Operator,則可以將證書的請求和續訂留給cert-manager,并通過將證書掛載到你的Web服務的pod中,使用它寫入密鑰的證書。

作為透傳路由的示例,你可以使用平臺部署,當在預定義路徑上掛載證書時,平臺部署支持TLS通信。

由cert-manager創建的密鑰platform-secret與ingress位于相同的命名空間中。當請求新證書時,operator負責更新密鑰。

現在你可以把這個密鑰文件掛載到/etc/nginx/certs/tls.crt/etc/nginx/certs/tls.key放在平臺pod中,平臺NGINX服務希望證書存在。

?volumeMounts指定應該掛載證書的位置。將證書掛載到/etc/nginx/certs文件夾中,這是應用程序容器期望它們存在的位置。

?secretName引用你在ingress中指定的密鑰。

服務如何知道它應該使用這些證書?該平臺服務基于NGINX,并使用以下配置同時監聽HTTP(端口8080)和HTTPS(端口4443)。當沒有掛載證書時,服務使用容器鏡像中包含的自簽名默認證書。如果沒有這些文件,則服務將無法啟動:

下一步是在平臺pod中公開用于HTTPS通信的端口,而不是HTTP端口。將platform服務中的端口和目標端口由8080修改為4443。

最后,更新ingress中的終止注釋和規則?;诼窂降穆酚刹豢赡苁褂猛競鹘K止,因為路由器不解密請求,因此無法知道請求的路徑。這意味著你需要從ingress中刪除除平臺規則之外的所有規則。其他服務將無法訪問。

?將終止注釋更改為passthrough,以建議OpenShift創建透傳路由。

?將端口號修改為公開的TLS端口號。

?將pathType更改為ImplemationSpecific。

?將路徑本身更改為空字符串。

僅更改服務上的“targetPort”設置就足夠了,這樣你就不必在ingress中更新端口以切換端口。但是,端口號的一致性有助于理解和調試系統,因此你還應該更新用于路由器和服務之間通信的端口。

現在你應該看到路由被更新為使用passthrough終止:

為了驗證路由現在使用TLS與pod進行通信,平臺服務修改日志輸出以輸出所使用的協議。你可以跟蹤該服務的日志,并從瀏覽器或第二個終端向路由器發送請求,應該會看到類似以下的輸出:

字符串TLSv1.2告訴你TLS已在pod中終止。如果沒有在本節中更改的設置,日志行將類似于以下內容:

NGINX默認不記錄是否使用TLS。變量$ssl_protocol被添加到NGINX配置的默認日志行中,專門用于可視化終止設置之間的差異。

如果應用程序需要透傳,則需要將街機平臺的架構更改為基于DNS名稱(而不是路徑)進行路由。對于在服務之間進行加密通信的需求,另一種選擇是使用重加密終止模式。

重加密

對于邊緣和透傳終止模式,只有一個證書用于將請求從客戶機加密到它終止的地方。終止要么發生在路由器中,要么發生在運行服務本身的pod中。對于重加密終止模式,第二個證書開始起作用。呈現給外部客戶端的證書將保持不變,但現在路由器將通過HTTPS與服務的pod進行通信,使用不同的TLS證書。此證書是路由器需要信任的證書,并且對服務的內部DNS名稱有效。要生成一個這樣的證書,請在平臺服務中添加以下注釋:

你現在應該看到一個新的密鑰出現了。更新平臺部署以使用此密鑰來服務TLS加密流量:

?Let's Encrypt TLS密鑰用于從客戶端到路由器的外部流量。

?生成的TLS密鑰用于從路由器到平臺服務的內部流量。

?參考?中所列的內部通信密鑰。

最后,更新ingress的終止注釋,重加密路由器和平臺pod之間的流量:

?指示OpenShift為重加密終止設置路由。

?重加密允許你再次使用基于路徑的路由,因此你可以重新添加額外的路徑。

現在你應該看到終止模式更改為在生成的路由上重加密:

在觀察日志的同時查詢服務應該會再次顯示請求正在使用TLS:

重加密終止模式與自動生成的證書相結合提供了一種簡單的方法來加密從客戶端到后端pod的流量,同時仍然允許對路由器中的請求有一些了解。這允許你使用基于路徑的路由,并且仍然對端到端的流量進行加密。

因為TLS流量只啟用了平臺服務,所以只有平臺服務的流量可以被服務。你可以將記分服務和游戲服務分離到使用邊緣終止的單獨ingress中。

主站蜘蛛池模板: 连城县| 铁岭市| 甘孜县| 天柱县| 临邑县| 永定县| 晴隆县| 长治县| 威信县| 池州市| 察哈| 昌邑市| 台中市| 上虞市| 乡城县| 博乐市| 宁国市| 谷城县| 永丰县| 河池市| 江北区| 改则县| 清涧县| 天峻县| 平和县| 宁国市| 繁昌县| 营口市| 庆安县| 左云县| 龙江县| 油尖旺区| 正定县| 丰顺县| 通榆县| 辛集市| 开阳县| 重庆市| 寻乌县| 扬中市| 贡嘎县|