Frage Wie umschreiben Sie den Domain-Teil von Set-Cookie in einem nginx Reverse Proxy?


Ich habe einen einfachen nginx Reverse Proxy:

server {
  server_name external.domain.com;
  location / {
    proxy_pass http://backend.int/;
  }
}

Das Problem ist, dass Set-Cookie Antwortheader enthalten ;Domain=backend.int, weil das Backend nicht weiß, dass es umgekehrt proxied ist.

Wie kann ich Nginx den Inhalt der schreiben Set-Cookie Antwortheader ersetzen ;Domain=backend.int mit ;Domain=external.domain.com?

Vorbei am Host Header unverändert ist in diesem Fall keine Option.

Apache httpd hat diese Funktion für eine Weile, siehe ProxyPassReverseCookieDomain, aber ich kann keinen Weg finden, dasselbe in nginx zu tun.


24
2018-06-08 11:06


Ursprung


Warum ist das Übergeben des Hostheaders keine Option? Imo der Host-Teil des Headers ist für solche Dinge gemacht. Wenn Sie übergeben müssen, welcher Proxy verwendet wurde, sollten Sie zusätzliche Header angeben. - jojoo
Angenommen, Sie haben einen Legacy-Server, der virtuelles Hosting ausführt und Sie möchten Nginx davor platzieren, um einige dieser Dienste in einer neuen Domäne zu veröffentlichen. Angenommen, Sie können die Konfiguration des Legacy-Servers nicht ändern (oder nicht). Nginx enthält alle Tools, die zum Veröffentlichen von Legacy-Diensten auf neuen Websites erforderlich sind, mit Ausnahme des Problems mit der Cookie-Domäne. - Tobia


Antworten:


Ab 1.1.15 wurde die Option proxy_cookie_domain hinzugefügt, um dieses Problem zu beheben.

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain


20
2017-12-03 15:55





Die Antwort von @shamer funktioniert gut mit mehreren Set-Cookie Antwort-Header, aber es schlägt fehl, wenn es nur einen gibt. Wie Agentzh am Ende des referenzierten Threads zeigt, if type(cookies) ~= "table" then cookies = {cookies} end wird benötigt, um diesen Fall zu behandeln.

Hier ist das Ganze:

location / { 
    proxy_pass http://backend.int/;

    header_filter_by_lua '
        local cookies = ngx.header.set_cookie 
        if not cookies then return end
        if type(cookies) ~= "table" then cookies = {cookies} end
        local newcookies = {}
        for i, val in ipairs(cookies) do
            local newval = string.gsub(val, "([dD]omain)=[%w_-\\\\.]+", 
                      "%1=external.domain.com") 
            table.insert(newcookies, newval) 
        end 
        ngx.header.set_cookie = newcookies 
    '; 
}

5
2017-11-15 05:32





Diese Frage wurde in der nginx-Mailing-Liste [1] gestellt. Es gibt keine Möglichkeit, dies direkt in nginx zu tun. Sie müssen auf das Modul ngx_lua zurückgreifen (> = v0.3.1).

Der Benutzer "agentzh" hat ein Beispiel dafür, wie dies in der Konfigurationsdatei inline aussehen würde:

    server_name external.domain.com; 

    location / { 
        proxy_pass http://backend.int/;

        header_filter_by_lua ' 
            local cookies = ngx.header.set_cookie 
            if not cookies then return end 
            local newcookies = {} 
            for i, val in ipairs(cookies) do 
                local newval = string.gsub(val, "([dD]omain)=[%w_-\\\\.]+", 
                          "%1=external.domain.com") 
                table.insert(newcookies, newval) 
            end 
            ngx.header.set_cookie = newcookies 
        '; 
    } 

[1] http://nginx.2469901.n2.nabble.com/Reforming-the-domain-part-of-Set-Cookie-in-a-proxy-passe-td6453554.html


2
2017-12-01 14:51



Danke für die richtige Antwort, obwohl ich in der Vergangenheit schlechte Erfahrungen mit ngx_lua gemacht habe: schlechte Speicherlecks. Ich denke, dass Nginx einige einfache Header-Manipulations-Primitive benötigt, die seine eingebaute Regexp-Engine verwenden, wenn nicht ein paar mehr benutzerdefinierte Instruktionen wie das Umschreiben von Cookie-Domains. - Tobia