Packages

An Elixir plug to rewrite the value of remote_ip key of Plug.Conn struct if the request comes from a trusted proxy.

Current section

Files

Jump to
trusted_proxy_rewriter lib trusted_proxy_rewriter.ex
Raw

lib/trusted_proxy_rewriter.ex

defmodule TrustedProxyRewriter do
import Plug.Conn, only: [get_req_header: 2]
@behaviour Plug
@xff_header "x-real-ip"
def init(opts) do
trusted_proxies = Keyword.get(opts, :proxies, []) |> Enum.map(&InetCidr.parse/1)
header_name = Keyword.get(opts, :header_name, @xff_header)
{header_name, trusted_proxies}
end
def call(conn, {header_name, trusted_proxies}) do
if trust_ip?(conn.remote_ip, trusted_proxies) do
conn |> get_req_header(header_name) |> rewrite_remote_ip(conn)
else
conn
end
end
defp trust_ip?(remote_ip, trusted_proxies) do
Enum.any?(trusted_proxies, &(InetCidr.contains?(&1, remote_ip)))
end
defp rewrite_remote_ip([], conn) do
conn
end
#Header contains only on ip
defp rewrite_remote_ip([header | _], conn) do
case parse_addresses(header) do
ip when is_tuple(ip) ->
%{conn | remote_ip: ip}
nil ->
conn
end
end
defp parse_addresses(nil), do: nil
defp parse_addresses(address) do
case address |> String.trim |> to_charlist |> :inet.parse_address do
{:ok, ip} -> ip
_ -> nil
end
end
end