透過反向 Proxy 公開 Azure Spring Apps

Azure Spring Apps
Azure 應用程式閘道
Azure Front Door

當您在 Azure Spring Apps 中裝載應用程式或微服務時,不一定會想要將它們直接發佈至網際網路。 您可以改為透過反向 Proxy 公開它們。 這種方法可讓您將服務放在應用程式前面。 此服務可以定義跨領域功能,例如 Web 應用程式防火牆 (WAF) 功能,以協助保護您的應用程式、負載平衡、路由、要求篩選和速率限制。

當您在 Azure Spring Apps 前部署一般反向 Proxy 服務,例如 Azure 應用程式閘道Azure Front Door 時,您應該確保您的應用程式只能透過反向 Proxy 來連線。 此防護有助於防止惡意用戶嘗試略過WAF或規避節流限制。

Azure DDoS 保護 (結合應用程式設計最佳做法) 可提供增強的 DDoS 風險降低功能,以針對 DDoS 攻擊提供更多的防禦。 您應該在任何周邊虛擬網路上啟用 Azure DDOS 保護。

本文說明如何強制執行存取限制,讓裝載在 Azure Spring Apps 中的應用程式只能透過反向 Proxy 服務存取。 強制執行這些限制的建議方式取決於您的 Azure Spring Apps 執行個體部署方式,以及您使用的反向 Proxy。 視您是在虛擬網路內部或外部部署而定,需要考慮的不同點。 本文提供四個案例的相關信息

  • 在虛擬網路 內部署 Azure Spring Apps,並從 網路內私下存取您的應用程式。

    • 您可以控制應用程式執行所在的虛擬網路。 使用網路安全組 (NSG) 等原生 Azure 網路功能來鎖定存取權,只允許反向 Proxy。

    • 您可以使用 Azure 應用程式閘道 公開應用程式到因特網,然後套用適當的存取限制來鎖定它。 本文稍後的案例 1說明此方法。

    • 您無法直接使用 Azure Front Door,因為它無法連線到私人虛擬網路中的 Azure Spring Apps 實例。 Azure Front Door 只能透過公用IP位址或使用私人端點的服務來連線到後端。 當您有多個區域部署 Azure Spring Apps 且需要全域負載平衡時,您仍然可以透過 應用程式閘道 公開 Azure Spring Apps 實例。 若要達成此案例,您會將 Azure Front Door 放在 應用程式閘道 前面。 本文稍後的案例 2說明此方法。

  • 如果您將端點指派給因特網,請在虛擬網路 外部部署 Azure Spring Apps,並將您的應用程式直接發佈至因特網。

    • 您不會控制網路,且無法使用NSG來限制存取。 只允許反向 Proxy 存取您的應用程式需要 Azure Spring Apps 本身的方法。

    • 由於您的應用程式可公開連線,因此您可以使用 應用程式閘道 或 Azure Front Door 作為反向 Proxy。 本文稍後的案例 3 將說明 應用程式閘道 方法。 本文稍後的案例 4說明 Azure Front Door 方法。

    • 您可以視需要使用這兩種方法的組合。 如果您使用 應用程式閘道 和 Azure Front Door,請在案例 2 中使用的兩個反向 Proxy 之間使用相同的存取限制。

注意

您可以使用其他反向 Proxy 服務,而不是 應用程式閘道 或 Azure Front Door。 針對以 Azure 虛擬網路為基礎的區域服務,例如 Azure API 管理,指導方針類似於 應用程式閘道 的指導方針。 如果您使用非 Azure 服務,則指引類似於 Azure Front Door 的指引。

案例比較

下表提供 Azure Spring Apps 四個反向 Proxy 設定案例的簡短比較。 如需每個案例的完整詳細數據,請參閱本文的適當章節。

