Nginx liefert Inhalte vom falschen „virtuellen Host“, während auf https zugegriffen wird

7

Ich habe einen Server, auf dem sowohl Nginx als auch Apache in einem Proxy-Setup ausgeführt werden. Nginx liefert den statischen Inhalt und Apache den dynamischen Inhalt, der wirklich gut funktioniert.

Dieses Setup hostet derzeit zwei Versionen derselben Site. Nennen wir sie Production.com und Staging.com.

Ich habe gerade die Einrichtung der Website product.com mit SSL abgeschlossen, was ebenfalls sehr gut funktioniert, aber festgestellt, dass mir der Inhalt des Webstamms von Production.com bereitgestellt wird, wenn ich auch mit SSL zu staging.com navigiere , was offensichtlich falsch ist.

Mir wurde gesagt, dass ich einen Standardhandler sowohl für SSL als auch für Nicht-SSL verwenden soll, um dieses Verhalten zu beseitigen, aber hier habe ich Probleme.

Im Moment habe ich diese Konfiguration in nginx.conf enthalten

default_80.conf
server {
    listen 80;
    server_name "";
    return 444;
}
default_443.conf
server {
    listen 443 default_server ssl;
    server_name "";
    return 444;
}
staging.com.conf
server {

    listen 80;
    server_name staging.com;
    access_log /var/log/nginx/staging.com.log;

    # static content folders
    location ^~ /(images|css|js) {
            root /var/www/staging.com/current;
            access_log /var/log/nginx/staging.com.static.log;
    }

    # static content files
    location ~* \.(js|css|rdf|xml|ico|txt|jpg|gif|png|jpeg)$ {
            root /var/www/staging.com/current;
            access_log /var/log/nginx/staging.com.static.log;
    }

    # proxy the rest to apache
    location / {

        proxy_pass         http://127.0.0.1:8080/;
        proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

        client_max_body_size       10m;
        client_body_buffer_size    128k;

        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;

        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
    }
}
Production.com.conf
server {

    listen 80;
    server_name production.com;
    rewrite ^       https://$server_name$request_uri? permanent;
}

server {

    listen 443 ssl;
    server_name production.com;
    access_log /var/log/nginx/production.com.log;

    ssl_certificate /etc/httpd/conf.d/SSL/ev.crt;
    ssl_certificate_key /etc/httpd/conf.d/SSL/server.key;
    keepalive_timeout 60;

    # static content folders
    location ^~ /(images|css|js) {
            root /var/www/production.com/current;
            access_log /var/log/nginx/production.com.static.log;
    }

    # static content files
    location ~* \.(js|css|rdf|xml|ico|txt|jpg|gif|png|jpeg)$ {
            root /var/www/production.com/current;
            access_log /var/log/nginx/production.com.static.log;
    }

    # proxy the rest to apache
    location / {

        # proxy settings
        proxy_pass         http://127.0.0.1:8080/;
        proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

        client_max_body_size       10m;
        client_body_buffer_size    128k;

        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;

        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
    }

}

Diese Einstellung beendet alle Arten von SSL-Zugriff auf eine der beiden Sites. Wenn ich die Direktive "default_server" aus der default_443.conf entferne, funktioniert sie stattdessen für beide Sites.

