
Ich habe Clients, die sich für ein Online-Browserspiel mit meinem WebSocket-Spieleserver verbinden. Spieleserver werden erstellt und zerstört, wenn Spieler Spiele starten, und daher kann jeder Server eine andere IP-Adresse haben, die ich nicht kontrollieren kann.
Ich brauche sichere WebSockets (WSS), also habe ich einen Nginx-Proxy mit einem SSL-Zertifikat. Der Client erhält die IP des Spieleservers, aber anstatt eine direkte Verbindung herzustellen (unsicher), geht er über meinen Nginx-Server mit der IP des Spieleservers als Abfrageparameter.
Hier ist das Problem: Jeder kann jetzt meinen Nginx-Server verwenden, um eine beliebige IP-Adresse zu übermitteln. Was ich brauche, ist eine Möglichkeit, sicherzustellen, dass Nginx nur eine Proxy-Adresse angibtMeinSpieleserver.
Ich habe keine Kontrolle über die IPs des Spieleservers, da es sich um einen externen Host handelt, aber ich besitze den Code des Spieleservers. Mein Nginx-Proxy wird von mir gehostet, aber die Spieleserver werden von einem Anbieter gehostet.
Mein Plan bestand darin, einen gemeinsamen geheimen Schlüssel auf dem Spieleserver und Nginx zu haben und damit den gesamten Datenverkehr zu verschlüsseln, aber ich weiß nicht, wie das gemacht werden könnte.
Hier ist, was ich bisher getan habe (basierendzu diesem Kern):
Ich habe mein eigenes selbstsigniertes CA-Zertifikat erstellt:
openssl genrsa -des3 -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt
Ich habe ein Zertifikat für den Spieleserver erstellt:
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
Dasselbe habe ich für den Nginx-Server gemacht ( ist das nötig? Hinweis: nicht nötig):
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
Meine Nginx-Konfiguration sieht dann ungefähr so aus:
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;
}
}
}
Mein Spieleserver ist ein WebSocket-Server, der gameserver.key
und verwendet gameserver.csr
.
Wenn ich es jedoch versuche, zeigen die Nginx-Fehlerprotokolle Folgendes:
upstream SSL certificate verify error: (18:self signed certificate) while SSL handshaking to upstream
Ich bin mir nicht sicher, ob das funktionieren kann und wo ich einen Fehler gemacht habe?nur ArtikelIch habe festgestellt, dass die Erwähnung dieses Fehlers darauf schließen lässt, dass das Zertifikat des Spieleservers nicht vertrauenswürdig ist, aber ich kann nicht herausfinden, warum.
Ich bin auch nicht sicher, welchen Wert ich beim Erstellen der Zertifikate eingeben soll Common Name
(da jeder Spieleserver seine eigene IP hat) und ob das ein Problem ist oder nicht.
Antwort1
Ich würde vorschlagen, eine interne Zertifizierungsstelle für die Backends einzurichten und zu verlangen, dass Ihre Backends bei dieser Zertifizierungsstelle verifiziert werden können. Sie können diese Zertifikate entweder so bootstrappen, dass sie ihre IP enthalten, oder die IP durch einen gemeinsamen Hostnamen überschreiben (was meiner Meinung nach ausreichen würde).
- Erstellen Sie eine nur interne CA und nennen Sie sie „Gameserver Backend“.
- Erstellen Sie ein ausschließlich internes Serverzertifikat und nennen Sie es „gameserver.auth.backend“.
- Verwenden Sie gameserver.auth.backend als Zertifikat für Ihr WebSocket-Knotenprogramm.
- sagen Sie nginx, dass es dies validieren und den allgemeinen Namen durch den von Ihnen angegebenen Namen ersetzen soll (anstelle der 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;
}
}
}