Como reescrever a parte do domínio do Set-Cookie em um proxy reverso nginx?

26

Eu tenho um proxy reverso nginx simples:

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

O problema é que os Set-Cookiecabeçalhos de resposta contêm ;Domain=backend.int, porque o back-end não sabe que está sendo proxy reverso.

Como posso fazer com que o nginx reescreva o conteúdo dos Set-Cookiecabeçalhos de resposta, substituindo ;Domain=backend.intpor ;Domain=external.domain.com?

Passar o Hostcabeçalho inalterado não é uma opção neste caso.

O Apache httpd possui esse recurso há algum tempo, veja ProxyPassReverseCookieDomain, mas não consigo encontrar uma maneira de fazer o mesmo no nginx.

Tobia
fonte
2
por que passar o cabeçalho do host não é uma opção? A parte host do cabeçalho é feita para essas coisas. se precisar passar qual proxy foi usado, forneça cabeçalhos adicionais.
jojoo
11
Suponha que você tenha um servidor legado que faça hospedagem virtual e que queira colocar o Nginx na frente dele, para publicar alguns desses serviços em um novo domínio. Suponha que você também não possa (ou não queira) alterar a configuração do servidor herdado. O Nginx contém todas as ferramentas necessárias para publicar serviços herdados em novos sites, exceto o problema do domínio de cookies.
Tobia

Respostas:

5

A resposta do @shamer funciona bem com Set-Cookiecabeçalhos de várias respostas, mas falha se houver apenas um. Como o agentzh aponta no final do encadeamento referenciado, if type(cookies) ~= "table" then cookies = {cookies} endé necessário para lidar com esse caso.

Aqui está a coisa toda:

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

Esta questão surgiu na lista de discussão nginx [1]. Não há como fazer isso diretamente no nginx. Você precisa recorrer ao módulo ngx_lua (> = v0.3.1).

O usuário "agentzh" tem um exemplo de como isso seria descrito no arquivo de configuração:

    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
fonte
2
Obrigado pela resposta correta, embora eu tenha tido uma experiência ruim com ngx_lua no passado: falta de memória. Eu acho que o Nginx precisa de algumas primitivas simples de manipulação de cabeçalho usando seu mecanismo regexp embutido, se não mais algumas instruções personalizadas, como reescrita de domínio de cookie.
Tobia