Authoritative edge/ingress proxy source IP range for a strict ASP.NET Core ForwardedHeaders trust boundary
hkwv
FREEOP

a month ago

What I need

The source IP address or CIDR that Railway's edge proxy uses when it connects to my container for public HTTP ingress, so I can configure it as an explicitly trusted proxy — plus confirmation of whether that range is stable enough to rely on as a security boundary.

Why the documented headers are not sufficient on their own

Since ASP.NET Core 8.0.17 / 9.0.6, the Forwarded Headers middleware ignores all X-Forwarded-* headers unless the immediate peer is listed in ForwardedHeadersOptions.KnownProxies or KnownNetworks. My application deliberately clears the default loopback entries outside Development, sets ForwardLimit = 1, and fails startup if no trusted entry is configured.

Consequence: without the correct peer address configured, X-Forwarded-Proto: https is ignored, the app sees the request as plain HTTP behind Railway's TLS edge, and UseHttpsRedirection() produces a redirect loop. I am not willing to work around this by trusting 0.0.0.0/0 or ::/0, which would erase the trust boundary entirely.

What I have already checked

  • Public networking → Specs & limits documents the headers the edge sets (X-Real-IP, X-Forwarded-Proto, X-Forwarded-Host, X-Railway-Edge, X-Railway-Request-Id) but does not publish an ingress IP or CIDR.
  • railway private-network status returns privateIps: [] for my services, so the CLI exposes no range.
  • The Caddy/React deployment guide in the docs configures trusted_proxies static private_ranges 100.0.0.0/8 # trust railway's proxy. I am unsure whether this is authoritative or merely illustrative — 100.0.0.0/10 (100.0.0.0–100.63.255.255) is publicly routable IANA space rather than RFC 6598 shared address space, so trusting the whole /8 appears broader than Railway's actual network.
  • An existing Central Station thread on edge proxy header handling has a Railway employee confirming that X-Forwarded-For is stripped at the edge and X-Real-IP is provided, but it does not state the proxy source range or guarantee the hop count.

Specific questions

  1. What source IP address / CIDR does the Railway edge use when connecting to a container for public HTTP ingress — for both IPv4 and IPv6?
  2. Is that range stable and safe to configure as a trust boundary, or can it change without notice? If it can change, what is the recommended way to express the trust boundary durably?
  3. How many proxy hops should an application expect between the edge and the container (i.e. what should ForwardLimit be set to)?
  4. Is X-Real-IP guaranteed to be set by the edge on every public request, and guaranteed to be stripped from client-supplied input so it cannot be spoofed? If so, is treating X-Real-IP as authoritative the officially recommended approach on Railway, in preference to X-Forwarded-For?
  5. Is the 100.0.0.0/8 value in the Caddy guide authoritative for this purpose, or should it be narrowed?

Environment (non-identifying)

| Field | Value |

|---|---|

| Plan | Trial |

| Region | ams |

| Build | Dockerfile build, .NET 10 / ASP.NET Core on mcr.microsoft.com/dotnet/aspnet:10.0 |

| Listening | http://[::]:8080, using the Railway-injected PORT |

| Ingress | one Railway-generated *.up.railway.app service domain, target port 8080 |

| Topology | one public web service; one private API service; PostgreSQL private, no TCP proxy |

I have deliberately left out my project, environment, service, and deployment IDs because this is a public thread and the questions above are about platform behaviour rather than a fault in one specific deployment. I'm happy to supply those IDs privately if a Railway engineer needs them — just ask and I'll provide them however you prefer.

There is no error log to attach: the affected web service is intentionally not deployed, because it fails startup validation by design until a trusted proxy entry is configured.

Solved$10 Bounty

Pinned Solution

  1. https://ipinfo.io/AS400940
  2. No. IPs may change. If you wish to have a static IP, you'll need to upgrade to the Pro plan.
  3. It could be 1 or 2 hops, but it's not fixed. The requests can be further forwarded throughout Railway's own network.
  4. The header can't be spoofed, as it's set at the edge.
  5. I'd recommend leaving it as is.

1 Replies

Railway
BOT

a month ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway • about 1 month ago


  1. https://ipinfo.io/AS400940
  2. No. IPs may change. If you wish to have a static IP, you'll need to upgrade to the Pro plan.
  3. It could be 1 or 2 hops, but it's not fixed. The requests can be further forwarded throughout Railway's own network.
  4. The header can't be spoofed, as it's set at the edge.
  5. I'd recommend leaving it as is.

Status changed to Solved brody • about 1 month ago


Welcome!

Sign in to your Railway account to join the conversation.

Loading...