У меня есть клиенты, подключающиеся к моему игровому серверу 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-адрес) и является ли это проблемой.
Я бы предложил настроить внутренний центр сертификации для серверных частей и потребовать, чтобы ваши серверные части могли быть проверены с помощью этого центра сертификации. Вы можете либо загрузить эти сертификаты, чтобы включить их IP, либо переопределить 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;
}
}
}