WebSockets

此範例將逐步說明 Envoy 可以設定為代理 WebSockets 的一些方式。

它示範了終止 WebSocket 連線(無論是否使用 TLS),並提供了一些基本範例,說明如何代理到加密和未加密的上游 Socket。

警告

為了簡單起見,這裡提供的範例不會驗證任何用戶端憑證,也不會驗證任何提供的憑證。

當使用 TLS 時,強烈建議您盡可能驗證所有憑證。

您也應該在控制連線兩端或可以使用相關協定的情況下驗證用戶端

步驟 1:為 wss 建立憑證檔案

將目錄變更為 Envoy 儲存庫中的 examples/websocket

$ pwd
envoy/examples/websocket
$ mkdir -p certs
$ openssl req -batch -new -x509 -nodes -keyout certs/key.pem -out certs/cert.pem
Generating a RSA private key
..................................................................................................................+++++
......+++++
writing new private key to 'certs/key.pem'
-----
$ openssl pkcs12 -export -passout pass: -out certs/output.pkcs12 -inkey certs/key.pem -in certs/cert.pem

步驟 2:建置並啟動沙箱

這會啟動四個監聽 localhost 連接埠 10000150002000030000 的代理。

它還會啟動兩個上游服務,一個是 ws,另一個是 wss

上游服務分別在連接埠 80443 的內部 Docker 網路中監聽。

Socket 伺服器是非常簡單的實作,它們只是輸出 [ws] HELO[wss] HELO 作為對任何輸入的回應。

$ docker compose pull
$ docker compose up --build -d
$ docker compose ps

            Name                             Command               State            Ports
---------------------------------------------------------------------------------------------------
websocket_proxy-ws_1                /docker-entrypoint.sh /usr ... Up      0.0.0.0:10000->10000/tcp
websocket_proxy-ws-route_1          /docker-entrypoint.sh /usr ... Up      0.0.0.0:15000->10000/tcp
websocket_proxy-wss_1               /docker-entrypoint.sh /usr ... Up      0.0.0.0:20000->10000/tcp
websocket_proxy-wss-passthrough_1   /docker-entrypoint.sh /usr ... Up      0.0.0.0:30000->10000/tcp
websocket_service-ws_1              websocat -E ws-listen:0.0. ... Up
websocket_service-wss_1             websocat wss-listen:0.0.0. ... Up

步驟 3:測試代理 ws -> ws

監聽連接埠 10000 的代理會在沒有 TLS 的情況下終止 WebSocket 連線,然後代理到上游 Socket,同樣沒有 TLS

為了讓 Envoy 終止 WebSocket 連線,必須設定 upgrade_configsHttpConnectionManager 中,如提供的 ws -> ws 組態 中所示

 1static_resources:
 2  listeners:
 3  - address:
 4      socket_address:
 5        address: 0.0.0.0
 6        port_value: 10000
 7    filter_chains:
 8    - filters:
 9      - name: envoy.filters.network.http_connection_manager
10        typed_config:
11          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
12          stat_prefix: ingress_ws_to_ws
13          upgrade_configs:
14          - upgrade_type: websocket
15          route_config:
16            name: local_route
17            virtual_hosts:
18            - name: app
19              domains:
20              - "*"
21              routes:
22              - match:
23                  prefix: "/"
24                route:
25                  cluster: service_ws
26          http_filters:
27          - name: envoy.filters.http.router
28            typed_config:
29              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

您可以依照下列步驟開始與 Socket 進行互動式工作階段

$ docker run -ti --network=host solsson/websocat ws://127.0.0.1:10000
HELO
[ws] HELO
GOODBYE
[ws] HELO

輸入 Ctrl-c 結束 Socket 工作階段。

步驟 4:測試特定路由上的代理 ws -> ws

監聽連接埠 15000 的代理會在特定路由 /ws 上終止沒有 TLS 的 WebSocket 連線,然後代理到同樣沒有 TLS 的上游 Socket。

為了讓 Envoy 終止 WebSocket 連線,必須設定 upgrade_configsRouteAction 中,如提供的 ws -> ws 組態 中所示

1              routes:
2              - match:
3                  prefix: "/ws"
4                route:
5                  cluster: service_ws
6                  upgrade_configs:
7                  - upgrade_type: websocket

您可以依照下列步驟開始與 Socket 進行互動式工作階段

$ docker run -ti --network=host solsson/websocat ws://127.0.0.1:15000/ws
HELO
[ws] HELO
GOODBYE
[ws] HELO

$ curl https://127.0.0.1:15000
NotWebSocket

$ curl https://127.0.0.1:15000/ws
Only WebSocket connections are welcome here

輸入 Ctrl-c 結束 Socket 工作階段。

步驟 5:測試代理 wss -> wss

監聽連接埠 20000 的代理會使用 TLS 終止 WebSocket 連線,然後代理到上游 TLS WebSocket。

除了 upgrade_configsHttpConnectionManager 中之外,wss -> wss 組態 還會將 TLS transport_socket 新增至 listenercluster

您可以依照下列步驟開始與 Socket 進行互動式工作階段

$ docker run -ti --network=host solsson/websocat --insecure wss://127.0.0.1:20000
HELO
[wss] HELO
GOODBYE
[wss] HELO

輸入 Ctrl-c 結束 Socket 工作階段。

步驟 6:測試 wss 直通代理

監聽連接埠 30000 的代理會將所有 TCP 流量傳遞到上游 TLS WebSocket。

wss 直通 組態 不需要 TLSHTTP 設定,而是使用簡單的 tcp_proxy

您可以依照下列步驟開始與 Socket 進行互動式工作階段

$ docker run -ti --network=host solsson/websocat --insecure wss://127.0.0.1:30000
HELO
[wss] HELO
GOODBYE
[wss] HELO

輸入 Ctrl-c 結束 Socket 工作階段。

另請參閱

保護 Envoy 快速入門指南

保護 Envoy 的主要概念概述。

雙重代理沙箱

使用 mTLS 搭配非 HTTP 流量,透過驗證和相互驗證來保護代理之間流量的範例。

TLS 沙箱

使用 Envoy 的各種 TLS 終止模式範例。