Jak przepisać część domeny Set-Cookie w odwrotnym proxy Nginx?

26

Mam proste odwrotne proxy Nginx:

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

Problem polega na tym, że Set-Cookiezawierają nagłówki odpowiedzi ;Domain=backend.int, ponieważ backend nie wie, że jest odwrotnie proxy.

Jak zmusić nginx do przepisania zawartości Set-Cookienagłówków odpowiedzi, zastępując ;Domain=backend.intje ;Domain=external.domain.com?

Przekazanie Hostnagłówka bez zmian nie jest opcją w tym przypadku.

Widzicie ProxyPassReverseCookieDomain, Apache httpd ma tę funkcję od dłuższego czasu , ale nie mogę znaleźć sposobu, aby zrobić to samo w Nginx.

Tobia
źródło
2
dlaczego przekazywanie nagłówka hosta nie jest opcją? imo część hosta nagłówka jest przeznaczona do takich rzeczy. jeśli musisz podać, który serwer proxy był używany, powinieneś podać dodatkowe nagłówki.
jojoo
1
Załóżmy, że masz starszy serwer obsługujący wirtualny hosting i chcesz postawić przed nim Nginx, aby opublikować niektóre z tych usług w nowej domenie. Załóżmy również, że nie możesz (lub nie chcesz) zmieniać konfiguracji starszego serwera. Nginx zawiera wszystkie narzędzia potrzebne do publikowania starszych usług w nowych witrynach, z wyjątkiem problemu z domeną plików cookie.
Tobia,

Odpowiedzi:

5

Odpowiedź z @shamer działa dobrze z wieloma Set-Cookienagłówkami odpowiedzi, ale kończy się niepowodzeniem, jeśli jest tylko jeden. Jak wskazuje agentzh na końcu przywoływanego wątku, if type(cookies) ~= "table" then cookies = {cookies} endpotrzebna jest obsługa tego przypadku.

Oto cała sprawa:

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
źródło
2

To pytanie pojawiło się na liście mailingowej nginx [1]. W Nginx nie ma bezpośredniego sposobu, aby to zrobić. Musisz skorzystać z modułu ngx_lua (> = v0.3.1).

Użytkownik „agentzh” ma przykład tego, jak by to wyglądało, wstawione w pliku konfiguracyjnym:

    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
źródło
2
Dziękuję za poprawną odpowiedź, chociaż miałem złe doświadczenia z ngx_lua w przeszłości: złe wycieki pamięci. Wydaje mi się, że Nginx potrzebuje prostych operacji prymitywnych do obsługi nagłówków za pomocą wbudowanego silnika regexp, jeśli nie kilku dodatkowych instrukcji, takich jak przepisywanie domen plików cookie.
Tobia,