How to rewrite the domain part of Set-Cookie in a nginx reverse proxy?
I have a simple nginx reverse proxy:
server {
server_name external.domain.com;
location / {
proxy_pass http://backend.int/;
}
}
The problem is that Set-Cookie
response headers contain ;Domain=backend.int
, because the backend does not know it is being reverse proxied.
How can I make nginx rewrite the content of the Set-Cookie
response headers, replacing ;Domain=backend.int
with ;Domain=external.domain.com
?
Passing the Host
header unchanged is not an option in this case.
Apache httpd has had this feature for a while, see ProxyPassReverseCookieDomain
, but I cannot seem to find a way to do the same in nginx.
Solution 1:
Starting in 1.1.15, proxy_cookie_domain option was added to address this issue.
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain
Solution 2:
The answer from @shamer works fine with multiple Set-Cookie
response headers, but it fails if there's just one. As agentzh points out at the end of the referenced thread, if type(cookies) ~= "table" then cookies = {cookies} end
is needed to handle that case.
Here's the whole thing:
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
';
}
Solution 3:
This question came up in the nginx mailing list [1]. There's no way to directly do this in nginx. You have to resort to using the ngx_lua module (>=v0.3.1).
The user "agentzh" has an example of what this would look like inlined in the config file:
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