¿Cómo reescribir la parte del dominio de Set-Cookie en un proxy inverso nginx?

26

Tengo un proxy inverso nginx simple:

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

El problema es que los Set-Cookieencabezados de respuesta contienen ;Domain=backend.int, porque el backend no sabe que está siendo proxy inverso.

¿Cómo puedo hacer que nginx reescriba el contenido de los Set-Cookieencabezados de respuesta, reemplazando ;Domain=backend.intpor ;Domain=external.domain.com?

Pasar el Hostencabezado sin cambios no es una opción en este caso.

Apache httpd ha tenido esta característica por un tiempo, vea ProxyPassReverseCookieDomain, pero parece que no puedo encontrar una manera de hacer lo mismo en nginx.

Tobia
fuente
2
¿Por qué pasar el encabezado del host no es una opción? La parte host del encabezado está hecha para tales cosas. si necesita pasar qué proxy se usó, debe proporcionar encabezados adicionales.
jojoo
1
Suponga que tiene un servidor heredado que realiza alojamiento virtual y desea poner Nginx al frente para publicar algunos de esos servicios en un nuevo dominio. Supongamos que tampoco puede (o no quiere) cambiar la configuración del servidor heredado. Nginx contiene todas las herramientas necesarias para publicar servicios heredados en nuevos sitios, excepto el problema del dominio de cookies.
Tobia

Respuestas:

5

La respuesta de @shamer funciona bien con múltiples Set-Cookieencabezados de respuesta, pero falla si solo hay uno. Como agentzh señala al final del hilo referenciado, if type(cookies) ~= "table" then cookies = {cookies} endes necesario para manejar ese caso.

Aquí está todo:

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
fuente
2

Esta pregunta apareció en la lista de correo nginx [1]. No hay forma de hacer esto directamente en nginx. Debe recurrir al uso del módulo ngx_lua (> = v0.3.1).

El usuario "agentzh" tiene un ejemplo de cómo se vería esto en el archivo de configuración:

    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

shamer
fuente
2
Gracias por la respuesta correcta, aunque he tenido una mala experiencia con ngx_lua en el pasado: pérdidas de memoria incorrecta. Creo que Nginx necesita algunas primitivas simples de manipulación de encabezado utilizando su motor de regexp incorporado, si no algunas instrucciones personalizadas más, como la reescritura del dominio de cookies.
Tobia