vpndetection_selectors (vpndetection v3.3.2)

View Source

How the client address is decided.

There is no portable default: a framework's own accessor may return the socket peer, or may already have walked a proxy chain, depending on the framework and on how the application configured it. You know your framework and your edge, so this is yours to choose - and anything of this shape works, so an edge we have never heard of is a fun rather than a feature request:

  fun(View) -> (maps:get(header, View))(<<"x-real-ip">>) end

Summary

Functions

The framework's own client-address accessor. The default.

An address from a single-value header your edge writes - header(<<"cf-connecting-ip">>) behind Cloudflare. Falls back to the framework's accessor when the header is absent.

Run a selector over one request view.

An address from X-Forwarded-For.

Types

selector/0

-type selector() :: fun((view()) -> binary() | undefined).

view/0

-type view() ::
          #{header := fun((binary()) -> binary() | undefined),
            framework_ip := fun(() -> binary() | undefined)}.

Functions

framework_ip()

-spec framework_ip() -> selector().

The framework's own client-address accessor. The default.

header(Name)

-spec header(binary() | string()) -> selector().

An address from a single-value header your edge writes - header(<<"cf-connecting-ip">>) behind Cloudflare. Falls back to the framework's accessor when the header is absent.

resolve(Selector, View)

-spec resolve(selector(), view()) -> binary() | undefined.

Run a selector over one request view.

xff(Depth)

-spec xff(non_neg_integer()) -> selector().

An address from X-Forwarded-For.

The LEFT-MOST entry (Depth 0) is whatever the caller sent, because proxies append to this header, so a visitor who sets it themselves appears first and this returns their forgery. It is only trustworthy when an edge you control overwrites the header. When you know how many proxies sit in front, count from the right: depth 1 is the address your nearest proxy saw.