firewall/firewall2.sh
Your Name a0cbf7c6f0 fix
2024-09-22 23:10:26 -06:00

639 lines
15 KiB
Bash
Executable File

#!/bin/bash
MY_IP="47.5.115.173"
ATTACK_THRESHOLD="50"
SERVER_IP='192.168.0.55'
NGINX_ACCESS="/tmp/access.log"
#WIREGUARD=(51820)
WIREGUARD=(57692)
WEB=(80 443)
ADGUARD=(3000 8082 853)
UPTIME=(4001)
DNS=(53 67 68)
CUPS=(631 5353)
BITCOIN=(8333 8332 8334 4050)
LND=(10009 9735 8080 28334 28333 19998 29000)
SYNCTHING=(22000 8384 21027)
NFS=(2049 111)
JELLYFIN=(8096 7359)
MACHINES=(127.0.0.1)
VIRT_BRIDGE="virbr0"
ADMIN=(22)
#### NFT CONFIG ####
NFT='/usr/bin/nft'
NFT_TCP="$NFT add rule ip filter input tcp dport"
NFT_UDP="$NFT add rule ip filter input udp dport"
NFT6_UDP="$NFT add rule ip6 filter input udp dport"
NFT6_TCP="$NFT add rule ip6 filter input tcp dport"
NFT_DROP='counter drop'
NFT_ACCEPT='counter accept'
NFT_CACHE='/tmp/nft.cache'
TMP_BLOCK='/tmp/tmp-blocked.txt'
####
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'
ATTACKER_DB='/opt/firewall/attacker-db.txt'
ATTACKER_LOG='/opt/firewall/attackers.txt'
BOT_ACCOUNT="blockbot@detroitriotcity.com"
CRAWLER_TMP='/tmp/crawlers.txt'
RULE_SET='/opt/firewall/nft.rules'
MENU_TOP="=============================FireWall================================="
MENU_BOTTOM="====================================================================="
DATE="$(date +%d/%b/%Y:%H:%M -d '15 seconds ago')"
#DATE="$(date +%d/%b/%Y:%H:%M:%S -d '15 seconds ago')"
echo $DATE
COUNTRY=(
https://www.ipdeny.com/ipblocks/data/countries/il.zone
https://www.ipdeny.com/ipblocks/data/countries/cn.zone
)
nft list table filter >$NFT_CACHE
ipBlockParser(){
if [[ "$1" == *":"* ]]; then
echo "Skipping ip6"
#$NFT add rule ip6 filter input position 0 ip6 saddr $1 $NFT_DROP
else
$NFT add rule ip filter input position 0 ip saddr "$1" $NFT_DROP
fi
}
portOpenParser(){
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_UDP $i $NFT_ACCEPT
}
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 $NFT_ACCEPT
$NFT add rule filter forward iifname enp11s0 oif wg0 $NFT_ACCEPT
$NFT add rule ip filter input ip saddr 192.168.5.0/24 $NFT_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 add rule filter input icmp type echo-request $NFT_DROP
#$NFT rule filter input log $NFT_DROP
$NFT rule filter output $NFT_ACCEPT
$NFT rule filter forward $NFT_ACCEPT
$NFT insert rule filter input ct state established $NFT_ACCEPT
$NFT insert rule filter input iif lo $NFT_ACCEPT
$NFT -f /opt/firewall/ipv6-filter.nft
# $NFT add rule ip6 filter input icmpv6 type nd-neighbor-solicit $NFT_DROP
# $NFT add rule ip6 filter input icmpv6 type nd-router-advert $NFT_DROP
$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 $NFT_ACCEPT
}
uptimeKuma() {
for i in "${UPTIME[@]}"; do
$NFT add rule ip filter input ip saddr $SERVER_IP tcp dport $i accept
done
}
admin() {
for i in "${ADMIN[@]}"; do
portOpenParser $i
done
}
wireguard() {
sysctl -w net.ipv4.conf.all.forwarding=1
for i in "${WIREGUARD[@]}"; do
portOpenParser $i
done
}
web() {
for i in "${WEB[@]}"; do
portOpenParser $i
done
}
dns() {
for i in "${DNS[@]}"; do
portOpenParser $i
$NFT_UDP $i $NFT_ACCEPT
done
}
adguard() {
for i in "${ADGUARD[@]}"; do
portOpenParser $i
done
}
cups() {
for i in "${CUPS[@]}"; do
portOpenParser $i
done
}
bitcoin() {
for i in "${BITCOIN[@]}"; do
portOpenParser $i
done
}
lnd() {
for i in "${LND[@]}"; do
$NFT add rule ip filter input ip saddr $SERVER_IP tcp dport $i accept
done
}
syncthingServer() {
for i in "${SYNCTHING[@]}"; do
$NFT add rule ip filter input ip saddr $SERVER_IP tcp dport $i accept
done
}
syncthing() {
for i in "${SYNCTHING[@]}"; do
portOpenParser $i
done
}
jellyfin() {
for i in "${JELLYFIN[@]}"; do
portOpenParser $i
done
}
kde-connect() {
$NFT_TCP 1714-1764 $NFT_ACCEPT
$NFT_UDP 1714-1764 $NFT_ACCEPT
}
nfs() {
for i in "${NFS[@]}"; do
portOpenParser $i
done
}
trust() {
for i in "${MACHINES[@]}"; do
$NFT add rule filter input ip saddr $i $NFT_ACCEPT
done
}
quickImport() {
STATS=($(cat /tmp/db.txt | sort -u))
for i in "${STATS[@]}"; do
ipBlockParser $i
done
}
import-saved() {
STATS=($(cat $SAVED_BOTS | sort -u))
for i in "${STATS[@]}"; do
ipBlockParser $i
done
}
start() {
$NFT flush ruleset
# if [ -f "$RULE_SET" ]; then
# echo
# echo "Importing Existing Rule Set"
#$NFT -f $RULE_SET
# else
#echo
#echo "No existing Rules saved"
$NFT -f /opt/firewall/ipv4-filter.nft
$NFT -f /opt/firewall/ipv6-filter.nft
# fi
if [[ $HOSTNAME == *"nas"* ]]; then
import-saved
wireguard
web
admin
adguard
dns
cups
syncthingServer
syncthing
blockCountry
jellyfin
wireguard-networking
uptimeKuma
docker restart uptime-kuma
$NFT insert rule filter input iif docker0 $NFT_ACCEPT
basic-security
else
virtualization
basic-security
fi
message "Starting Firewall"
}
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 $NFT_ACCEPT
$NFT rule filter input $NFT_ACCEPT
$NFT rule filter output $NFT_ACCEPT
$NFT rule filter forward $NFT_ACCEPT
$NFT insert rule filter input ct state established $NFT_ACCEPT
$NFT insert rule filter input iif lo $NFT_ACCEPT
$NFT -f /opt/firewall/ipv6-filter.nft
# $NFT add rule ip6 filter input icmpv6 type nd-neighbor-solicit $NFT_ACCEPT
# $NFT add rule ip6 filter input icmpv6 type nd-router-advert $NFT_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
}
saved-attackers() {
echo
IP=($(cat $ATTACKER_LOG | grep -vi $MY_IP | cut -d ' ' -f1 | sort -u))
for i in "${IP[@]}"; do
CHECK=$(cat $NFT_CACHE | grep $i)
if [ "$CHECK" = "" ]; then
echo "Blocking IP: $i"
logger "Blocking IP: $i"
ipBlockParser $i
else
echo
echo "Skipping Duplicate IP $i"
echo
fi
done
}
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 "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" = "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
elif [ "$1" = "saved" ]; then
saved-bots
else
menu
fi