2 months ago
Hi,
We run an API on Railway behind a custom domain, and we're putting Cloudflare
in front of it. We'd like the Railway origin to only accept traffic that
transited Cloudflare. Three questions:
-
Can Railway's edge validate a client certificate presented by an upstream
proxy? Specifically, is Cloudflare Authenticated Origin Pulls (mTLS)
supported — is there any way to configure client-certificate verification
for a public domain, given that Railway terminates TLS?
-
If not: is there a supported way to restrict a public HTTP domain to a
specific set of source IPs (e.g. Cloudflare's published ranges)? Or is the
intended pattern to remove the public domain entirely and expose the
service only via a cloudflared sidecar over private networking?
-
Is X-Real-IP always set by Railway's edge, and does the edge overwrite any
X-Real-IP a client sends? We want to confirm it cannot be spoofed by the
caller before relying on it.
Thanks.
Pinned Solution
2 months ago
For the questions above:
- IIRC not possible, since TLS is terminated at the edge and not at the origin
- Some users have done something similar (eg, using Tailscale or a Cloudflare Tunnel to expose services). You can maintain your own list of traffic from allowed IPs, but that would get complicated really easily. Using a tunnel would be much easier.
X-Real-IPis set at the edge, so no, it can't be easily spoofed.
5 Replies
2 months ago
This is a question the Railway community is better placed to answer than support: people who have already worked this out on their own projects and can tell you what actually worked.
So we'd like to open your thread as a community bounty. Railway pays a bounty to the community member who answers it, and threads like this usually get picked up quickly.
Opening it makes this entire thread public, including everything already posted. Nothing becomes public until you decide. Use the buttons below.
- Open to the community - Before you click, take a moment to edit or remove anything you'd rather not share. The thread becomes publicly visible right away.
- Keep it private and close the thread - Nothing becomes public and the thread closes.
Status changed to Awaiting User Response Railway • about 2 months ago
2 months ago
This thread has been opened as a public bounty so the community can help solve it. The thread and any further activity are now visible to everyone.
Status changed to Open Railway • about 2 months ago
2 months ago
Users can't bypass Cloudflare if the traffic is going through Cloudflare.
0x5b62656e5d
~~Users can't bypass Cloudflare if the traffic is going through Cloudflare.~~
2 months ago
Sorry, I was unclear — I mean traffic that does NOT go through Cloudflare.
Proxying a domain through Cloudflare only changes public DNS. Railway's edge
still serves the hostname to anyone connecting to Railway's IP with matching
SNI, and origin IPs are easy to recover from DNS history:
curl --resolve mydomain.com:443: https://mydomain.com/
Is there any Railway-side way to refuse requests that didn't come from my proxy
(client-cert validation, IP allowlist)? Or should I run a cloudflared sidecar
over private networking with no public domain?
2 months ago
For the questions above:
- IIRC not possible, since TLS is terminated at the edge and not at the origin
- Some users have done something similar (eg, using Tailscale or a Cloudflare Tunnel to expose services). You can maintain your own list of traffic from allowed IPs, but that would get complicated really easily. Using a tunnel would be much easier.
X-Real-IPis set at the edge, so no, it can't be easily spoofed.
0x5b62656e5d
For the questions above: 1. IIRC not possible, since TLS is terminated at the edge and not at the origin 2. Some users have done something similar (eg, using Tailscale or a Cloudflare Tunnel to expose services). You can maintain your own list of traffic from allowed IPs, but that would get complicated really easily. Using a tunnel would be much easier. 3. `X-Real-IP` is set at the edge, so no, it can't be easily spoofed.
2 months ago
Thanks — going the cloudflared route
Status changed to Solved mayori • about 2 months ago