railway ip whitelisting via caddy
miroblog
PROOP

6 days ago

I have a setup like this in Caddy to whitelist certain IPs:

{
    admin off
    servers {
        trusted_proxies static private_ranges 100.64.0.0/10
    }
}

:{$PORT:8000} {
    @allowed client_ip {$CADDY_IP_WHITELIST:0.0.0.0/0}
    handle @allowed {
        reverse_proxy localhost:9000
    }
    respond "Access denied" 403
}

The problem: I can't get the real client IP — it seems to be overridden by the cache server (cache-icn1450077-ICN).

Here are the headers I'm seeing:

X-Forwarded-For: <my-ip>, 157.52.116.77, 100.64.0.2
X-Forwarded-Host: ???.app
X-Forwarded-Proto: https
X-Forwarded-Server: cache-icn1450077-ICN
X-Orig-Host: ???.app
X-Railway-Edge: railway/----
X-Railway-Request-Id: ----
X-Real-Ip: 157.52.116.77

My actual IP is the first value in X-Forwarded-For, but X-Real-Ip shows 157.52.116.77 instead.

It looks like this started happening after Railway's recent DDoS protection changes (around February). The behavior is intermittent — sometimes it works correctly, sometimes it doesn't.

How can I reliably extract the real client IP?

Solved$20 Bounty

Pinned Solution

miroblog
PROOP

5 days ago

Oh i figured out ...

- https://blog.railway.com/p/incident-report-february-19-2026
- Envoy -> Fastly

so use this pattern where
- fastly ip ranges : https://api.fastly.com/public-ip-list
- caddy at 8080
- your app port 9000

{
admin off
servers {
trusted_proxies static <Railway IPs> <Fastly IPs>
trusted_proxies_strict
}
}

:${PORT:8000} {
@allowed client_ip {${CADDY_IP_WHITELIST:0.0.0.0/0}}
handle @allowed {
reverse_proxy localhost:9000
}

respond "Access denied" 403
}

4 Replies

miroblog
PROOP

6 days ago

Fastly-Client-Ip: xxx

seems like this can be ovewritten by curl -H . so it did not help


xmrafonso
FREETop 5% Contributor

6 days ago

Hey,

You can either trust all proxies (would work, but insecure) or you'd handle it whitelisting in your app directly but all of these can be faked.

The problem relies on the fact that railway does not publicly provide stable edge ip ranges, so there is no way to validate authenticity of requests.

But I did find the following ips for railway servers in another thread:

California, United States - 162.220.232.0/23

Virginia, United States - 162.220.234.0/23

Amsterdam, Netherlands - 208.77.244.0/23

Singapore - 208.77.246.0/23

So I guess you can try to use these.


miroblog
PROOP

5 days ago

Oh i figured out ...

- https://blog.railway.com/p/incident-report-february-19-2026
- Envoy -> Fastly

so use this pattern where
- fastly ip ranges : https://api.fastly.com/public-ip-list
- caddy at 8080
- your app port 9000

{
admin off
servers {
trusted_proxies static <Railway IPs> <Fastly IPs>
trusted_proxies_strict
}
}

:${PORT:8000} {
@allowed client_ip {${CADDY_IP_WHITELIST:0.0.0.0/0}}
handle @allowed {
reverse_proxy localhost:9000
}

respond "Access denied" 403
}


5 days ago

We have been off Envoy for many years at this point.


Status changed to Awaiting User Response Railway 5 days ago


Status changed to Solved brody 5 days ago


Loading...