aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Felder <feld@feld.me>2021-01-24 14:56:45 -0600
committerMark Felder <feld@feld.me>2021-01-24 15:06:19 -0600
commitc4701323dd92c29208730fcf49ada046986e7171 (patch)
treebec30727d3ce6d3ee8c4ee0013f7d4791f8ab5d2
parent0a6f5f479348eff5f5404d4455fcb8254809812f (diff)
downloadpleroma-c4701323dd92c29208730fcf49ada046986e7171.tar.gz
Initial unoptimized version of using RBL in an MRF
-rw-r--r--config/config.exs5
-rw-r--r--lib/pleroma/web/activity_pub/mrf/dnsrbl.ex90
2 files changed, 95 insertions, 0 deletions
diff --git a/config/config.exs b/config/config.exs
index c4a690799..b673d35d7 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -399,6 +399,11 @@ config :pleroma, :mrf_vocabulary,
accept: [],
reject: []
+config :pleroma, :mrf_dnsrbl,
+ nameserver: "bl.pleroma.com",
+ port: 53,
+ zone: nil
+
# threshold of 7 days
config :pleroma, :mrf_object_age,
threshold: 604_800,
diff --git a/lib/pleroma/web/activity_pub/mrf/dnsrbl.ex b/lib/pleroma/web/activity_pub/mrf/dnsrbl.ex
new file mode 100644
index 000000000..37e13d4dd
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/dnsrbl.ex
@@ -0,0 +1,90 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.DnsRblPolicy do
+ @moduledoc "Dynamic activity filtering based on public database"
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ alias Pleroma.Config
+
+ defp check_rbl(%{host: actor_host} = _actor_info, object) do
+ rblconfig = Config.get([:mrf_dnsrbl])
+ rblhost = rblconfig[:nameserver]
+
+ {:ok, rblnsip} =
+ case rblhost |> String.to_charlist() |> :inet_parse.address() do
+ {:ok, _} -> rblhost |> String.to_charlist() |> :inet_parse.address()
+ _ -> {:ok, rblhost |> :inet_res.lookup(:in, :a) |> Enum.random()}
+ end
+
+ rblport = rblconfig[:port]
+
+ rblzone = rblconfig[:zone] || rblhost
+
+ query = (actor_host <> "." <> rblzone) |> String.to_charlist()
+
+ rbl_response =
+ :inet_res.lookup(query, :in, :a, nameservers: [{rblnsip, rblport}], timeout: 1000, retry: 1)
+
+ cond do
+ actor_host == Config.get([Pleroma.Web.Endpoint, :url, :host]) -> {:ok, object}
+ rbl_response != [] -> {:reject, "[DNSRBLPolicy]"}
+ true -> {:ok, object}
+ end
+ end
+
+ @impl true
+ def filter(%{"actor" => actor} = object) do
+ actor_info = URI.parse(actor)
+
+ with {:ok, object} <- check_rbl(actor_info, object) do
+ {:ok, object}
+ else
+ _ -> {:reject, "[DNSRBLPolicy]"}
+ end
+ end
+
+ @impl true
+ def filter(object), do: {:ok, object}
+
+ @impl true
+ def describe do
+ mrf_dnsrbl =
+ Config.get(:mrf_dnsrbl)
+ |> Enum.into(%{})
+
+ {:ok, %{mrf_dnsrbl: mrf_dnsrbl}}
+ end
+
+ @impl true
+ def config_description do
+ %{
+ key: :mrf_dnsrbl,
+ related_policy: "Pleroma.Web.ActivityPub.MRF.DnsRblPolicy",
+ label: "MRF DNSRBL",
+ description: "DNS RealTime Blackhole Policy",
+ children: [
+ %{
+ key: :nameserver,
+ type: {:string},
+ description: "DNSRBL NameServer to Query",
+ suggestions: ["bl.pleroma.com"]
+ },
+ %{
+ key: :port,
+ type: {:string},
+ description: "Nameserver port",
+ suggestions: ["53"]
+ },
+ %{
+ key: :zone,
+ type: {:string},
+ description:
+ "Zone for querying, if unable to detect because nameserver is an IP address",
+ suggestions: ["bl.pleroma.com"]
+ }
+ ]
+ }
+ end
+end