Obsah

Nastavení firewallu a routování

Popis nastavení pro router, kdy se budou z vnitřní sítě routovat packety do internetu.

Editace /etc/sysctl.conf

Povolení forwardování ipv4 a v tuto chvíli vypnut ipv6

net.ipv4.ip_forward=1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Reload systemd:

sysctl -p

UFW

ufw logging on
ufw logging medium
 
ufw allow 53 comment "open DNS port"
ufw allow 67,68/udp comment "open DHCP ports"
ufw allow 5555/tcp comment "open SoftEther"
ufw allow 500/udp comment "SoftEther"
ufw allow 4500/udp comment "SoftEther"
ufw allow 443/tcp comment "open SoftEther over HTTPS"
ufw limit 22/tcp comment "limited connection to ssh. Allows 6 connection per 30 sec"

Pokud na serveru spustím služby jako nextcloudpi, http server nebo monit, je potřeba to ve firewallu povolit.

ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 80 proto tcp comment "Open port 80 from internal network"
ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 443 proto tcp comment "Open port 443 from internal network"
ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 4443 proto tcp comment "Open port 4443 from internal network"
ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 2812 proto tcp comment "Open MONIT port 2812 from internal network"

Pro povolení sdílení Windows (Samba) je potřeba na firewallu povolit na interní síti následující porty:

ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 137 proto udp comment "Samba port 137/udp"
ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 138 proto udp comment "Samba port 138/udp"
ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 139 proto tcp comment "Samba port 139/tcp"
ufw allow in on br0 from 192.168.0.1/24 to 192.168.0.1/32 port 445 proto tcp comment "Samba port 445/tcp"

Editace /etc/default/ufw

Zajisti, aby v souboru bylo následující nastavení:

DEFAULT_INPUT_POLICY="DROP"
DEFAULT_OUTPUT_POLICY="ACCEPT"
DEFAULT_FORWARD_POLICY="ACCEPT"
IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"

Pokud bych chtěl vypnout IPV6, tak v souboru nastavím:

IPV6=no

Editace /etc/ufw/sysctl.conf

Zajisti, aby v souboru bylo následující nastavení:

net/ipv4/ip_forward=1

Editace /etc/ufw/before.rules

Na začátek souboru přidat:

*nat
:POSTROUTING ACCEPT [0:0]
 
# Forward traffic through eth0 - Change to match you out-interface
-A POSTROUTING -s 192.168.0.0/24 -o wan -j MASQUERADE
COMMIT

Na jiném serveru mám OpenVPN službu a pro tu bylo nutné v tomto souboru před všechna pravidla zase přidat následující kód:

# START OPENVPN RULES                                                                                                                                                                                              
# NAT table rules                                                                                                                                                                                                  
*nat                                                                                                                                                                                                               
:POSTROUTING ACCEPT [0:0]                                                                                                                                                                                          
# Allow traffic from OpenVPN client to eth0                                                                                                                                                                        
-A POSTROUTING -s 10.9.0.0/8 -o ens3 -j MASQUERADE                                                                                                                                                                 
COMMIT                                                                                                                                                                                                             
# END OPENVPN RULES 

Dále jsem mezi filtry přidal filtr :port-scan, výsledek pak vypadá takto:

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
:port-scan - [0:0]
# End required lines

A za pravidla

# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

jsem přidával další pravidla.

# Blacklisting IP
#-I INPUT -m set --match-set blacklist src -j DROP
#-I INPUT -m set --match-set blacklist src -j LOG --log-prefix "IP Blacklisted: "
-A ufw-before-input -m set --match-set blacklist src -j LOG --log-prefix "[IP BLACKLISTED] "
-A ufw-before-input -m set --match-set blacklist src -j DROP

Tímto nastavením jsem se inspiroval pro webserver. V pravidlech je důležité změnit vstupní interface, který je uveden jako wan.

# Start CUSTOM UFW added by clusterednetworks 2020-10-20
# https://github.com/clusterednetworks/ufw-rate-limit-http-https
# Limit to 20 concurrent connections on port 80/443 per IP
-A ufw-before-input -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 -j DROP
-A ufw-before-input -p tcp --syn --dport 443 -m connlimit --connlimit-above 20 -j DROP
 
# Limit to 20 connections on port 80/443 per 2 seconds per IP
-A ufw-before-input -p tcp --dport 80 -i wan -m state --state NEW -m recent --set
-A ufw-before-input -p tcp --dport 80 -i wan -m state --state NEW -m recent --update --seconds 2 --hitcount 20 -j DROP
-A ufw-before-input -p tcp --dport 443 -i wan -m state --state NEW -m recent --set
-A ufw-before-input -p tcp --dport 443 -i wan -m state --state NEW -m recent --update --seconds 2 --hitcount 20 -j DROP
# End Custom UFW by clusterednetworks

Ochrana proti ping flood

# Prevent ping flood
# https://bookofzeus.com/harden-ubuntu/hardening/protect-ddos-attacks/
-A ufw-before-input -p icmp -m limit --limit 6/s --limit-burst 1 -j ACCEPT
-A ufw-before-input -p icmp -j DROP

Omezení skenování portů

