How to use Nginx to whitelist a specific URL

I have an nginx docker setup. I can’t quite get the nginx.conf setup how I want it.

What I want whitelisted: testingexample.com
NGINX fly app: nginx-app.fly.dev
Backend data app: backend-app.fly.dev

What I want is requests from testingexample.com pointed at nginx-app.fly.dev to reverse-proxy to backend-app.fly.dev. But I also only want to reverse-proxy if the request comes from testingexample.com.

I currently have this config that sets up my reverse proxy. I just need to be able to whitelist testingexample.com

server {
  listen 8080;
  listen [::]:8080;

  server_name _
  proxy_set_header X-Forwarded-Host $http_host;
  proxy_ssl_server_name on;

  location /data/ {
    proxy_pass https://backend-app.fly.dev/data/;
  }
}

How would I go about this?

Another issue with this is that the user would still be able to access backend-app.fly.dev directly. Is there anyway to prevent that?

Hey,

I haven’t tried but my total guess would be to look at $host. You can see what this is from e.g this code: https://steelywing.github.io/note/Note/Nginx/host/#validation

In theory:

if ($host !~* (yourhostname.com)) {
      return 403;
}

For an actual lookup of hostnames for allow/deny, this seems neat: https://www.nginx.com/resources/wiki/modules/rdns/but it seems to have been abandoned for a while and so may not even install or work.

As for someone being able to bypass your proxy and access the name.fly.dev directly, that would remain the case. I don’t know of an option to turn off that. All I can think is you would need to not expose the backend app to the public internet at all (for example don’t assign it an IP). And so (in theory) as long as your proxy was hosted by Fly, you could use app-name.internal as the host to proxy in your nginx. Since if the proxy was a Fly app and the backend app was also a Fly app (in the same organisation), they can talk to each other over the encrypted, private network. Without needing to go over the public internet. Nobody outside of your Fly network could resolve that app-name.internal and thus that backend would not be available to them.

You probably need to append the port so e.g http://app-name.internal:1234 (assuming your backend is listening on port 1234). You can use http since the connection is encrypted.

All that’s very much in theory!

I have fixed the first issue of restricting by using the following code ‘referrer’.

 server {
  listen 8080;
  listen [::]:8080;

  server_name frontend.fly.dev;

  valid_referers server_names localhost;

  if ($invalid_referer) {
          return 402;
  }

  location / {
          proxy_set_header X-Forwarded-Host $http_host;
          proxy_ssl_server_name on;
          proxy_pass https://backend.fly.dev/;
  }

  location /data/ {
          proxy_set_header X-Forwarded-Host $http_host;
          proxy_ssl_server_name on;
          proxy_pass https://backend.fly.dev/data/;
  }
}

I would now like my backend.fly.dev to only be accessible to my frontend.fly.dev. Greg mentioned using a .internal but I can find anything on them. Does someone have some insight/docs.