4

Here's my situation, I have a Rails 4 app that can be accessed by multiple domains, depending on the domain, the content changes.

Say the main domain is domain1 and all the other domains just use Nginx's proxy_pass to forward the requests to domain1, this is all working fine except that the session or other cookies are not set for domain2.

In my Rails app i've created a middleware that sets dynamically the domain for the session according to what domain is accessing the app using the content of the CUSTOMHEADER header, and I can see in the Set-Cookie header that the cookie domain is correct so I'm thinking my problem is in my Nginx configuration, but sadly my Nginx knowledge is quite limited.

Nginx config

The following is an example host file for domain2 (one of the example domains where the cookies are not set):

server {
  listen   80;

  server_name domain2.com;
  rewrite ^(.*) http://www.domain2.com$1 permanent;
}

server {
  listen   80;
  server_name www.domain2.com;

  location /assets/ {
    proxy_pass                      https://main.domain1.com/assets/;
    proxy_set_header                X-Real-IP       $remote_addr;
    proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header                Cookie $http_cookie;
    proxy_set_header                CUSTOMHEADER www.domain2.com;
    proxy_pass_request_headers      on;
  }

  location /some_path/ {
    proxy_pass                      https://main.domain1.com/some_path/;
    proxy_set_header                X-Real-IP       $remote_addr;
    proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header                Cookie $http_cookie;
    proxy_set_header                CUSTOMHEADER www.domain2.com;
    proxy_pass_request_headers      on;
  }

  location / {
    proxy_pass                      https://main.domain1.com;
    proxy_set_header                X-Real-IP       $remote_addr;
    proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header                Cookie $http_cookie;
    proxy_set_header                CUSTOMHEADER www.domain2.com;
    proxy_pass_request_headers      on;
    rewrite ^/(.*)$ /sites/some-id/$1 break;
  }
}

when opening up a page in the browser and inspecting the headers i get the following (in Chrome):

Response Headers

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 05 Nov 2018 22:21:45 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Vary: Accept-Encoding
Status: 200 OK
Cache-Control: max-age=0, private, must-revalidate
Strict-Transport-Security: max-age=31536000
X-XSS-Protection: 1; mode=block
X-Request-Id: 33d26df0-f44c-4ff5-9513-62aaade8c581
ETag: W/"3dd8553b2a02cfc9f85a609c5f90bafb"
X-Frame-Options: SAMEORIGIN
X-Runtime: 0.025616
X-Content-Type-Options: nosniff
Set-Cookie: _myapp_session=dmNFR2...3ae445b; domain=www.domain2.com; path=/; secure; HttpOnly
X-Powered-By: Phusion Passenger 5.1.2
Content-Encoding: gzip

Request Headers

GET /login HTTP/1.1
Host: www.domain2.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://www.domain2.com/bla
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,pt;q=0.8,fr;q=0.7
If-None-Match: W/"09c9ac3842dd3942a006b9000bd7a29d"

As you can see the Response contains the Set-Cookie header and the cookie has the correct domain, and yet the cookie is never set by the browser, and you will also notice that the Request doesn't have the Cookie header, although that might just be because there is no cookie to send.

Note 1: I've also tried setting the following headers in the response coming from the Rails app, but that didn't help:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Credentials: true

Note 2: I know the browser will not create the cookie if it's oversized but the cookie size should be far from the maximum, so I don't think that's the problem here.

The session works fine when accessing the main domain (http://main.domain1.com), what am I missing here? I feel like I'm lacking some theoretical knowledge about Nginx or web servers in general that is preventing me from getting this right but I've been struggling with this for 3 days, tried all kinds of headers and different combinations and so far all my research is fruitless.

6
  • 1
    Why are you using a CUSTOMHEADER: header, when the hostname is already available in the Host: header? You only need to pass it upstream. For that matter, why do you have separate server blocks? If it's the same web app and the same document root, all of the hostnames can be served from the same server block. Nov 5, 2018 at 22:49
  • well the different hosts are user generated so whenever they create one, the app spits out all those configs in a separate file, makes it much easier to manage having that separation, as for the custom header, might not have been the best solution but it did the trick. But unless I'm wrong I don't think any of that relates to the cookie problem though, any thoughts on that?
    – Julien
    Nov 5, 2018 at 23:12
  • Yes, but I already gave you the solution to that! Use a single server block. Don't try to redirect. Nov 5, 2018 at 23:13
  • not sure i understand, the first server block is just used to redirect to www.domain2.com in case the domain is accessed without the www., not sure how removing that is gonna help with my problem.
    – Julien
    Nov 5, 2018 at 23:42
  • No, I said nothing about that server block that redirects to https. It's all the duplicate ones that serve your web app that you need to have a single one. Nov 5, 2018 at 23:48

1 Answer 1

2

Finally solved this, the problem was that the main.domain1.com was using SSL while the other domains weren't, I tried disabling SSL on the main domain and it worked, the other domains finally had session cookies, I'll have to see if it works once I add SSL to the other domains and re-enable it on the main domain but i'll cross that bridge once I get there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.