仅代理我的游戏服务器的 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. 在你的 websocket 节点程序上使用 gameserver.auth.backend 作为证书
  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;
        }
    }
}

相关内容