Skip to content

Client IP at Your Origin

Because all traffic flows through smoxy, every connection your origin server sees comes from a smoxy address - REMOTE_ADDR no longer contains the visitor's IP. smoxy forwards the visitor's real IP address in the X-Real-IP request header. Configure your origin to read the client IP from exactly this header.


Use X-Real-IP, not X-Forwarded-For

smoxy sends two IP-related headers with every request to your origin:

HeaderContent
X-Real-IPAlways exactly one address: the visitor's IP as determined by smoxy at the edge.
X-Forwarded-ForThe full forwarding chain. It can contain several addresses: entries the client sent itself, hops of an upstream CDN (e.g. Cloudflare), and smoxy's own hops.

X-Real-IP is the address smoxy itself uses for security checks, logging, and load balancing - and it is also the basis for the GeoIP headers. It stays correct even when another CDN such as Cloudflare runs in front of smoxy.

X-Forwarded-For, by contrast, is a chain that grows with every hop, and its first entries are client-controlled - anyone can send an X-Forwarded-For header. Extracting the visitor from it means counting proxy hops correctly; one hop off and your logs, IP allowlists, and rate limits use the address of a proxy instead of the visitor. Treat it as an audit trail, not as the source of the client IP.


Apache

Use mod_remoteip so Apache treats the forwarded address as the client IP for logging, access control (Require ip), and everything downstream:

apache
RemoteIPHeader X-Real-IP

In your log format, use %a (the client IP after mod_remoteip) instead of %h (the peer address).

nginx

Use the realip module:

nginx
set_real_ip_from <address of the proxy in front of your origin>;
real_ip_header X-Real-IP;

Application code

If you cannot change the web server configuration, read the header directly, e.g. in PHP:

php
$clientIp = $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'];

Many frameworks offer a "trusted proxies" setting for this; where possible, configure it to use X-Real-IP.


Only trust the header behind smoxy

Like any forwarded header, X-Real-IP is only trustworthy when the request actually came through smoxy. If your origin is also reachable directly from the internet, restrict the trust (RemoteIPTrustedProxy in Apache, set_real_ip_from in nginx) to the addresses that reach your origin, or block direct access to the origin entirely.