Сервер nginx, который работает только с моими игровыми серверами.

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

Мне нужно, чтобы WebSockets были безопасными (WSS), поэтому у меня есть прокси nginx с SSL сертификат. Клиент получает IP-адрес игрового сервера, но вместо прямого подключения (небезопасно) он проходит через мой сервер nginx с IP-адресом игрового сервера в качестве параметра запроса.

Вот проблема: теперь любой может использовать мой сервер nginx для прокси для любой IP по их выбору. Мне нужен способ убедиться, что nginx проксирует только мои игровые серверы.

У меня нет контроля над IP-адресами игрового сервера, поскольку это внешний хост, но код игрового сервера принадлежит мне . Мой прокси-сервер nginx размещен у меня, но игровые серверы размещены у провайдера.

Мой план состоял в том, чтобы иметь общий секретный ключ на игровом сервере и nginx и шифровать им весь трафик, но я изо всех сил пытаюсь понять, как это можно сделать.


Вот что я сделал, чтобы far (на основе по этой сути ):

Я создал свой собственный самозаверяющий сертификат 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

Я не уверен, может ли это сработать, и где я ошибся? В единственной статье , где я обнаружил упоминание об этой ошибке, предполагается, что сертификат игрового сервера не является доверенным, но я не могу понять почему.

Я также не уверен, какое значение я должен указать для Общее имя при создании сертификатов (поскольку каждый игровой сервер имеет свой IP-адрес) и является ли это проблемой.

1
задан 2 December 2020 в 12:59
1 ответ

Я бы предложил настроить внутренний центр сертификации для серверных частей и потребовать, чтобы ваши серверные части могли быть проверены с помощью этого центра сертификации. Вы можете либо загрузить эти сертификаты, чтобы включить их IP, либо переопределить IP с общим именем хоста (которого, я думаю, будет достаточно).

  1. создайте только внутренний ЦС, назовите его "Gameserver Backend"
  2. создайте сертификат сервера только для внутреннего использования, назовите его "gameserver.auth.backend"
  3. используйте 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;
        }
    }
}
0
ответ дан 1 December 2020 в 15:54

Теги

Похожие вопросы