nginx 伺服器僅代理我的遊戲伺服器

nginx 伺服器僅代理我的遊戲伺服器

我有客戶端連接到我的 WebSockets 遊戲伺服器來玩線上瀏覽器遊戲。遊戲伺服器在玩家開始遊戲時創建和銷毀,因此每個伺服器可以有一個我無法控制的不同IP位址。

我需要 WebSockets 是安全的(WSS),所以我有一個帶有 SSL 憑證的 nginx 代理程式。客戶端接收遊戲伺服器的 IP,但不是直接連線(不安全),而是透過我的 nginx 伺服器,將遊戲伺服器 IP 作為查詢參數。

問題是:現在任何人都可以使用我的 nginx 伺服器來代理他們選擇的任何 IP。我需要的是確保 nginx 僅代理的方法我的遊戲伺服器。

我無法控制遊戲伺服器 IP,因為它是外部主機,但我擁有遊戲伺服器代碼。我的 nginx 代理由我託管,但遊戲伺服器由提供者託管。

我的計劃是在遊戲伺服器和 nginx 上有一個共享金鑰,並用它加密所有流量,但我正在努力找出如何做到這一點。


這是我到目前為止所做的事情(基於在這個要點上):

我創建了自己的自簽名 CA 憑證:

openssl genrsa -des3 -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

我為遊戲伺服器創建了一個憑證:

openssl genrsa -out gameserver.key 2048
openssl req -new -key gameserver.key -out gameserver.csr
openssl x509 -req -in gameserver.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out gameserver.crt -days 500 -sha256

我對 nginx 伺服器做了同樣的事情(需要嗎?注意:不需要):

openssl genrsa -out nginx.key 2048
openssl req -new -key nginx.key -out nginx.csr
openssl x509 -req -in nginx.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out nginx.crt -days 500 -sha256

我的 nginx 設定是這樣的:

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 443 ssl;
        # these are for game client
        ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;

        location / {
            if ( $arg_host != "" ) {
                proxy_pass https://$arg_host:$arg_port;
            }
            proxy_ssl_certificate     nginx.crt;
            proxy_ssl_certificate_key nginx.key;

            proxy_ssl_trusted_certificate rootCA.crt;

            proxy_ssl_verify on;
            proxy_ssl_verify_depth 2;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
            proxy_read_timeout 86400;
        }
    }
}

gameserver.key我的遊戲伺服器是一個使用和 的WebSockets 伺服器gameserver.csr

但是,當我嘗試時,nginx 錯誤日誌顯示:

upstream SSL certificate verify error: (18:self signed certificate) while SSL handshaking to upstream

我不確定這是否可行,以及我哪裡出錯了?這唯一的文章我發現提到此錯誤表明遊戲伺服器憑證不受信任,但我不明白為什麼。

我也不確定Common Name創建證書時應該賦予什麼值(因為每個遊戲伺服器都在自己的 IP 上)以及這是否是一個問題。

答案1

我建議為後端設定內部憑證授權機構,並要求您的後端可以透過該憑證授權單位進行驗證,您可以引導這些憑證以包含它們的 IP,或使用通用主機名稱覆蓋 IP(我認為這會就夠了)。

  1. 創建一個僅限內部的 CA,將其稱為“遊戲伺服器後端”
  2. 建立一個僅供內部使用的伺服器證書,將其命名為“gameserver.auth.backend”
  3. 使用 gameserver.auth.backend 作為 websocket 節點程式上的憑證
  4. 告訴 nginx 進行驗證,用您指定的名稱(而不是 IP)覆蓋通用名稱
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 443 ssl;
        # these are for game client
        ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;

        location / {
            if ( $arg_host != "" ) {
                proxy_pass https://$arg_host:$arg_port;
            }

            proxy_ssl_verify on;
            proxy_ssl_verify_depth 2;
            proxy_ssl_name gameserver.auth.backend;
            proxy_ssl_server_name on;
            proxy_ssl_trusted_certificate GameserverCA.crt;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
            proxy_read_timeout 86400;
        }
    }
}

相關內容