From e1749a8b45e0ec3811c717b8a44beabc78007c05 Mon Sep 17 00:00:00 2001 From: tastytea Date: Sat, 13 Jul 2019 23:41:03 +0200 Subject: [PATCH] Added firewall_pleroma_rejects.sh. --- firewall_pleroma_rejects.sh | 134 ++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100755 firewall_pleroma_rejects.sh diff --git a/firewall_pleroma_rejects.sh b/firewall_pleroma_rejects.sh new file mode 100755 index 0000000..70865f2 --- /dev/null +++ b/firewall_pleroma_rejects.sh @@ -0,0 +1,134 @@ +#!/bin/zsh +# Generate nftables rules from the list of rejected instances. The list is +# fetched from nodeinfo 2.1. masto.host- and CloudFlare-IPs are filtered out. +# BE CAREFUL: Some instances may run under a shared IP, you may block more than +# you want. No warranties and so on. + +# Version: 2019-07-13_1 + +# Before you run this script for the first time, run: +# nft add table inet fediverse + +function get_domains() +{ + local instance="${1}" + local nodeinfo=$(curl -s "https://${instance}/nodeinfo/2.1.json") + local domains_json=$(jq -c '.metadata.federation.mrf_simple.reject' <<<"${nodeinfo}") + + sed -e 's/\[//' -e 's/\]//' -e 's/"//g' -e 's/,/\n/g' <<<"${domains_json}" +} + +function get_ips() +{ + local domain="${1}" + + # Resolve aliases. + local realdomain="${domain}" + while [[ -n "${realdomain}" ]]; do + realdomain=$(dig +short "${domain}" CNAME) + if [[ -n "${realdomain}" ]]; then + domain="${realdomain:0:-1}" + fi + done + + for ip_version in AAAA A; do + for ip in $(dig +short "${domain}" "${ip_version}"); do + echo "${ip}" + done + done +} + +function gen_rule() +{ + # TODO: Filter out Cloudflare-IPs. + local ip="${1}" + local domain="${2}" + # Regular expressions to ignore. + local -a ignorelist=("^2001:41d0:302:1100:" # masto.host + "^217\.182\.80\.236$" # masto.host + "^2a06:98c[0-7]:" # CloudFlare 2a06:98c0::/29 + "^2400:cb00:" # CloudFlare 2400:cb00::/32 + "^2606:4700:" # CloudFlare 2606:4700::/32 + "^2803:f800:" # CloudFlare 2803:f800::/32 + "^2405:b500:" # CloudFlare 2405:b500::/32 + "^2405:8100:" # CloudFlare 2405:8100::/32 + "^2c0f:f248:" # CloudFlare 2c0f:f248::/32 + "^104\.1[6-9]\." # CloudFlare 104.16.0.0/12 + "^104\.2[0-9]\." + "^104\.3[01]\." + "^172\.6[4-9]\." # CloudFlare 172.64.0.0/13 + "^172\.7[01]\." + "^162\.15[89]\." # CloudFlare 162.158.0.0/15 + "^198\.41\.12[89]\." # CloudFlare 198.41.128.0/17 + "^198\.41\.1[3-5][0-9]\." + "^141\.101\.6[4-9]\." # CloudFlare 141.101.64.0/18 + "^141\.101\.[7-9][0-9]\." + "^141\.101\.1[01][0-9]\." + "^141\.101\.12[0-7]\." + "^108\.162\.19[2-9]\." # CloudFlare 108.162.192.0/18 + "^108\.162\.2[0-9]+\." + "^173\.245\.4[89]\." # CloudFlare 173.245.48.0/20 + "^173\.245\.5[0-9]\." + "^173\.245\.6[0-3]\." + "^190\.93\.2[45][0-9]\." # CloudFlare 190.93.240.0/20 + "^188\.114\.9[6-9]\." # CloudFlare 188.114.96.0/20 + "^188\.114\.10[0-9]\." + "^188\.114\.111\." + "^103\.21\.24[4-7]\." # CloudFlare 103.21.244.0/22 + "^103\.22\.20[0-3]\." # CloudFlare 103.22.200.0/22 + "^197\.234\.24[0-3]" # CloudFlare 197.234.240.0/22 + "^131\.0\.7[2-5]\." # CloudFlare 131.0.72.0/22 + ) + + for ignore in ${ignorelist}; do + if [[ "${ip}" =~ "${ignore}" ]]; then + return + fi + done + + if grep -q ":" <<<${ip}; then + echo " ip6 saddr ${ip} drop comment \"${domain}\"" + else + echo " ip saddr ${ip} drop comment \"${domain}\"" + fi +} + +function main() +{ + local instance="${1}" + + if [[ -z "${instance}" ]]; then + echo "Usage: ${ZSH_ARGZERO} instance" >&2 + echo " ${ZSH_ARGZERO} instance | nft -f -" >&2 + return 1 + fi + if ! command -v dig > /dev/null; then + echo "Error: dig not found. Please install bind-tools." >&2 + return 2 + fi + if ! command -v curl > /dev/null; then + echo "Error: curl not found. Please install it." >&2 + return 2 + fi + if ! command -v jq > /dev/null; then + echo "Error: jq not found. Please install it." >&2 + return 2 + fi + + echo "#!/sbin/nft -f" + echo "flush table inet fediverse" + echo "table inet fediverse {" + echo " chain input {" + echo " type filter hook input priority 0; policy accept;" + + for domain in $(get_domains "${instance}"); do + for ip in $(get_ips "${domain}"); do + gen_rule "${ip}" "${domain}" + done + done + + echo " }" + echo "}" +} + +main "${1}"