Macaw.Plug.ClientIp (macaw_plug v0.1.4)

Copy Markdown View Source

The client's address behind trusted proxies.

When the connection's peer is a trusted proxy, the client is the right-most X-Forwarded-For entry that is not itself a trusted proxy; entries to its left could have been written by the client. Otherwise the client is the peer, and the header is ignored. The plug sets conn.remote_ip to the client, so logging, rate limits and everything downstream key on the right address, and keeps the socket peer in conn.private.macaw_plug_peer.

plug Macaw.Plug.ClientIp, trusted_proxies: ["10.0.0.0/8", "fd00::/8"]

Trusted proxies default to none. With none trusted, every client is its peer: behind a reverse proxy that means every visitor looks like the proxy, which is wrong but never spoofable. The :trusted_proxies option takes CIDRs or single addresses, or {module, function, args} returning them, called on every request, for a list that changes at runtime. A malformed entry raises at init/1, naming it.

A forwarded request from an untrusted peer (it sent X-Forwarded-For, but its address isn't trusted) is served as usual, with the header ignored, and emits the telemetry event [:macaw_plug, :client_ip, :untrusted_forward] with the peer in its metadata. It usually means a proxy in front of the app is missing from the trusted list. attach_default_logger/1 logs it at most once per interval.

Summary

Functions

Logs an untrusted forward, and a bad entry in a dynamic trusted-proxy list, each at most once per interval_ms (default one minute) on this node. Returns the telemetry handler's attach result.

The X-Forwarded-For entries of a request, left to right.

The socket peer of a request this plug has run on, else its remote_ip.

The client address for a peer, its X-Forwarded-For entries (left to right, as sent) and the trusted CIDRs.

Functions

attach_default_logger(interval_ms \\ 60000)

@spec attach_default_logger(pos_integer()) :: :ok | {:error, :already_exists}

Logs an untrusted forward, and a bad entry in a dynamic trusted-proxy list, each at most once per interval_ms (default one minute) on this node. Returns the telemetry handler's attach result.

forwarded_for(conn)

@spec forwarded_for(Plug.Conn.t()) :: [String.t()]

The X-Forwarded-For entries of a request, left to right.

peer(conn)

@spec peer(Plug.Conn.t()) :: Macaw.Plug.Ip.ip()

The socket peer of a request this plug has run on, else its remote_ip.

resolve(peer, forwarded, trusted)

The client address for a peer, its X-Forwarded-For entries (left to right, as sent) and the trusted CIDRs.