I have a fly app running a server image. This is great and fantastic, but this server image implements no auth at all – everything is public all the time. Not ideal!
I need to restrict access to this server. My initial plan was to set an NGINX proxy up on Fly that proxies through the private network .internal address, and put basic auth on that.
However, no matter what I try (all the examples from fly, all the examples here) the proxy returns a 502.
What are my best approaches here? Does anyone have nginx running a proxy like this? How does yours work?
What do you intend to run behind Ngnix? Node? If so, you can choose to handle http basic auth in Node itself.
As for 502s, can you check if your reverse proxy / server is handling incoming connections as expected (example: over plaintext http, if you’re using Fly’s http-handler)? Can you share your app’s fly.toml?
I’d say basic auth is the simplest way to accomplish what you’re trying to do.
If you’re adventurous, you can bind your Fly VMs in a tailnet, or expose them over tailscale funnels…? I haven’t done so myself but it doesn’t sound too complicated. Another alternative would be to use tunnels like ngrok, or front your Fly VMs with Cloudflare Access serving from behind the Cloudflare proxy.
And, since you ask, what we do is, have the user send the secret (as part of the URL: https://domain.tld/serve/this/path/heres-my-secret) and match it against a pre-generated, hard-coded hmac valid against a preset msg for that secret (ref). This is an overkill, so you’d not want to do this.
I think nginx is the correct approach here. You could also look into an API gateway like Kong.
What address is oxigraph bound to? I have had to use the IPv6 loopback address for Rust services in the past: [::]:7878
If you want to restrict access with nginx you should remove the external port mapping ([[services.ports]]) in your fly.toml since your service is currently exposed.to the internet on ports 80 and 443. I have also had issues in the past using .internal addresses while having external ports mapped.
Not using Nginx, but I’ve had success with combining Cloudflare Access and Caddy server. Full stack looks like this.
Cloudflare → Fly Proxy → Caddy app on Fly → Python app on Fly
More details:
Cloudflare is configured for authenticated origin pulls. I also use Cloudflare Access to manage authentication. It’s a pretty neat one-click solution.
The Caddy app is configured as a reverse proxy (listen to incoming connections on 8080, verify the connection is coming from CF, forward the request to 8080 on Python app via the app-name.internal hostname.
The Python app is not exposed to the public Internet.
With this setup, I get the following:
Email-based auth via CF access.
Caddy app can’t be accessed via IP or fly.dev domain thanks to the authenticated origin pull setup.
Python app only talks to Caddy via internal network.
Hi @nikolaswise Sorry I haven’t got the key to getting the reverse proxy working, but I believe port 22 is a wrong turn. A program called Hallpass listens on port 22 of each Fly.io app VM, to allow you to use fly ssh.
If your oxigraph app is internal only then you can remove the entire services section from the fly.toml for the oxigraph app.
For your proxy, you need to make sure that you always use http for the oxigraph urls as internally it will never use https and https is not supported (unless oxigraph itself handles https).
Make sure to keep using the 7878 port because port 22 is for ssh and is the wrong port to use for your purpose.
One thing I noticed is that you’re potentially binding to the wrong address. I see you have used [::1]:7878, try using [::]:7878 instead.