
オンライン ブラウザー ゲーム用に、WebSocket ゲーム サーバーに接続するクライアントがあります。ゲーム サーバーは、プレイヤーがゲームを開始すると作成および破棄されるため、各サーバーには制御できない異なる IP アドレスが設定されます。
WebSocket をセキュア (WSS) にする必要があるため、SSL 証明書付きの nginx プロキシを使用します。クライアントはゲーム サーバーの IP を受け取りますが、直接接続する (安全ではない) 代わりに、ゲーム サーバーの IP をクエリ パラメータとして nginx サーバーを経由します。
問題は、誰でも私のnginxサーバーを使って好きなIPにプロキシできるということです。必要なのは、nginxがプロキシするIPアドレスが私のゲームサーバー。
ゲーム サーバーの 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
私のゲーム サーバーは、 と を使用する WebSocket サーバーですgameserver.csr
。
しかし、試してみると、nginx エラー ログに次のように表示されます。
upstream SSL certificate verify error: (18:self signed certificate) while SSL handshaking to upstream
これがうまくいくかどうかわかりません。どこが間違っていたのでしょうか?記事のみこのエラーはゲーム サーバーの証明書が信頼されていないことを示唆しているようですが、その理由はわかりません。
Common Name
また、証明書を作成するときに にどのような値を入力すればよいのか (各ゲーム サーバーは独自の IP 上にあるため)、またこれが問題になるかどうかもわかりません。
答え1
私が提案するのは、バックエンドの内部証明機関を設定し、バックエンドがその証明機関で検証できることを要求することです。これらの証明書をブートストラップして IP を含めるか、IP を共通のホスト名で上書きします (これで十分だと思います)。
- 内部専用の CA を作成し、「Gameserver Backend」という名前を付けます。
- 内部専用のサーバー証明書を作成し、「gameserver.auth.backend」という名前を付けます。
- Websocketノードプログラムの証明書としてgameserver.auth.backendを使用します。
- 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;
}
}
}