summaryrefslogtreecommitdiff
path: root/lib/pleroma/plugs/remote_ip.ex
blob: 0ac9050d0764149e2361811016179f1282b20c82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Plugs.RemoteIp do
  @moduledoc """
  This is a shim to call [`RemoteIp`](https://git.pleroma.social/pleroma/remote_ip) but with runtime configuration.
  """

  import Plug.Conn

  @behaviour Plug

  @headers ~w[
    x-forwarded-for
  ]

  # https://en.wikipedia.org/wiki/Localhost
  # https://en.wikipedia.org/wiki/Private_network
  @reserved ~w[
    127.0.0.0/8
    ::1/128
    fc00::/7
    10.0.0.0/8
    172.16.0.0/12
    192.168.0.0/16
  ]

  def init(_), do: nil

  def call(%{remote_ip: original_remote_ip} = conn, _) do
    config = Pleroma.Config.get(__MODULE__, [])

    if Keyword.get(config, :enabled, false) do
      %{remote_ip: new_remote_ip} = conn = RemoteIp.call(conn, remote_ip_opts(config))
      assign(conn, :remote_ip_found, original_remote_ip != new_remote_ip)
    else
      conn
    end
  end

  defp remote_ip_opts(config) do
    headers = config |> Keyword.get(:headers, @headers) |> MapSet.new()
    reserved = Keyword.get(config, :reserved, @reserved)

    proxies =
      config
      |> Keyword.get(:proxies, [])
      |> Enum.concat(reserved)
      |> Enum.map(&InetCidr.parse/1)

    {headers, proxies}
  end
end