案例 部署 服務 組態
1 虛擬網路內部 應用程式閘道 - 針對您想要公開的每個應用程式,將端點指派給端點,並將適當的自定義網域或網域對應至該應用程式。
- 針對 應用程式閘道 中的後端集區,請使用每個應用程式的指派端點。
- 在服務運行時間子網中,新增 NSG 以只允許來自 應用程式閘道 子網、應用程式子網和 Azure 負載平衡器的流量。 封鎖所有其他流量。
2 虛擬網路內部 Azure Front Door 應用程式閘道 - 使用案例 1 所述的相同方法,限制 應用程式閘道 與 Azure Spring Apps 之間的存取。
- 在 應用程式閘道 子網上,建立 NSG 只允許具有服務卷標的AzureFrontDoor.Backend流量。
- 在 應用程式閘道 中建立自定義 WAF 規則,以確認 X-Azure-FDID HTTP 標頭包含您的特定 Azure Front Door 實例識別碼。
3 虛擬網路外部 使用 Spring Cloud Gateway 應用程式閘道 - 使用 Spring Cloud Gateway 公開後端應用程式。 只有 Spring Cloud Gateway 應用程式需要指派的端點。 所有後端應用程式的自定義網域都應該對應至這個單一 Spring Cloud Gateway 應用程式。
- 針對 應用程式閘道 中的後端集區,請使用 Spring Cloud Gateway 應用程式的指派端點。
- 在 Spring Cloud 閘道中,將XForwarded Remote Addr路由述詞設定為 應用程式閘道 的公用 IP 位址。
- 選擇性地,在您的 Spring Framework 應用程式中,將 server.forward-headers-strategy 應用程式屬性設定為 FRAMEWORK
4 虛擬網路外部 搭配 Spring Cloud Gateway 的 Azure Front Door - 使用 Spring Cloud Gateway 公開後端應用程式。 只有 Spring Cloud Gateway 應用程式需要指派的端點。 所有後端應用程式的自定義網域都應該對應至這個單一 Spring Cloud Gateway 應用程式。
- 針對 Azure Front Door 中的後端集區或來源,請使用 Spring Cloud Gateway 應用程式的指派端點。
- 在 Spring Cloud Gateway 中 XForwarded Remote Addr ,將路由述詞設定為 Azure Front Door 的所有輸出 IP 範圍,並將此設定保持在最新狀態。 Header設定路由述詞,以確保 X-Azure-FDID HTTP 標頭包含您唯一的 Azure Front Door 識別碼。
- 選擇性地,在您的 Spring Framework 應用程式中,將 server.forward-headers-strategy 應用程式屬性設定為 FRAMEWORK

注意

設定組態之後,請考慮使用 Azure 原則資源鎖定,以防止意外或惡意變更,而可能會略過反向 Proxy,並直接公開應用程式。 此保護僅適用於 Azure 資源(特別是 NSG),因為 Azure Spring Apps 內的 設定不會顯示在 Azure 控制平面上。

虛擬網路內的部署

在虛擬網路中部署 Azure Spring Apps 時,它會使用 兩個子網

  • 包含相關網路資源的服務運行時間子網
  • 裝載程式代碼的應用程式子網

因為服務運行時間子網包含用來連線到應用程式的負載平衡器,因此您可以在此服務運行時間子網上定義 NSG,只允許來自反向 Proxy 的流量。 當您封鎖所有其他流量時,虛擬網路中的任何人都無法存取您的應用程式,而不需要通過反向 Proxy。

重要

將子網存取限制為僅反向 Proxy 可能會導致依賴從用戶端裝置直接連線到應用程式的功能失敗,例如 記錄串流。 請考慮針對這些用戶端裝置特別新增 NSG 規則,而且只有在需要特定直接存取時才新增。

您想要透過反向 Proxy 公開的每個應用程式都應該有一個指派的端點,讓反向 Proxy 可以連線到虛擬網路中的應用程式。 針對每個應用程式,您也應該 對應它所使用的自定義網域 ,以避免覆寫反向 Proxy 中的 HTTP Host 標頭,並將原始主機名保持不變。 此方法可避免發生中斷的 Cookie 或重新導向 URL 無法正常運作的問題。 如需詳細資訊,請參閱 主機名保留

注意

或者,除了 NSG 之外,您也可以遵循在虛擬網路外部部署 Azure Spring Apps 時的指引。或者,若要深入防禦,您也可以遵循指導方針。 本節說明如何使用 Spring Cloud Gateway 來達成存取限制,這也會影響後端應用程式,因為它們不再需要指派的端點或自定義網域。

