Wie schreibe ich den Domain-Teil von Set-Cookie in einem Nginx-Reverse-Proxy um?

26

Ich habe einen einfachen Nginx-Reverse-Proxy:

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

Das Problem besteht darin, dass Set-CookieAntwortheader enthalten sind ;Domain=backend.int, da das Backend nicht weiß, dass es sich um einen Reverse-Proxy handelt.

Wie kann ich den Inhalt der neu zu schreiben machen nginx - Set-CookieResponse - Header und ersetzt ;Domain=backend.intmit ;Domain=external.domain.com?

HostIn diesem Fall ist es nicht möglich, den Header unverändert weiterzugeben.

Apache httpd hat diese Funktion schon eine Weile, ProxyPassReverseCookieDomainaber ich kann anscheinend keinen Weg finden, dies auch in nginx zu tun.

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

Antworten:

5

Die Antwort von @shamer funktioniert problemlos mit mehreren Set-CookieAntwort-Headern, schlägt jedoch fehl, wenn nur einer vorhanden ist. Wie agentzh am Ende des referenzierten Threads hervorhebt, if type(cookies) ~= "table" then cookies = {cookies} endist dies erforderlich, 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 
    '; 
}
lhagan
quelle
2

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

Der Benutzer "agentzh" hat ein Beispiel dafür, wie dies in der Konfigurationsdatei 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/Rewriting-the-domain-part-of-Set-Cookie-in-a-proxy-pass-td6453554.html

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