From 0a5cd0708f58d592fec6b5e882661139a92b4d20 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Sep 2024 15:44:35 -0600 Subject: [PATCH] fix --- firewall.service | 4 +- firewall.sh | 534 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 536 insertions(+), 2 deletions(-) create mode 100755 firewall.sh diff --git a/firewall.service b/firewall.service index d1444e3..8d8c39a 100644 --- a/firewall.service +++ b/firewall.service @@ -4,8 +4,8 @@ After=gdm.service [Service] Type=oneshot -ExecStart=bash /opt/firewall/firewall2.sh start -ExecStop=bash /opt/firewall/firewall2.sh stop +ExecStart=bash /opt/firewall/firewall.sh start +ExecStop=bash /opt/firewall/firewall.sh stop RemainAfterExit=true StandardOutput=journal diff --git a/firewall.sh b/firewall.sh new file mode 100755 index 0000000..6ce5a19 --- /dev/null +++ b/firewall.sh @@ -0,0 +1,534 @@ +#!/bin/bash +MY_IP="47.5.115.173" +ATTACK_THRESHOLD="50" +SERVER_IP='192.168.0.55' +NGINX_ACCESS="/tmp/access.log" +#Firewall Port Configuration +# +declare -A portConfig +portConfig["https"]="443" +portConfig["http"]="80" +portConfig["cups"]="631" +portConfig["WireGuard"]="57692" +portConfig["AdGuard-1"]="3000" +portConfig["AdGuard-2"]="8082" +portConfig["AdGuard-3"]="853" +portConfig["Uptime"]="4001" +portConfig["DNS-1"]="53" +portConfig["DNS-2"]="67" +portConfig["DNS-3"]="68" +portConfig["CUPS-1"]="631" +portConfig["CUPS-2"]="5353" +#portConfig["Bitcoin-1"]="8333" +#portConfig["Bitcoin-2"]="8332" +#portConfig["Bitcoin-3"]="8333" +#portConfig["Bitcoin-4"]="4050" +#portConfig["KDE-Connect"]="1714-1764" +#portConfig["Lightning-1"]="10009" +#portConfig["Lightning-1"]="9735" +#portConfig["Lightning-2"]="8080" +#portConfig["Lightning-3"]="28334" +#portConfig["Lightning-4"]="28333" +#portConfig["Lightning-5"]="19998" +#portConfig["Lightning-6"]="29000" +portConfig["SyncThing-1"]="22000" +portConfig["SyncThing-2"]="8384" +portConfig["SyncThing-3"]="21027" +#portConfig["NFS-1"]="2049" +#portConfig["NFS-2"]="111" +portConfig["Jellyfin-1"]="8096" +portConfig["Jellyfin-1"]="7359" +portConfig["SSH"]="22" +MACHINES=(127.0.0.1) +VIRT_BRIDGE="virbr0" +#### NFT CONFIG #### +# +NFT='/usr/bin/nft' +NFT_CACHE='/tmp/nft.cache' +TMP_BLOCK='/tmp/tmp-blocked.txt' +#Log Files +# +SAVED_BOTS='/opt/firewall/bots.txt' +CRAWLER_DB='/opt/firewall/crawlers.txt' +SAFE_TRAFFIC='/opt/firewall/safe.txt' +PEDO_DB='/opt/firewall/pedo.txt' +PEDO_LOG='/opt/firewall/pedo-log.txt' +BOT_ACCOUNT="blockbot@detroitriotcity.com" +CRAWLER_TMP='/tmp/crawlers.txt' +RULE_SET='/opt/firewall/nft.rules' +MENU_TOP="=============================FireWall=================================" +MENU_BOTTOM="=====================================================================" + +#Cache the Date and Current Firewall Rules at every launch +DATE="$(date +%d/%b/%Y:%H:%M -d '1 minute ago')" +nft list table filter >$NFT_CACHE + +#Countries to Block +COUNTRY=( + https://www.ipdeny.com/ipblocks/data/countries/il.zone + https://www.ipdeny.com/ipblocks/data/countries/cn.zone +) + +ipBlockParser(){ + if [[ "$1" == *":"* ]]; then + $NFT insert rule ip6 filter input position 0 ip6 saddr $1 drop + else + $NFT insert rule ip filter input position 0 ip saddr "$1" drop + fi +} + +portOpenParser(){ + if [[ "$1" == "443" || "$1" == "80" ]]; then + $NFT add rule ip filter input ct state new tcp dport $1 update @http_ratelimit { ip saddr limit rate 10/second } accept + $NFT add rule ip6 filter input ct state new tcp dport $1 update @http_ratelimit { ip6 saddr limit rate 10/second } accept + else + $NFT add rule ip filter input position 0 tcp dport $1 accept + $NFT add rule ip filter input position 0 udp dport $1 accept + $NFT add rule ip6 filter input position 0 tcp dport $1 accept + $NFT add rule ip6 filter input position 0 udp dport $1 accept + fi +} + +ipDeleteParser(){ + if [[ "$1" == *":"* ]]; then + $NFT delete rule ip6 filter input handle $HANDLE + else + $NFT delete rule ip filter input handle $HANDLE + fi +} + +blockCountry() { + for i in "${COUNTRY[@]}"; do + echo + echo "Blocking $i" + DB=($(curl $i)) + for j in "${DB[@]}"; do + ipBlockParser $j + done + done + +} + +wireguard-networking() { + $NFT add table nat + $NFT add chain nat postrouting + $NFT add rule nat postrouting oif wg0 iif enp11s0 + $NFT add rule nat postrouting oif enp11s0 iif wg0 + $NFT add rule nat postrouting masquerade + $NFT add rule filter forward iifname wg0 oif enp11s0 accept + $NFT add rule filter forward iifname enp11s0 oif wg0 accept + $NFT add rule ip filter input ip saddr 192.168.5.0/24 accept +} + +attacker-protection() { + watch + module-nostr + bot-search +} + +bot-search() { + CRAWLERS=($(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep -Evi 'Guro|spank|report|rape|block' | grep -Ei -f $CRAWLER_DB | grep -Evi -f $SAFE_TRAFFIC | cut -d "-" -f1 | sort -u)) + + echo + echo "Processing Web Crawler list into NFT....." + echo + for i in "${CRAWLERS[@]}"; do + CHECK=$(cat $NFT_CACHE | grep $i) + if [ "$CHECK" = "" ]; then + ipBlockParser $i + echo $i >>$SAVED_BOTS + else + echo + echo "Skipping Duplicate IP $i" + echo + fi + done +} + +drc-alert() { + toot activate $BOT_ACCOUNT + toot post ":emergency: :hacker_p: :hacker_e: :hacker_d: :hacker_o: :trans: :hacker_a: :hacker_l: :hacker_e: :hacker_r: :hacker_t: :emergency2: $1" -m /root/detroit/akkoma/blockbot/pedo.png +} + +pedo-search() { + echo + PEDO_SEARCH=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep -Ei 'tag|search' | grep -Evi -f $CRAWLER_DB | grep -Ei -f $PEDO_DB | head -1) + echo $PEDO_SEARCH + if [ "$PEDO_SEARCH" ]; then + echo "Pedo Found!" + echo "Processing Pedo Searches into NFT....." + IP=$(echo $PEDO_SEARCH | cut -d ' ' -f1) + ipBlockParser $IP + message "[Pedo Alert] $PEDO_SEARCH" + #drc-alert "$PEDO_SEARCH" + echo $IP >> $PEDO_LOG + else + echo + echo "No Pedos Found" + echo + fi +} + +basic-security() { + $NFT flush ruleset + $NFT -f /opt/firewall/ipv4-filter.nft + $NFT -f /opt/firewall/ipv6-filter.nft + $NFT add rule filter input icmp type echo-request drop + $NFT rule filter output accept + $NFT rule filter forward accept + $NFT insert rule filter input ct state established accept + $NFT insert rule filter input iif lo accept + + for i in "${!portConfig[@]}"; do + echo "Enabling Port for: $i" + portOpenParser "${portConfig[$i]}" + + done + + $NFT add rule filter input drop + $NFT add rule ip6 filter input drop +} + +virtualization() { + ip link del virbr0 + killall dnsmasq + /usr/bin/systemctl restart libvirtd + /usr/bin/virsh net-start default + /usr/bin/systemctl restart pleroma + $NFT insert rule filter input iif $VIRT_BRIDGE accept +} + +trust() { + for i in "${MACHINES[@]}"; do + $NFT add rule filter input ip saddr $i accept + done +} + +import-saved() { + + STATS=($(cat $SAVED_BOTS | sort -u)) + for i in "${STATS[@]}"; do + ipBlockParser $i + done +} + + +start() { + basic-security + + if [[ $HOSTNAME == *"nas"* ]]; then + sysctl -w net.ipv4.conf.all.forwarding=1 + import-saved + blockCountry + wireguard-networking + docker restart uptime-kuma + + #Docker + $NFT insert rule filter input iif docker0 accept + else + virtualization + fi +} + +research() { + STATS=($(cat $TMP_BLOCK | sort -u)) + for i in "${STATS[@]}"; do + echo $MENU_TOP + echo " [Researching $i] " + echo + DATA=$(grep $i $NGINX_LOG | grep -Evi -f $SAFE_TRAFFIC) + echo "$DATA" + echo + echo $MENU_BOTTOM + echo + read -p 'Press Enter to Continue ' -e + done +} + +automaticStatus() { + status + sleep 30 + automaticStatus +} + +status() { + clear + STATS=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | wc -l) + GET=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep GET | wc -l) + POST=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep POST | wc -l) + PUT=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep -i PUT | wc -l) + NOT_FOUND=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep 404 | wc -l) + GATEWAY=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep 502 | wc -l) + SUCCESS=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep 200 | wc -l) + CRAWL=$(grep $DATE $NGINX_ACCESS | grep -vi $MY_IP | grep -Ei -f $CRAWLER_DB | wc -l) + echo $MENU_TOP + echo "Attack Threshold: $ATTACK_THRESHOLD" + echo "Firewall Rules: $($NFT list table filter | wc -l)" + echo + echo "Traffic Last Minute: $STATS" + echo " GET: $GET" + echo " PUT: $PUT" + echo " POST: $POST" + echo " Crawlers: $CRAWL" + echo + echo "Query Stats:: " + echo " 200: $SUCCESS" + echo " 404: $NOT_FOUND" + echo " 502: $GATEWAY" + echo + #echo "Dropped Traffic: $($NFT list table filter | grep -Ei 'log counter packets' | cut -d ' ' -f6)" + echo + echo "Rate-limited IP's:" + cat $TMP_BLOCK | sort -u + echo $MENU_BOTTOM +} + +stop() { + #forgive + $NFT -s list ruleset | tee $RULE_SET + $NFT flush ruleset + $NFT -f /usr/share/nftables/ipv4-filter.nft + $NFT add rule filter input icmp type echo-request accept + $NFT rule filter input accept + $NFT rule filter output accept + $NFT rule filter forward accept + $NFT insert rule filter input ct state established accept + $NFT insert rule filter input iif lo accept + + $NFT -f /opt/firewall/ipv6-filter.nft + # $NFT add rule ip6 filter input icmpv6 type nd-neighbor-solicit accept + # $NFT add rule ip6 filter input icmpv6 type nd-router-advert accept + message "Stopping Firewall" +} + +forgive() { + IP=($(grep -vi $MY_IP $TMP_BLOCK | sort -u)) + echo $IP + for i in "${IP[@]}"; do + HANDLE=$(nft -n -a list ruleset | grep $i | grep handle | cut -d '#' -f2 | cut -d ' ' -f3) + echo "Removing: $i Handle: $HANDLE" + echo $NFT delete rule ip filter input handle $HANDLE + ipDeleteParser $HANDLE + done + + echo "Clearing old $TMP_BLOCK" + echo >$TMP_BLOCK +} + +module-go() { + GO_SPAM=$(grep $2 $NGINX_ACCESS | grep -E "Go-http-client" | wc -l) + if [[ "$GO_SPAM" -gt 10 ]]; then + ipBlockParser "$1" + echo $1 >>$TMP_BLOCK + message "Go Spam Attack!" + fi +} + + +module-akkoma() { + SEARCH_SPAM=$(grep $2 $NGINX_ACCESS | grep -E "api/v1/instance|api/v1/notifications|api/v1/accounts|api/v2/search|timelines/public|timelines/home|/api/v1/accounts" | grep $1 | wc -l) + CHECK=$(cat $NFT_CACHE | sort -u | grep $i) + if [[ "$SEARCH_SPAM" -gt 30 ]]; then + echo "$IP $CHECK $COUNT" + if [ "$CHECK" = "" ]; then + ipBlockParser "$1" + echo $1 >>$TMP_BLOCK + message "module-akkoma: Spam Attack! $i" + echo "module-akkoma: Spam $1" + else + echo "module-akkoma: Ignoring Duplicate IP: $i" + fi + fi +} + +module-get-spam() { + GET_SPAM=$(grep $2 $NGINX_ACCESS | grep -E "GET / HTTP" | wc -l) + if [[ "$GET_SPAM" -gt 5 ]]; then + ipBlockParser "$1" + echo $1 >>$TMP_BLOCK + message "GET Spam Attack! $1" + fi +} + +module-php() { + PHP_SPAM=$(grep $2 $NGINX_ACCESS | grep -E ".php|cgi-bin|wp-content|wp-admin|wp-includes" | wc -l) + if [[ "$PHP_SPAM" -gt 1 ]]; then + ipBlockParser "$1" + echo $1 >>$TMP_BLOCK + message "PHP Attack!" + fi +} + +module-lightning() { + LN_SPAM=$(grep $2 $NGINX_ACCESS | grep "lnurlp/verita84" | wc -l) + if [[ "$LN_SPAM" -gt 5 ]]; then + ipBlockParser "$1" + message "Lightning Spam Attack!" + echo $1 >>$TMP_BLOCK + fi +} + +message() { + BOT_ACCOUNT="blockbot@detroitriotcity.com" + echo "$1" | /root/go/bin/algia dm-post -u 33c74427f3b2b73d5e38f3e6c991c122a55d204072356f71da49a0e209fb6940 --stdin +} + +watch() { + echo "Scanning $DATE" + echo + IP=($(grep $DATE $NGINX_ACCESS | grep -Evi -f $SAFE_TRAFFIC | grep -Evi -f $CRAWLER_DB | grep -Evi -f $SAVED_BOTS |grep -vi $MY_IP | grep -vi '127.0.0.1' | cut -d ' ' -f1 | sort -u)) + + for i in "${IP[@]}"; do + module-akkoma "$i" "$DATE" + module-lightning "$i" "$DATE" + module-php "$i" "$DATE" + module-go "$i" "$DATE" + module-get-spam "$i" "$DATE" + + COUNT=$(grep $DATE $NGINX_ACCESS | grep $i | grep -Evi -f $SAFE_TRAFFIC | grep -Evi -f $SAVED_BOTS | wc -l) + + CHECK=$(cat $NFT_CACHE | sort -u | grep $i) + if [[ "$COUNT" -gt $ATTACK_THRESHOLD ]]; then + if [ "$CHECK" = "" ]; then + echo "Danger! Blocking IP: $i Count: $COUNT" + logger "Blocking IP: $i with a count of: $COUNT" + echo $i >>$TMP_BLOCK + ipBlockParser $i + message "Blocking IP: $i with a count of: $COUNT" + else + echo + echo "Skipping Duplicate IP" + echo + + fi + else + echo + echo "$i count: $COUNT below Threshhold: $ATTACK_THRESHOLD" + echo + fi + done +} + +module-nostr(){ + IP=($(grep $DATE $NGINX_ACCESS | grep "/block=" | cut -d '=' -f2| cut -d ' ' -f1 | sed 's/"//')) + for i in "${IP[@]}"; do + echo $i + if [[ "$i" == *"npub"* ]]; then + bash /opt/strfry-policies/block.sh $i + else + echo "No Npubs to block" + fi + done +} + +test-bots() { + TEST=($(cat $SAVED_BOTS)) + for i in "${TEST[@]}"; do + DATA=$(grep $i $NGINX_ACCESS | grep -Evi -f $CRAWLER_DB) + if [ "$DATA" = "" ]; then + echo "No Data. Probably OK" + else + echo $DATA + echo + read -p 'Press Enter to Continue ' -e + fi + done +} + +research-ip() { + echo "Enter an IP Address to search" + read -p 'IP Address: ' -e IP + cat $NGINX_ACCESS | grep $IP + echo + read -p 'Press Enter to Continue ' -e +} + +menu() { + clear + echo + echo $MENU_TOP + echo "1. Start" + echo "2. Stop" + echo "3. Reseearch" + echo "4. Forgive" + echo "5. Status" + echo "6. Live Traffic" + echo "7. Test Bot Search Rules" + echo "8. Research IP" + echo "9. View Current Rule Set" + echo "0. Quit" + echo $MENU_BOTTOM + echo + read -p 'Choice: ' CHOICE + echo + if [ "$CHOICE" = "1" ]; then + echo + echo "Starting Firewall" + start + read -p 'Press Enter to Continue ' -e- + elif [ "$CHOICE" = "2" ]; then + echo + echo "Stopping Firewall" + stop + read -p 'Press Enter to Continue ' -e + elif [ "$CHOICE" = "3" ]; then + research + read -p 'Press Enter to Continue ' -e + elif [ "$CHOICE" = "4" ]; then + forgive + elif [ "$CHOICE" = "55" ]; then + automaticStatus + elif [ "$CHOICE" = "5" ]; then + status + read -p 'Press Enter to Continue ' -e + elif [ "$CHOICE" = "6" ]; then + tail -f $NGINX_ACCESS | grep -Evi -f $SAFE_TRAFFIC | grep -Evi -f $CRAWLER_DB + read -p 'Press Enter to Continue ' -e + elif [ "$CHOICE" = "7" ]; then + test-bots + read -p 'Press Enter to Continue ' -e + elif [ "$CHOICE" = "8" ]; then + research-ip + read -p 'Press Enter to Continue ' -e + elif [ "$CHOICE" = "9" ]; then + nft -s list ruleset | less + elif [ "$CHOICE" = "0" ]; then + exit + fi + echo + menu +} + +if [ "$1" = "start" ]; then + start +elif [ "$1" = "virt" ]; then + virtualization +elif [ "$1" = "bot-search" ]; then + bot-search +elif [ "$1" = "attacker-protection" ]; then + attacker-protection +elif [ "$1" = "country" ]; then + blockCountry +elif [ "$1" = "status" ]; then + automaticStatus +elif [ "$1" = "forgive" ]; then + forgive +elif [ "$1" = "watch" ]; then + watch +elif [ "$1" = "research" ]; then + research +elif [ "$1" = "stop" ]; then + stop +elif [ "$1" = "message" ]; then + message $2 +elif [ "$1" = "test" ]; then + test-bots +elif [ "$1" = "nostr" ]; then + module-nostr +elif [ "$1" = "import" ]; then + import-saved +elif [ "$1" = "saved" ]; then + saved-bots +else + menu +fi