nginx try_files-Umleitung mit falschem Schema hinter dem SSL-Terminierungs-Load-Balancer (Haproxy)

8

Ich habe einen Nginx 1.6.2-Server, der als Backend hinter einem Load Balancer ausgeführt wird, der die SSL-Terminierung durchführt. Die gesamte Kommunikation mit den Backend-Servern erfolgt über HTTP.

Diagramm, was los ist:

          /--http---> frontend:80  --\
client --+                            +--http---> backend:8000
          \--https--> frontend:443 --/

                      LOAD BALANCER                BACKENDS

Zu Testzwecken habe ich momentan nur ein Backend. Der Load Balancer führt HAProxy 1.5 aus, über das ich etwas Kontrolle habe.

Ich habe eine ziemlich typische try_filesDirektive in meinem serverBlock in der Backend-Nginx-Konfiguration:

server {
    server_name frontend;
    ...
    try_files $uri $uri/ =404;
    ...
}

Wenn ich jetzt standardmäßig auf ein Verzeichnis ohne abschließenden Schrägstrich zugreife, z. B. https://frontend/somedirmöchte nginx eine HTTP 301-Umleitung an eine absolute URL wie senden http://frontend:8000/somedir/.

Ich kann nginx dazu bringen, die 8000-Portnummer mit wegzulassen port_in_redirect off.

Allerdings kann ich das http://Schema zu Beginn der Umleitung, die Nginx generiert, nicht korrigieren . Das Beste, was ich von Nginx erwarten kann, ist eine Weiterleitung von https://frontend/somedirnach http://frontend/somedir/, wodurch SSL effektiv entfernt wird!

Der Load Balancer sendet einen X-Forwarded-ProtoHeader, aber ich sehe keine Möglichkeit für Nginx, ihn beim Erstellen seiner Umleitung zu konsultieren. Tatsächlich gibt es eine Antwort von 2012, die besagt, dass Nginx dies nicht kann, und die Lösung besteht darin, den Load Balancer durch Nginx zu ersetzen. IMHO ist dies zu trivial, um einen solch drastischen Stapelwechsel zu rechtfertigen.

Hat sich hier seit 2012 etwas geändert? Ich will nicht wirklich diese Umleitungen auf der HAProxy Ebene neu zu schreiben: Ist vorsätzliche HTTPS zu HTTP - Redirects von der Web - Anwendung könnte „re-HTTPSed“ bekommen , wenn ich nur immer neu schreiben das Schema für die Location:Antwort - Header das gleiche wie das Schema zu sein Die Anfrage wurde mit gestellt.

BEARBEITEN:

Hier ist eine minimierte Konfiguration, die zeigt, dass nginx absolute Location:URLs erzeugt . Beachten Sie, dass keine Umschreibungen vorgenommen wurden.

user nobody nobody;
worker_processes auto;
worker_rlimit_nofile 4096;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # TODO: Tune fastcgi_buffers/other buffers

    # Configure keepalive connections
    keepalive_timeout 15;
    keepalive_requests 1000;

    # Hide server version.
    server_tokens off;

    # Do not allow any directory indexes anywhere.
    # This is the default, but it is here for extra paranoia.
    autoindex off;

    # gzip text content.
    gzip on;
    gzip_vary on;
    gzip_disable "msie6";
    gzip_comp_level 2;
    gzip_min_length 1024;
    gzip_types  text/css
                text/plain
                text/xml
                application/json
                application/javascript;

    server {
        listen 8000 default_server;

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name localhost;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

Und wenn Sie Curl verwenden, um die Header anzuzeigen - beachten Sie, dass ich ein Verzeichnis testdirunter erstellt habe /usr/share/nginx/html:

[myuser@dev nginx]$ curl -i http://localhost:8000/testdir
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 26 Mar 2015 14:35:49 GMT
Content-Type: text/html
Content-Length: 178
Location: http://localhost:8000/testdir/
Connection: keep-alive

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
mutron
quelle
nginx wants to send an HTTP 301 redirect to an absolute URL- nginx macht das nur, wenn Sie eine explizite Umschreiberegel haben - bitte zeigen Sie Ihre vollständige Konfiguration.
AD7six
Ich habe die Konfiguration hinzugefügt und sie verkleinert, um dieses Problem zu veranschaulichen. Ich schreibe nicht explizit um.
Mutron
1
Sie sollten Ihren Balancer so konfigurieren, dass er das Protokoll im Location:Header ersetzt, da nginx keine Ahnung hat, was das ursprüngliche Protokoll war.
Alexey Ten
2
@AlexeyTen Möchten Sie das als Antwort posten, damit ich es genehmigen kann? Ich habe auch in Nginx keinen Weg gefunden, dies zu tun, daher scheint eine Änderung am Load Balancer tatsächlich der einzige Weg zu sein.
Mutron
1
Dies ist immer noch ein Fehler mit der neuesten nginX-Version! Weiß jemand, ob es bereits einen Fehlerbericht gibt? Konnte keinen finden.
Roel van Duijnhoven

Antworten:

1

Schneller Vorlauf bis 2019 und Sie können:

absolute_redirect off; 
port_in_redirect off;

Aus Dokumenten fürabsolute_redirect :

Wenn deaktiviert, sind von nginx ausgegebene Weiterleitungen relativ.

Danila Vershinin
quelle
-1

Sie müssen den Load Balancer anweisen http, httpsin den Anforderungen wie folgt neu zu schreiben :

proxy_redirect http:// $scheme://;
HostFission
quelle