firewall/firewall2.sh
Your Name 76ba8e5e21 fix
2024-09-12 19:19:30 -06:00

604 lines
14 KiB
Bash
Executable File

#!/bin/bash
MY_IP="47.5.112.50"
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/sbin/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='/usr/sbin/nft'
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'
DATE="$(date +%Y:%H: -d "1 hour ago")"
#DATE="$(date +%Y:%H:)";
RULE_SET='/opt/firewall/nft.rules'
MENU_TOP="=============================FireWall================================="
MENU_BOTTOM="====================================================================="
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
blockCountry() {
for i in "${COUNTRY[@]}"; do
echo
echo "Blocking $i"
DB=($(curl $i))
for j in "${DB[@]}"; do
$NFT add rule ip filter input position 8 ip saddr $j $NFT_DROP
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() {
saved-attackers
watch
pedo-search
bot-search
}
bot-search() {
DATE="$(date +%d/%b/%Y:%H:%M -d '1 min ago')"
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
$NFT add rule ip filter input position 8 ip saddr $i $NFT_DROP
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() {
DATE="$(date +%d/%b/%Y:%H:%M -d '1 min ago')"
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)
$NFT add rule ip filter input position 8 ip saddr $IP $NFT_DROP
message "[Pedo Alert] $PEDO_SEARCH"
drc-alert "$PEDO_SEARCH"
else
echo
echo "No Pedos Found"
echo
fi
}
basic-security() {
$NFT add rule filter input icmp type echo-request $NFT_DROP
$NFT add rule filter input log
$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
}
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
$NFT_TCP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
done
}
wireguard() {
sysctl -w net.ipv4.conf.all.forwarding=1
for i in "${WIREGUARD[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_UDP $i $NFT_ACCEPT
done
}
web() {
for i in "${WEB[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
done
}
dns() {
for i in "${DNS[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_UDP $i $NFT_ACCEPT
done
}
adguard() {
for i in "${ADGUARD[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
done
}
cups() {
for i in "${CUPS[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_UDP $i $NFT_ACCEPT
done
}
bitcoin() {
for i in "${BITCOIN[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
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
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_UDP $i $NFT_ACCEPT
done
}
jellyfin() {
for i in "${JELLYFIN[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
#$NFT6_TCP $i $NFT_ACCEPT
#$NFT6_UDP $i $NFT_ACCEPT
done
}
kde-connect() {
$NFT_TCP 1714-1764 $NFT_ACCEPT
$NFT_UDP 1714-1764 $NFT_ACCEPT
}
nfs() {
for i in "${NFS[@]}"; do
$NFT_TCP $i $NFT_ACCEPT
$NFT_UDP $i $NFT_ACCEPT
done
}
trust() {
for i in "${MACHINES[@]}"; do
$NFT add rule filter input ip saddr $i $NFT_ACCEPT
done
}
import() {
STATS=($(cat $SAVED_BOTS | sort -u))
for i in "${STATS[@]}"; do
if [[ $i == *":"* ]]; then
echo "Skipping ipv6"
else
$NFT add rule ip filter input ip saddr $i $NFT_DROP &
fi
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
# fi
if [[ $HOSTNAME == *"nas"* ]]; then
import
attacker-protection
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() {
DATE="$(date +%d/%b/%Y:%H:%M -d '1 min ago')"
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
DATE="$(date +%d/%b/%Y:%H:%M -d '1 min ago')"
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
$NFT delete rule ip filter input handle $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"
$NFT add rule ip filter input ip saddr $i $NFT_DROP
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 20 ]]; then
$NFT add rule ip filter input position 8 ip saddr "$1" $NFT_DROP
echo $1 >>$TMP_BLOCK
message "Go Spam Attack!"
fi
}
module-get-spam() {
GET_SPAM=$(grep $2 $NGINX_ACCESS | grep -E "GET / HTTP" | wc -l)
if [[ "$GET_SPAM" -gt 20 ]]; then
$NFT add rule ip filter input position 8 ip saddr "$1" $NFT_DROP
echo $1 >>$TMP_BLOCK
message "GET Spam Attack!"
fi
}
module-php() {
PHP_SPAM=$(grep $2 $NGINX_ACCESS | grep -E "defaults.php|config.php|upgrade.php|plugins.php|xmrlpc|cgi-bin|wp-content|wp-admin|wp-includes" | wc -l)
if [[ "$PHP_SPAM" -gt 2 ]]; then
$NFT add rule ip filter input position 8 ip saddr "$1" $NFT_DROP
echo $1 >>$TMP_BLOCK
message "Wordpress Attack!"
fi
}
module-lightning() {
LN_SPAM=$(grep $2 $NGINX_ACCESS | grep "lnurlp/verita84" | wc -l)
if [[ "$LN_SPAM" -gt 5 ]]; then
$NFT add rule ip filter input position 8 ip saddr "$1" $NFT_DROP
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() {
DATE="$(date +%d/%b/%Y:%H:%M -d '1 min ago')"
echo "Scanning $DATE"
echo
IP=($(grep $DATE $NGINX_ACCESS | grep -Evi -f $CRAWLER_DB | grep -Evi -f $SAFE_TRAFFIC | grep -vi $MY_IP | grep -vi '127.0.0.1' | cut -d ' ' -f1 | sort -u))
for i in "${IP[@]}"; do
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 | wc -l)
CHECK=$(cat $NFT_CACHE | sort -u | grep $i)
if [[ "$COUNT" -gt $ATTACK_THRESHOLD ]]; then
echo "Danger!"
echo "$IP $CHECK $COUNT"
if [ "$CHECK" = "" ]; then
echo "Blocking IP: $i Count: $COUNT"
logger "Blocking IP: $i with a count of: $COUNT"
echo $i >>$TMP_BLOCK
$NFT add rule ip filter input position 8 ip saddr $i $NFT_DROP
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
}
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" = "saved" ]; then
saved-bots
else
menu
fi