сервер nginx, который проксирует только мои игровые серверы

сервер nginx, который проксирует только мои игровые серверы

У меня есть клиенты, подключающиеся к моему игровому серверу WebSockets для онлайн-браузерной игры. Игровые серверы создаются и уничтожаются, когда игроки начинают игру, и поэтому каждый сервер может иметь свой IP-адрес, который я не могу контролировать.

Мне нужно, чтобы WebSockets были безопасными (WSS), поэтому у меня есть прокси nginx с сертификатом SSL. Клиент получает 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;
        }
    }
}

Мой игровой сервер — это сервер WebSockets, использующий gameserver.keyи 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, назовите его «Gameserver Backend»
  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;
        }
    }
}

Связанный контент