Skip to content
Back to site

Static egress IP

Customers with receivers behind a firewall need a fixed IP address to allowlist.

Railhook has no setting for this: the worker’s HTTP client has no forward-proxy option and does not read HTTP_PROXY or HTTPS_PROXY. Solve it one layer down. The worker is the only component that sends deliveries, so fixing its outbound address fixes it for every webhook.

worker → your network's outbound address → your customer's endpoint
↑
this is the address they allowlist

By default that address is whatever your infrastructure uses (a node’s public IP, a shared NAT pool, an address that changes when a node is replaced), and none of those can be allowlisted.

Put the worker’s subnet behind a managed NAT gateway with a static address. Start here: it needs no Railhook configuration and survives node replacement.

Environment Service Attach
AWS NAT Gateway An Elastic IP, on the route table of the worker nodes’ private subnet
Google Cloud Cloud NAT A reserved static external IP
Azure NAT Gateway A static public IP
Other providers, bare metal A gateway host A floating IP, with the worker’s default route through it

To keep the fixed address for webhook traffic only, run the worker on nodes behind the NAT and other workloads elsewhere. Dashboard traffic, backups and image pulls then stay off an address that may be expensive or rate-limited.

If you run a service mesh or an egress gateway (Istio, Cilium), route the worker’s traffic through it. The redirect happens below the application, so no Railhook setting is needed.

An egress gateway can also log or restrict where deliveries go. It adds to Railhook’s own SSRF protection and does not replace it: Railhook checks every delivery URL before building a request and refuses private addresses unless WEBHOOK_ALLOW_PRIVATE_IPS or WEBHOOK_ALLOWED_HOSTS allows them.

Publish the addresses where customers can read them without asking, with:

  1. Every address that may be used.
  2. That the list can change, and with how much notice. An allowlist changed without warning is an outage on someone else’s infrastructure.

This concerns only webhooks you send. Providers sending webhooks to Railhook need your ingress URL, not an allowlist.