Es stellt sich also die Frage, wie ich den SSL-Zugriff ( https://staging.com gibt 444 zurück) für staging.com deaktivieren und auf Production.com aktivieren kann.

Mit freundlichen Grüßen Lars

Lars
quelle
Testen Sie dies mit Windows XP und IE? Es wird nicht funktionieren.
Eltern
Nicht wirklich, nein. Windows 7 und Chrome
Lars
Okay, stellen Sie nur sicher, dass Sie nicht auf einer Plattform getestet haben, die wahrscheinlich nie funktioniert hätte.
Eltern

Antworten:

6

Stellen Sie zunächst sicher, dass Ihre Version von Nginx SNI unterstützt, falls Sie eine dieser seltsamen Distributionen verwenden (die TLS-SNI-Unterstützung sollte oben aktiviert sein):

nginx -V

Ich habe das Setup unten veröffentlicht. Hier sind die Ergebnisse auf meiner Box (/var/www/production/index.html enthält PRODUCTION und /var/www/staging/index.html, STAGING).

http://192.168.56.101 Verbindungsreset (444)
https://192.168.56.101 Verbindungsreset (444)
http://staging.example.com STAGING
https://staging.example.com Umleitung zu http
http: // Production.example.com- Umleitung zu https
https://production.example.com PRODUCTION

Als Referenz habe ich die stabile Version von Nginx aus den Debian-Repositories (0.7.67) verwendet, aber ich habe ein sehr ähnliches Setup für 1.0. Etwas, das fast genauso funktioniert. Wenn Sie es nicht zum Laufen bringen können, teilen Sie uns bitte Ihre genaue Version mit.

In Ihrem Fall möchten Sie wahrscheinlich beide Standardeinstellungen in default_server ändern. Möglicherweise möchten Sie das Umschreiben auch dauerhaft machen und es möglicherweise in eine Rückgabe 301 ändern, wenn Ihre Nginx-Version dies zulässt.


/ etc / nginx / sites-enabled / default

server {
    listen 80 default;
    return 444;
}

server {
    listen 443 default;
    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    return 444;
}

/ etc / nginx / sites-enabled / Produktion

server {
    listen   80; ## listen for ipv4
    server_name production.example.com;
    rewrite ^ https://production.example.com$request_uri?;
}

server {
    listen  443;
    server_name production.example.com;
    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    keepalive_timeout 60;

    location / {
            proxy_pass      http://127.0.0.1:81;
            proxy_set_header        Host    $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

/ etc / nginx / sites-enabled / staging

server {
    listen  80;
    server_name staging.example.com;
    keepalive_timeout 60;

    location / {
            proxy_pass      http://127.0.0.1:81;
            proxy_set_header        Host    $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen   443; ## listen for ipv4
    server_name staging.example.com;
    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    keepalive_timeout 60;

    rewrite ^(.*) http://staging.example.com$1;
}

/ etc / apache2 / sites-enabled / Produktion

<VirtualHost *:81>
    ServerAdmin webmaster@localhost
    ServerAlias production.example.com

    DocumentRoot /var/www/production
    <Directory />
            Options FollowSymLinks
            AllowOverride None
    </Directory>
    <Directory /var/www/production>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Order allow,deny
            Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

/ etc / apache2 / sites-enabled / staging

<VirtualHost *:81>
    ServerAdmin webmaster@localhost
    ServerAlias staging.example.com

    DocumentRoot /var/www/staging
    <Directory />
            Options FollowSymLinks
            AllowOverride None
    </Directory>
    <Directory /var/www/staging>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Order allow,deny
            Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

/etc/apache2/ports.conf

NameVirtualHost *:81
Listen 81
Eltern
quelle
Dieser Ausschnitt: server { listen 443 default; ssl on; ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; return 444; }... ist erstaunlich bei der Reduzierung der Belastung durch übermäßige Spinnen- / Bodenbildung, danke! +1
Plasmid87
1
das Hinzufügen defaultzum listenhat den Trick getan !!
Maxmitch
0

Ich (mit Hilfe von 3molo im IRC) habe es gelöst, indem ich einen Serverblock mit ssl für staging.com hinzugefügt und HTTP neu geschrieben habe. Dies ist meiner Meinung nach eine genehmigte Problemumgehung.

server {
    listen 443 ssl;
    server_name staging.com;

    ssl_certificate /etc/httpd/conf.d/SSL/ev.crt;
    ssl_certificate_key /etc/httpd/conf.d/SSL/server.key;
    keepalive_timeout 60;

    rewrite ^       http://$server_name$request_uri? permanent;
}

Das Problem bleibt jedoch weiterhin bestehen. Warum um alles in der Welt stellt Nginx Inhalte bereit, wenn $ http_host und Servername nicht übereinstimmen? Wenn es jemanden gibt, der die Antwort auf diese Frage hat, würde ich sie gerne hören.

Lars
quelle
1
Ich habe oben mit weiteren Informationen geantwortet, aber warum nginx irgendetwas bedienen würde, wenn der Host nicht übereinstimmt: Standardmäßig bedient nginx den ersten gefundenen Serverblock, unabhängig davon, ob es eine server_name-Klausel hat oder nicht, vorausgesetzt, es ist kein default_server definiert in einem anderen Serverblock.
Eltern
Das ist ein seltsames Design. Um ehrlich zu sein, klingt es wirklich lächerlich.
Lars
-1

Wenn staging.com und Production.com auf dieselben IP-Adressen verweisen, liegt dies außerhalb Ihrer Kontrolle, da SSL ausgehandelt wird, bevor der Host-Header vom Client gesendet wird.

Wenn möglich, verwenden Sie eine IP pro Site. Wenn nicht, können Sie möglicherweise "if $ host = staging.com .." im Serverkontext für Production.com verwenden.

3molo
quelle
1
Das ist einfach falsch. Ich kann das Problem oben nicht sehen, aber es ist heutzutage definitiv möglich, vhosts mit SSL zu verwenden.
Eltern
Wenn Sie SNI ja, was nicht alle Browser können. Überprüfen Sie meine Ansprüche, bevor Sie abstimmen, Sir, bitte.
3molo
Und wenn Sie sich die Kommentare ansehen, verwendet er keinen Browser aus dem Jahr 1800. Bearbeiten: Ich habe Ihre Behauptungen überprüft, indem ich das OP gefragt habe!
Eltern
1
Nein, und Sie fragen es auch nicht in Ihrer Frage. Sie sagen nur, dass es außerhalb seiner Kontrolle liegt. Wissen wir, dass er keine Wurzel in seiner eigenen Box hat? Bitte lassen Sie uns von diesem dummen Argument auf die Frage kommen.
Eltern
1
Wenn Sie sich selbst bearbeiten, um klarer zu sein, werde ich die Ablehnung entfernen, ich bin kein Arschloch. Aber im Moment geben Sie keine Informationen darüber an, warum dies nicht funktioniert, Sie beziehen sich überhaupt nicht auf SNI, Sie erwähnen nichts über OpenSSL oder die Kompilierungsoptionen von Nginx, daher halte ich es für schlecht und irreführend Antworten.
Eltern