# block port scan
-A ufw-before-input -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j port-scan
-A port-scan -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j LOG --log-prefix "[PORT SCAN] "
-A port-scan -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN
-A port-scan -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "XMAS scan: "
-A port-scan -p tcp --tcp-flags ALL FIN,PSH,URG -j LOG --log-prefix "XMAS B: "
-A port-scan -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "XMAS C: "
-A port-scan -j DROP

Spuštění firewallu

Nakonec zapnout firewall a pokud je všechno ok, tak snížit úroveň logování:

ufw enable
ufw logging medium

IP blacklist pomocí ipset

Nejprve jsem vytvořil si v libovolné složce vytvořím tuto strukturu:

-rwxrwx--- 1 root root   1771 21. kvě 11.52 ip-blacklist
-rw-r--r-- 1 root root 520806 18. lis 23.04 ip-blacklist.conf
-rw-r--r-- 1 root root     16 18. lis 23.04 ip-blacklist-custom.conf
-rw-r-xr-x 1 root root    289 20. kvě  2022 ipset-blacklist
drwxr-xr-x 2 root root   4096 28. led  2019 lists

Obsah souboru ip-blacklist. Je vidět, že některé věci mám pro nefunkčnost zakomentované. Soubor má nastavena práva na spouštění. Skript stáhne z internetu z různých blocklistů problematické IP adresy a zkoncentruje je do jednoho souboru.

#!/bin/bash
 
# you can ban country
# "http://ipverse.net/ipblocks/data/countries/xx.zone" # Ban an entire country, see http://ipverse.net/ipblocks/data/countries/
 
IP_TMP=/tmp/ip.tmp
IP_BLACKLIST=/root/scripts/ip-blacklist/ip-blacklist.conf
IP_BLACKLIST_TMP=/tmp/ip-blacklist.tmp
IP_BLACKLIST_CUSTOM=/root/scripts/ip-blacklist/ip-blacklist-custom.conf # optional
LISTS_FOLDER=/root/scripts/ip-blacklist/lists
 
#list="chinese nigerian russian lacnic exploited-servers" 
list="chinese nigerian lacnic" 
 
BLACKLISTS=(
"http://www.projecthoneypot.org/list_of_ips.php?t=d&rss=1" # Project Honey Pot Directory of Dictionary Attacker IPs
"http://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1" # TOR Exit Nodes
"http://www.maxmind.com/en/anonymous_proxies" # MaxMind GeoIP Anonymous Proxies
"http://danger.rulez.sk/projects/bruteforceblocker/blist.php" # BruteForceBlocker IP List
"http://www.spamhaus.org/drop/drop.lasso" # Spamhaus Don't Route Or Peer List (DROP)
"http://cinsscore.com/list/ci-badguys.txt" # C.I. Army Malicious IP List
"http://lists.blocklist.de/lists/all.txt" # blocklist.de attackers
)
 
 
#cd $LISTS_FOLDER && rm $LISTS_FOLDER/*
 
 
for i in "${BLACKLISTS[@]}"
do
 curl -s "$i" > $IP_TMP
 grep -Po '(?:\d{1,3}\.){3}\d{1,3}(?:/\d{1,2})?' $IP_TMP >> $IP_BLACKLIST_TMP
done
 
#for i in `echo $list`; do
 # Download
# wget --quiet http://www.wizcrafts.net/$i-iptables-blocklist.html
 # Grep out all but ip blocks
# cat $i-iptables-blocklist.html | grep -v \< | grep -v \: | grep -v \; | grep -v \# | grep -v \" | grep [0-9] > $i.txt
 # Consolidate blocks into master list
# cat $i.txt >> $IP_BLACKLIST_TMP
#done
 
cat $IP_BLACKLIST_CUSTOM >> $IP_BLACKLIST_TMP
 
sort $IP_BLACKLIST_TMP -n | uniq > $IP_BLACKLIST
rm $IP_BLACKLIST_TMP
wc -l $IP_BLACKLIST

Zároveň jsem vytvořil soubor ip-blacklist_custom.conf do kterého uvádím IP adresy, které chci trvale blokovat. Ještě je potřeba vytvořit skript ipset_blacklist:

#!/bin/bash
 
IP_BLACKLIST=/root/scripts/ip-blacklist/ip-blacklist.conf
 
IPSET=/usr/sbin/ipset
 
$IPSET list blacklist
 
if [ $? -ne 0 ]
        then $IPSET create blacklist hash:net
fi
 
$IPSET flush blacklist
egrep -v "^#|^$" $IP_BLACKLIST | while IFS= read -r ip
do
  $IPSET add blacklist $ip
done

Poslední co zbývá je zajistit, aby se oba skripty spouštěli alespoň 1x týdně. K tomu vytvořím skript /etc/cron.weekly/blacklistip-update. Zároveň musí být skript spustitelný - spuštěním je dobré ho také otestovat. Zároveň stahování blacklistu z internetu chci spouštět jako neprivilegovaný uživatel. Zbytek musí spouštět root.

#!/bin/bash
 
SCRIPT_FOLDER=/etc/scripts/ip-blacklist
 
cd $SCRIPT_FOLDER
 
su - neprivilegovany_user -c "$SCRIPT_FOLDER/ip-blacklist" 2>&1 >/dev/null && ./ipset-blacklist  2>&1 >/dev/null