fragen stichworte

Nginx SNI und Letsencrypt unter FreeBSD; Falsches Zertifikat

Ich habe ein VPS mit 14 Domänen. Ich setze letskencrypt ein, um automatisch ein separates Zertifikat für jede Domäne mit allen darin enthaltenen Unterdomänen abzurufen. Ich habe also 14 Zertifikate. Natürlich ist es nicht möglich, alle Domänen in ein einziges Zertifikat zu setzen, da ich in Kürze die maximal 100 Domäne/Unterdomäne pro Zertifikat für Letsencrypt erreichen kann.

Ich war also einen Monat lang glücklich, bis ich herausfand, dass nginx für alle Domains falsche Zertifikate abgibt (mit Ausnahme derjenigen, die automatisch abgerufen wird - oder ich werde - als Standardserver für Port 443 festlegen). Nach vielen Kopfschmerzen fand ich heraus, dass jedes SSL-Zertifikat eine eigene IP-Adresse haben muss und keine gemeinsame. Dann habe ich auch herausgefunden, dass es SNI als Problemumgehung für dieses Problem gibt.

$ nginx -V
TLS SNI support enabled

Also, machen Sie die lange Geschichte kurz. Das Problem ist egal, was ich tue, denn nginx ist hartnäckig das falsche cert:

$ curl --insecure -v https://babaei.net 2>&1 | awk 'BEGIN { cert=0 }/^\* Server certificate:/{ cert=1 }/^\*/{ if (cert) print }'
* Server certificate:
*  subject: CN=babaei.net
*  start date: Aug 28 13:30:00 2016 GMT
*  expire date: Nov 26 13:30:00 2016 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Connection #0 to host babaei.net left intact

$ curl --insecure -v https://learnmyway.net 2>&1 | awk 'BEGIN { cert=0 }/^\* Server certificate:/{ cert=1 }/^\*/{ if (cert) print }'
* Server certificate:
*  subject: CN=babaei.net
*  start date: Aug 28 13:30:00 2016 GMT
*  expire date: Nov 26 13:30:00 2016 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Connection #0 to host learnmyway.net left intact

$ curl --insecure -v https://3rr0r.org 2>&1 | awk 'BEGIN { cert=0 }/^\* Server certificate:/{ cert=1 }/^\*/{ if (cert) print }'
* Server certificate:
*  subject: CN=babaei.net
*  start date: Aug 28 13:30:00 2016 GMT
*  expire date: Nov 26 13:30:00 2016 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Connection #0 to host 3rr0r.org left intact

Verstehen Sie mich nicht falsch, die eigentlichen Zertifikate sind genau das, was sie sein sollen:

$ openssl x509 -noout -subject -in/path/to/certs/babaei.net.pem
subject=/CN=babaei.net

$ openssl x509 -noout -subject -in/path/to/certs/learnmyway.net.pem
subject=/CN=learnmyway.net

$ openssl x509 -noout -subject -in/path/to/certs/3rr0r.org.pem
subject=/CN=3rr0r.org

Nehmen wir an, wir haben zwei Domains alpha.com und omega.com. Wie würden Sie SNI-fähiges nginx so konfigurieren, dass für jedes das richtige SSL-Zertifikat bereitgestellt wird?

server {
  server_tokens  off;

  listen  443 ssl http2;
  listen  [::]:443 ssl http2;
  server_name  www.alpha.com;

  ssl  on;
  ssl_certificate /path/to/alpha.com/cert.pem;
  ssl_certificate_key/path/to/alpha.com/key.pem;
}

server {
  server_tokens  off;

  listen  443 ssl http2;
  listen  [::]:443 ssl http2;
  server_name  www.omega.com;

  ssl  on;
  ssl_certificate /path/to/omega.com/cert.pem;
  ssl_certificate_key/path/to/omega.com/key.pem;
}

Vielen Dank

UPDATE: Dies war die ursprüngliche Konfiguration:

server {
    server_tokens   off;

    listen          80;
    listen          [::]:80;
    server_name     learnmyway.net;

    location/{
        return 301 https://www.$server_name$request_uri;  # enforce https/www
    }

    # Error Pages
    include/path/to/snippets/error;

    # Anti-DDoS
    include/path/to/snippets/anti-ddos;

    # letsencrypt acme challenges
    include/path/to/snippets/letsencrypt-acme-challenge;
}

server {
    server_tokens   off;

    listen          80;
    listen          [::]:80;
    server_name     *.learnmyway.net;

    location/{
        return 301 https://$host$request_uri;  # enforce https
    }

    # Error Pages
    include/path/to/snippets/error;

    # Anti-DDoS
    include/path/to/snippets/anti-ddos;

    # letsencrypt acme challenges
    include/path/to/snippets/letsencrypt-acme-challenge;
}


server {
    server_tokens   off;

    listen          443 ssl http2;
    listen          [::]:443 ssl http2;
    server_name     www.learnmyway.net;

    # Hardened SSL
    include                /path/to/snippets/hardened-ssl;
    ssl_certificate        /path/to/certs/learnmyway.net.pem;
    ssl_certificate_key    /path/to/keys/learnmyway.net.pem;
    ssl_trusted_certificate/path/to/certs/learnmyway.net.pem;

    #error_log     /path/to/learnmyway.net/log/www_error_log;
    #access_log    /path/to/learnmyway.net/log/www_access_log;

    root           /path/to/learnmyway.net/www/;
    index           index.html;

    # Error Pages
    include        /path/to/snippets/error;

    # Anti-DDoS
    include        /path/to/snippets/anti-ddos;

    # letsencrypt acme challenges
    include/path/to/snippets/letsencrypt-acme-challenge;

    # Compression
    include        /path/to/snippets/compression;

    # Static Resource Caching
    include        /path/to/snippets/static-resource-caching;
}

antworten

Sieht aus, als hätte @AlexeyTen recht. Durch Hinzufügen des folgenden Serverblocks wurde das Problem behoben:

server {
    server_tokens   off;

    listen          443 ssl http2;
    listen          [::]:443 ssl http2;
    server_name     learnmyway.net;

    # Hardened SSL
    include/path/to/snippets/hardened-ssl;
    ssl_certificate/path/to/certs/learnmyway.net.pem;
    ssl_certificate_key/path/to/keys/learnmyway.net.pem;
    ssl_trusted_certificate/path/to/certs/learnmyway.net.pem;

    return 301 https://www.$server_name$request_uri;  # enforce www
}

Mein Fehler: Da * ein Platzhalterzeichen ist, dachte ich, * .learnmyway.net werde auch learnmyway.net lösen. Es scheint, ich habe mich geirrt.