1

I'm trying to use nginx as a reverse proxy. One server is a play server. When I try to proxy the server, I receive a 400 Host Not Allowed error.

flow

                                         ----------(services1)
                                         |----(services2)
client ----(https)---> nginx ---(http)---|-------(services3)
                                         |----(services4)
                                         ---------(services5)

(i.e. the client talks to nginx via ssl and then nginx acts as a reverse proxy to whatever backend is needed over http).

I'm trying to test this out with a dummy scala play backend.

I have an nginx.conf that looks like:

http {
    ...

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;

    upstream play-backend {
        server 127.0.0.1:9000;
    }

    include sites-enabled/*.conf;
}

Now, I have a default.conf (inside sites-enabled) that redirect http traffic over ssl:

server {
    listen 80 default_server;
    list [::]:80 default_server;

    return 301 https://$host$request_uri;
    ...
}

Then, inside my default-ssl.conf (inside sites-enabled), I have my reverse proxy logic:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ... certificate and other stuff ...

    location /foo {
        proxy_pass http://play-backend;
    }
}

I am able to successfully divert traffic over ssl, but I'm not sure why I can't proxy to any of my backend services. I have a feeling I've organized everything wrong and it's somehow trying to use https to communicate with the play server.

I can confirm the play server is working by directly hitting localhost:9000/

EDIT: Specifically, the problem is that nginx makes a request to the backend service from myexampledomain.com rather than from localhost. I'm not sure how to send the request from localhost to the backend service and then return it to the client from the domain over ssl.

  • It seems changing proxy_set_header Host localhost will work, but I'm not sure if that's safe. Any help would be appreciated. – clo_jur Jun 11 '17 at 20:31
  • Off-topic comment which I'll delete once you've seen this: please come here chat.stackexchange.com/transcript/message/39776961#39776961 regarding your recent deleted question. :) – Wildcard Sep 2 '17 at 4:32
0

You probably need to setup the Allowed Host Filter on your application.conf. You should use the can use "." to allow any Host, or you could use "myexampledomain.com" .

   play.filters.hosts {
     # Allow requests to myexampledomain.com.
     allowed = ["myexampledomain.com"]
   }

https://www.playframework.com/documentation/2.6.x/AllowedHostsFilter

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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