案例 1:使用 應用程式閘道 作為反向 Proxy

案例 1 說明如何使用 應用程式閘道 公開您的應用程式到因特網,然後套用適當的存取限制來鎖定它。

下圖描述案例 1 的架構:

Diagram that shows the use of Azure Application Gateway with Azure Spring Apps in a virtual network.

下載此架構的 Visio 檔案

當 應用程式閘道 位於 Azure Spring Apps 實例前面時,您會使用 Spring Cloud Gateway 應用程式的指派端點作為後端集區。 範例端點為 myspringcloudservice-myapp.private.azuremicroservices.io。 端點會解析為服務運行時間子網中的私人IP位址。 因此,若要限制存取,您可以將 NSG 放在具有下列輸入安全性規則的服務運行時間子網上(將拒絕規則設為最低優先順序):

動作 來源類型 來源值 通訊協定 目的地連接埠範圍
允許 IP 位址 應用程式閘道 子網的私人IP範圍(例如 , 10.1.2.0/24)。 TCP 80, 443 (或適當時的其他埠)
允許 IP 位址 Azure Spring Apps 中應用程式子網的私人IP範圍(例如 , 10.1.1.0/24)。 TCP *
允許 服務標籤 AzureLoadBalancer Any *
拒絕 服務標籤 Any Any *

