Comment réécrire la partie domaine de Set-Cookie dans un proxy inverse nginx?

26

J'ai un simple proxy inverse nginx:

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

Le problème est que Set-Cookieles en-têtes de réponse contiennent ;Domain=backend.int, car le backend ne sait pas qu'il est en cours de proxy inverse.

Comment puis-je faire réécrire nginx le contenu des en- Set-Cookietêtes de réponse, en remplaçant ;Domain=backend.intpar ;Domain=external.domain.com?

Passer l'en- Hosttête inchangé n'est pas une option dans ce cas.

Apache httpd a cette fonctionnalité depuis un certain temps, voyez ProxyPassReverseCookieDomain, mais je n'arrive pas à trouver un moyen de faire la même chose dans nginx.

Tobia
la source
2
pourquoi le passage de l'en-tête d'hôte n'est pas une option? imo la partie hôte de l'en-tête est faite pour de telles choses. si vous devez transmettre le proxy utilisé, vous devez fournir des en-têtes supplémentaires.
jojoo
1
Supposons que vous ayez un serveur hérité qui fait de l'hébergement virtuel et que vous vouliez mettre Nginx devant, pour publier certains de ces services sur un nouveau domaine. Supposons également que vous ne puissiez pas (ou ne souhaitiez pas) modifier la configuration du serveur hérité. Nginx contient tous les outils nécessaires pour publier des services hérités sur de nouveaux sites, à l'exception du problème du domaine des cookies.
Tobia

Réponses:

5

La réponse de @shamer fonctionne bien avec plusieurs en- Set-Cookietêtes de réponse, mais elle échoue s'il n'y en a qu'un. Comme l'agentzh le fait remarquer à la fin du thread référencé, if type(cookies) ~= "table" then cookies = {cookies} endest nécessaire pour gérer ce cas.

Voici le tout:

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
la source
2

Cette question est apparue dans la liste de diffusion nginx [1]. Il n'y a aucun moyen de le faire directement dans nginx. Vous devez recourir à l'utilisation du module ngx_lua (> = v0.3.1).

L'utilisateur "agentzh" a un exemple de ce à quoi cela ressemblerait dans le fichier de configuration:

    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

honte
la source
2
Merci pour la bonne réponse, bien que j'ai eu une mauvaise expérience avec ngx_lua dans le passé: fuites de mémoire incorrectes. Je pense que Nginx a besoin de quelques primitives de manipulation d'en-tête simples en utilisant son moteur regexp intégré, sinon quelques instructions personnalisées telles que la réécriture du domaine des cookies.
Tobia