server nginx care doar proxy-uri la serverele mele de joc (Administrarea sistemului, Nginx, Criptare)

edbentley a intrebat.
a intrebat.

Am clienți care se conectează la serverul meu de joc WebSockets pentru un joc de browser online. Serverele de joc sunt create și distruse atunci când jucătorii încep jocurile și, prin urmare, fiecare server poate avea o adresă IP diferită pe care nu o pot controla.

Am nevoie ca WebSockets să fie securizat (WSS), așa că am un proxy nginx cu un certificat SSL. Clientul primește IP-ul serverului de joc, dar în loc să se conecteze direct (nesigur), trece prin serverul meu nginx cu IP-ul serverului de joc ca parametru de interogare.

Iată care este problema: oricine poate folosi acum serverul meu nginx pentru a face proxy către orice IP pe care îl alege. Am nevoie de o modalitate de a mă asigura că nginx face proxy doar către serverele de joc.

Nu am controlul asupra IP-urilor serverelor de joc, deoarece este o gazdă externă, dar dețin codul serverului de joc. Proxy-ul meu nginx este găzduit de mine, dar serverele de joc sunt găzduite de un furnizor.

Planul meu era să am o cheie secretă partajată pe serverul de joc și pe nginx și să criptez tot traficul cu aceasta, dar mă străduiesc să aflu cum se poate face acest lucru.


Iată ce am făcut până acum (bazat pe pe acest gist):

Mi-am creat propriul certificat CA auto-semnat:

openssl genrsa -des3 -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Am creat un certificat pentru serverul de joc:

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

Am făcut același lucru pentru serverul nginx (este necesar acest lucru? notă: nu este necesar):

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

Configurația mea nginx este atunci ceva de genul următor:

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;
        }
    }
}

Serverul meu de joc este un server WebSockets care folosește gameserver.key și gameserver.csr.

Cu toate acestea, atunci când încerc, jurnalele de eroare nginx arată:

upstream SSL certificate verify error: (18:self signed certificate) while SSL handshaking to upstream

Nu sunt sigur dacă acest lucru poate funcționa, și unde am greșit? singurul articol pe care l-am găsit care menționează această eroare sugerează că certificatul serverului de joc nu este de încredere, dar nu-mi dau seama de ce.

De asemenea, nu sunt sigur ce valoare ar trebui să pun pentru Common Name la crearea certificatelor (din moment ce fiecare server de joc este pe propriul IP) și dacă aceasta este o problemă sau nu.

Comentarii

  • Te-ai uitat la modulul nginx secure link? –  > Por Michael Hampton.
  • Traficul de la nginx către backend este, de asemenea, criptat? V-ați uitat la certificatele de client pentru proxy docs.nginx.com/nginx/admin-guide/security-controls/… –  > Por Jacob Evans.
  • @MichaelHampton Mulțumesc pentru sugestie, dar se pare că se bazează pe URL-uri? Nu îmi este clar cum ar putea funcționa pentru WebSockets –  > Por edbentley.
  • WebSocket-ul tău are un URL! –  > Por Michael Hampton.
  • @JacobEvans Am încercat să folosesc certificate de client și am actualizat întrebarea cu cât de departe am ajuns. –  > Por edbentley.
1 răspunsuri
Jacob Evans

Ceea ce aș sugera este să configurați o autoritate de certificare internă pentru backend-uri și să solicitați ca backend-urile dvs. să poată fi verificate cu această autoritate de certificare, puteți fie să bootstrap aceste certificate pentru a include IP-ul lor, fie să înlocuiți IP-ul cu un nume de gazdă comun (care cred că ar fi suficient).

  1. creați o autoritate de certificare internă, numiți-o „Gameserver Backend”.
  2. creați un certificat de server doar intern, numiți-l „gameserver.auth.backend”.
  3. folosiți gameserver.auth.backend ca certificat în programul de noduri websocket
  4. spuneți-i lui nginx să valideze în funcție de acesta, înlocuind numele comun cu cel pe care l-ați specificat (în loc de 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;
        }
    }
}

Comentarii

  • Ah, era o problemă cu CN, la care nu am acordat suficientă atenție înainte. Acum funcționează, mulțumesc! –  > Por edbentley.