案例 1 設定可確保服務運行時間子網只允許來自下列來源的流量:

  • 專用 應用程式閘道 子網
  • 應用程式子網(需要兩個 Azure Spring Apps 子網之間的雙向通訊。
  • Azure 負載平衡器(這是一般 Azure 平臺需求)

所有其他流量都會遭到封鎖。

案例 2:同時使用 Azure Front Door 和 應用程式閘道 作為反向 Proxy

如先前所述,您無法將 Azure Front Door 直接放在 Azure Spring Apps 前面,因為它無法連線到您的專用虛擬網路。 (Azure Front Door Standard 或 進階版 可以連線到虛擬網路中的私人端點,但 Azure Spring Apps 目前不提供私人端點支援。如果您仍想要使用 Azure Front Door,例如在不同 Azure 區域中的多個 Azure Spring Apps 實例之間要求全域負載平衡,您仍然可以透過 應用程式閘道 公開您的應用程式。 若要達成此案例,您會將 Azure Front Door 放在 應用程式閘道 前面。

下圖描述案例 2 的架構:

Diagram that shows the use of Azure Front Door and Azure Application Gateway with Azure Spring Apps in a virtual network.

下載此架構的 Visio 檔案

案例 2 組態會以與案例 1 相同的方式,實作 應用程式閘道 與 Azure Spring Apps 之間的存取限制。 您可以使用適當的規則,將 NSG 放在服務運行時間子網上。

在案例 2 中,您也必須確保 應用程式閘道 只接受來自 Azure Front Door 實例的流量。 Azure Front Door 檔說明 如何鎖定後端的存取權,只允許 Azure Front Door 流量。 當後端 應用程式閘道 時,您可以實作這項限制,如下所示:

虛擬網路外部的部署

當您在虛擬網路外部部署 Azure Spring Apps 時,您無法使用原生 Azure 網路功能,因為您不會控制網路。 相反地,您必須對應用程式本身套用必要的存取限制,以只允許來自反向 Proxy 的流量。 如果您有許多應用程式,此方法可能會增加複雜度,而且有風險,無法適當地設定每個應用程式。

使用 Spring Cloud Gateway 公開並協助保護您的應用程式

若要從個別應用程式的開發人員移除訪問控制的責任,您可以使用 Spring Cloud Gateway 來套用跨領域限制。 Spring Cloud Gateway 是常用的 Spring 專案,您可以部署至 Azure Spring Apps,就像任何其他應用程式一樣。 藉由使用 Spring Cloud Gateway,您可以將自己的應用程式保留在 Azure Spring Apps 實例內,並確保它只能透過共用的 Spring Cloud Gateway 應用程式來存取。 接著,您可以使用路由述詞來設定此應用程式,這是 Spring Cloud Gateway 的內建功能。 路由述詞可以使用傳入 HTTP 要求的不同屬性來判斷是否要將要求路由傳送至後端應用程式或拒絕它。 述詞可以使用屬性,例如用戶端IP位址、要求方法或路徑、HTTP 標頭等等。

重要

當您以這種方式將 Spring Cloud Gateway 放在後端應用程式前面時,您必須 將所有自定義網域對應至 Spring Cloud Gateway 應用程式 ,而不是將後端應用程式對應至後端應用程式。 否則,當任何自定義網路變數的要求傳入時,Azure Spring Apps 不會先將連入流量路由傳送至 Spring Cloud Gateway。

此方法假設您的反向 Proxy 不會覆寫 HTTP Host 標頭,並保留原始主機名。 如需詳細資訊,請參閱 主機名保留

此模式通常使用。 為了本文的目的,我們假設您透過 Spring Cloud Gateway 公開您的應用程式。 我們預期您會使用其路由述詞來設定必要的存取限制,以確保只允許來自反向 Proxy 的要求。 即使您未使用 Spring Cloud Gateway,仍適用相同的一般原則。 不過,您必須根據本文稍後討論的相同 X-Forwarded-For HTTP 標頭,將自己的要求篩選功能建置至您的應用程式。

注意

Spring Cloud Gateway 本身也是反向 Proxy,可提供路由、要求篩選和速率限制等服務。 如果此服務提供案例所需的所有功能,您可能不需要其他反向 Proxy,例如 應用程式閘道 或 Azure Front Door。 仍然考慮使用其他 Azure 服務的最常見原因是它們同時提供 WAF 功能,或 Azure Front Door 所提供的全域負載平衡功能。

描述 Spring Cloud Gateway 的運作方式不在本文的討論範圍內。 這是一項高度彈性的服務,您可以透過程式碼或組態進行自定義。 為了保持簡單,本文僅說明不需要變更程式碼的純組態驅動方法。 您可以在已部署的 Spring Cloud Gateway 應用程式中加入傳統 application.propertiesapplication.yml 檔案,以實作此方法。 您也可以使用 Azure Spring Apps 中的組態伺服器,將組態檔外部化為 Git 存放庫,來實作 方法。 在下列範例中,我們會使用 YAML 語法來實 application.yml 作 方法,但對等 application.properties 的語法也有效。

將要求路由傳送至您的應用程式

根據預設,當您在 Azure Spring Apps 中的應用程式沒有指派端點或為其設定的自定義網域時,就無法從外部連線。 當應用程式 向 Spring Cloud Service Registry 註冊本身時,Spring Cloud Gateway 可以探索應用程式,以便使用路由規則將流量轉送至正確的目的地應用程式。

因此,Azure Spring Apps 中唯一需要為其指派端點的應用程式就是您的 Spring Cloud Gateway 應用程式。 此端點可從外部連線。 您不應該將端點指派給任何其他應用程式。 否則,您可以直接連線到應用程式,而不是透過 Spring Cloud Gateway,進而允許略過反向 Proxy。

透過 Spring Cloud Gateway 公開所有已註冊應用程式的簡單方式,是使用 DiscoveryClient 路由定義定位器 ,如下所示:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          predicates:
          - Path="/"+serviceId+"/**" # Include the Path predicate to retain default behavior
          - (...)

或者,您可以藉由定義應用程式特定的路由,選擇性地透過 Spring Cloud Gateway 公開特定應用程式:

spring:
  cloud:
    gateway:
      routes:
      - id: my_app1_route
        uri: lb://MY-APP1
        filters:
        - RewritePath=/myapp1(?<segment>/?.*), $\{segment}
        predicates:
        - (...)

透過探索定位器方法和明確路由定義,您可以使用路由述詞來拒絕無效的要求。 在此情況下,我們會使用該功能來封鎖來自 Azure Spring Apps 前面預期反向 Proxy 的要求。

使用 X-Forwarded-For HTTP 標頭限制存取

當您將應用程式部署到 Azure Spring Apps 時,HTTP 用戶端或反向 Proxy 不會直接連線到應用程式。 網路流量會先通過內部輸入控制器。

注意

此方法表示您在要求管線中有三個或甚至四個反向 Proxy,再於後續案例中連線到您的應用程式。 這些是可能的反向 Proxy:Azure Front Door 和/或 應用程式閘道、輸入控制器和 Spring Cloud Gateway 應用程式。

由於額外的服務,直接網路用戶端的IP位址一律是內部 Azure Spring Apps 元件。 IP 位址絕不 是邏輯 用戶端,例如您預期呼叫應用程式的反向 Proxy。 您無法使用用戶端 IP 位址進行存取限制。 您也無法使用 Spring Cloud Gateway 的內 RemoteAddr 建路由述 詞來進行要求篩選,因為它預設會使用用戶端 IP 位址。

幸運的是,Azure Spring Apps 一律會將邏輯用戶端的IP位址新增至 X-Forwarded-For 要求上的 HTTP 標頭至您的應用程式。 標頭的最後一個 (最右邊) 值 X-Forwarded-For 一律包含邏輯用戶端的IP位址。

若要根據 X-Forwarded-For 標頭篩選要求,您可以使用內 XForwarded Remote Addr 建路由述詞。 此述詞可讓您設定反向 Proxy 的 IP 位址或 IP 範圍清單,以做為最右邊的值。

注意

路由 XForwarded Remote Addr 述詞需要 Spring Cloud Gateway 3.1.1 版或更新版本。 3.1.1 版可在 Spring Cloud 2021.0.1 版定型中使用。 如果您無法使用對 Spring Cloud Gateway 應用程式進行一些程式碼變更,以修改路由述詞決定用戶端 IP 位址的方式RemoteAddr。 您可以達到與路由述詞相同的結果 XForwarded Remote Addr 。 將 RemoteAddr 路由述詞設定為使用 XForwardedRemoteAddressResolver ,並將後者設定為 maxTrustedIndex 的值 1。 此方法會將 Spring Cloud Gateway 應用程式設定為使用標頭最右邊的值 X-Forwarded-For 作為邏輯用戶端 IP 位址。

設定您的應用程式以查看正確的主機名和要求URL

當您使用 Spring Cloud Gateway 時,需要考慮一個重要因素。 Spring Cloud Gateway 會將輸出要求上的 HTTP Host 標頭設定為應用程式實例的內部 IP 位址,例如 Host: 10.2.1.15:1025。 應用程式程式代碼所看到的要求主機名不再是瀏覽器所傳送之要求的原始主機名,例如 contoso.com。 在某些情況下,此結果可能會導致 Cookie 中斷或重新導向 URL 無法正常運作等問題。 如需這些類型問題的詳細資訊,以及如何設定反向 Proxy 服務,例如 應用程式閘道 或 Azure Front Door 以避免它們,請參閱主機名保留

Spring Cloud Gateway 會在標頭Forwarded提供原始主機名。 它也會設定其他標頭,例如 X-Forwarded-PortX-Forwarded-ProtoX-Forwarded-Prefix 因此您的應用程式可以使用它們來重新建構原始要求URL。 在 Spring Framework 應用程式中,您可以藉由在應用程式屬性中將 設定設為 server.forward-headers-strategyFRAMEWORK ,來自動達成此設定。 (請勿將此值設定為 NATIVE。否則,會使用其他標頭,而不需要將必要的 X-Forwarded-Prefix 標頭納入考慮。如需詳細資訊,請參閱 在前端 Proxy 伺服器後方執行。 使用此組態時, HttpServletRequest.getRequestURL 方法會將所有這些標頭納入考慮,並傳回瀏覽器所傳送的確切要求 URL。

注意

您可能會想要在 Spring Cloud Gateway 中使用 PreserveHostHeader 篩選器 ,這會在輸出要求上維護原始主機名。 不過,此方法無法運作,因為該主機名已對應為 Spring Cloud Gateway 應用程式上的自定義網域。 最後一個後端應用程式無法再對應一次。 此設定會造成 HTTP 404 錯誤,因為後端應用程式會拒絕傳入要求。 它無法辨識主機名。

案例 3:搭配 Spring Cloud Gateway 使用 應用程式閘道

案例 3 說明如何使用 應用程式閘道 作為透過 Spring Cloud 閘道端點公開連線應用程式的反向 Proxy。

下圖描述案例 3 的架構:

Diagram that shows the use of Azure Application Gateway with Azure Spring Apps outside of a virtual network.

下載此架構的 Visio 檔案

當 應用程式閘道 位於 Azure Spring Apps 實例前面時,您可以使用 Spring Cloud Gateway 應用程式的指派端點作為後端集區。 範例端點為 myspringcloudservice-mygateway.azuremicroservices.io。 由於 Azure Spring Apps 部署在虛擬網路外部,因此此 URL 會解析為公用 IP 位址。 當後端集區是公用端點時,應用程式閘道 會使用其前端公用IP位址來連線到後端服務。

若要只允許來自 應用程式閘道 實例的要求到達 Spring Cloud Gateway,您可以設定XForwarded Remote Addr路由述詞。 設定述詞只允許來自您 應用程式閘道 專用公用IP位址的要求,如下列範例所示:

(...)
predicates:
- XForwardedRemoteAddr="20.103.252.85"

案例 4:搭配 Spring Cloud 閘道使用 Azure Front Door

案例 4 說明如何使用 Azure Front Door 作為透過 Spring Cloud 閘道端點公開連線應用程式的反向 Proxy。

下圖描述案例 4 的架構:

Diagram that shows the use of Azure Front Door with Azure Spring Apps outside of a virtual network.

下載此架構的 Visio 檔案

類似於案例 3,此設定會使用 Spring Cloud Gateway 應用程式的公用 URL 作為 Azure Front Door 中的後端集區或來源。 範例端點為 https://myspringcloudservice-mygateway.azuremicroservices.io

由於 Azure Front Door 是具有許多 邊緣位置的全域服務,因此會使用許多 IP 位址與其後端集區通訊。 Azure Front Door 檔說明 如何鎖定後端的存取權,只允許 Azure Front Door 流量。 不過,在此案例中,您不會控制部署應用程式的 Azure 網路。 不幸的是,您無法使用 AzureFrontDoor.Backend 服務標籤來取得保證為最新狀態的輸出 Azure Front Door IP 位址完整清單。 相反地,您必須下載 Azure IP 範圍和服務標籤、尋找 AzureFrontDoor.Backend 區段,並將數位XForwarded Remote Addr中的所有IP範圍addressPrefixes複製到路由述片語態。

重要

Azure Front Door 所使用的 IP 範圍可能會變更。 授權 的 Azure IP 範圍和服務標籤 檔案會每週發佈,並記錄 IP 範圍的任何變更。 為了確保您的設定保持最新狀態,請每週確認 IP 範圍,並視需要更新您的設定(理想情況下,以自動化方式)。 若要避免這種方法的維護額外負荷,您可以使用 NSG 搭配 AzureFrontDoor.Backend 服務標籤,在虛擬網路中部署 Azure Spring Apps 與其他所述的案例。

由於 Azure Front Door IP 範圍與其他組織共用,因此您也必須根據 X-Azure-FDID 包含您唯一的 Front Door ID HTTP 標頭,確定您只能鎖定特定 Azure Front Door 實例的存取權。 您可以使用路由述 詞來限制存取 Header ,除非指定的 HTTP 標頭具有特定值,否則會拒絕要求。

在此案例中,您的 Spring Cloud Gateway 路由述片語態看起來可能如下列範例所示:

(...)
predicates:
- XForwardedRemoteAddr="13.73.248.16/29","20.21.37.40/29","20.36.120.104/29","20.37.64.104/29", ...(and many more)...
- Header="X-Azure-FDID", "e483e3cc-e7f3-4e0a-9eca-5f2a62bde229"

參與者

Microsoft 會維護此內容。 下列參與者開發了原始內容。

主體作者:

若要查看非公用LinkedIn設定檔,請登入LinkedIn。

下一步