Bagaimana cara menulis ulang bagian domain Set-Cookie di proksi reverse nginx?

26

Saya memiliki proxy reverse nginx sederhana:

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

Masalahnya adalah bahwa Set-Cookieheader respons berisi ;Domain=backend.int, karena backend tidak tahu itu sedang terbalik proksi.

Bagaimana saya bisa membuat nginx menulis ulang isi dari Set-Cookieheader respon, menggantikan ;Domain=backend.intdengan ;Domain=external.domain.com?

Melewati Hosttajuk tidak berubah bukanlah pilihan dalam kasus ini.

Apache httpd telah memiliki fitur ini untuk sementara waktu, lihat ProxyPassReverseCookieDomain, tetapi sepertinya saya tidak dapat menemukan cara untuk melakukan hal yang sama di nginx.

Tobia
sumber
2
mengapa melewatkan header host bukan opsi? karena bagian host dari header dibuat untuk hal-hal seperti itu. jika Anda harus melewati proxy mana yang digunakan, Anda harus menyediakan tajuk tambahan.
jojoo
1
Misalkan Anda memiliki server lama yang melakukan hosting virtual dan Anda ingin meletakkan Nginx di depannya, untuk menerbitkan beberapa layanan tersebut pada domain baru. Misalkan Anda tidak dapat (atau tidak mau) mengubah konfigurasi server lama. Nginx berisi semua alat yang diperlukan untuk menerbitkan layanan lawas di situs baru, kecuali untuk masalah domain cookie.
Tobia

Jawaban:

5

Jawaban dari @shamer berfungsi dengan baik dengan beberapa Set-Cookieheader respons, tetapi gagal jika hanya ada satu. Seperti yang ditunjukkan agentzh di akhir utas yang dirujuk, if type(cookies) ~= "table" then cookies = {cookies} enddiperlukan untuk menangani kasus itu.

Ini semuanya:

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

Pertanyaan ini muncul di milis nginx [1]. Tidak ada cara untuk langsung melakukan ini di nginx. Anda harus menggunakan modul ngx_lua (> = v0.3.1).

Pengguna "agentzh" memiliki contoh tampilan seperti yang diuraikan dalam file konfigurasi:

    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
sumber
2
Terima kasih atas jawaban yang benar, meskipun saya pernah memiliki pengalaman buruk dengan ngx_lua di masa lalu: kebocoran memori buruk. Saya pikir Nginx membutuhkan beberapa primitif manipulasi header sederhana menggunakan mesin regexp bawaannya, jika tidak beberapa instruksi khusus seperti penulisan ulang domain cookie.
Tobia