Compare commits
7 Commits
feature/sa
...
feat/mrf-d
Author | SHA1 | Date | |
---|---|---|---|
|
127c5ad253 | ||
|
617ec63483 | ||
|
00828731fb | ||
|
bf15a1c7f3 | ||
|
a55c6de32b | ||
|
f44e11c7ab | ||
|
c4701323dd |
@ -399,6 +399,11 @@ config :pleroma, :mrf_vocabulary,
|
||||
accept: [],
|
||||
reject: []
|
||||
|
||||
config :pleroma, :mrf_dnsrbl,
|
||||
nameserver: "bl.pleroma.com",
|
||||
port: 53,
|
||||
rblzone: nil
|
||||
|
||||
# threshold of 7 days
|
||||
config :pleroma, :mrf_object_age,
|
||||
threshold: 604_800,
|
||||
|
113
lib/pleroma/web/activity_pub/mrf/dns_rbl_policy.ex
Normal file
113
lib/pleroma/web/activity_pub/mrf/dns_rbl_policy.ex
Normal file
@ -0,0 +1,113 @@
|
||||
# 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])
|
||||
|
||||
# :nameserver is the RBL server we want to query
|
||||
rblhost = rblconfig[:nameserver]
|
||||
|
||||
# We have to query the nameserver's by IP, so look it up if an IP address wasn't
|
||||
# provided in the config.
|
||||
# You may want this to be a hostname with round-robin A records for basic load
|
||||
# balancing, so we try that.
|
||||
{:ok, rblnsip} =
|
||||
case rblhost |> String.to_charlist() |> :inet_parse.address() do
|
||||
{:ok, _} -> rblhost |> String.to_charlist() |> :inet_parse.address()
|
||||
_ -> {:ok, rblhost |> String.to_charlist() |> :inet_res.lookup(:in, :a) |> Enum.random()}
|
||||
end
|
||||
|
||||
rblport = rblconfig[:port]
|
||||
|
||||
# If the provided nameserver was an IP, we also need to know the zone because we can't
|
||||
# derive it from the hostname. If the DNSRBL server software is configured to use "bl.pleroma.com"
|
||||
# -- irrespective of the actual hostname/IP used to reach it --
|
||||
# we need the configured zone as queries are nested under the zone. e.g., if you're checking the
|
||||
# status of pleroma.host you are querying for:
|
||||
#
|
||||
# dig @nameserverip pleroma.host.bl.pleroma.com. in A
|
||||
#
|
||||
rblzone = rblconfig[:rblzone] || rblhost
|
||||
|
||||
# concatenate the host we're checking with the zone, e.g., "pleroma.host" <> . <> "bl.pleroma.com" <> .
|
||||
# trim off duplicate trailing period in case it was supplied in the config.
|
||||
query =
|
||||
(actor_host <> "." <> rblzone <> ".")
|
||||
|> String.replace_suffix("..", ".")
|
||||
|> String.to_charlist()
|
||||
|
||||
# Timeout of 1s, retry 1
|
||||
# We will only be using UDP for queries, so if the DNSRBL server is > 500ms away it
|
||||
# may not work. However you wouldn't want it to be this far away or it will slow things
|
||||
# down. I think we should probably try to cache entries in cachex too, maybe 300s TTL ?
|
||||
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: :rblzone,
|
||||
type: {:string},
|
||||
description:
|
||||
"Zone for querying, if unable to detect because nameserver is an IP address",
|
||||
suggestions: ["bl.pleroma.com"]
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user