Compare commits

...

14 Commits

6 changed files with 164 additions and 2 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
nftables.conf

25
Makefile Normal file
View File

@ -0,0 +1,25 @@
SRC = ./
NFT = nftables.conf.nft
all:
$(info run make makeconf to unify .nft files into nftables.conf)
$(info run make install to install nftables.conf in /etc and set as current ruleset)
$(info run make uninstall to replace /etc/nftables.conf with backup and set as current ruleset)
makeconf:
$(info running makeconf.sh)
$(SRC)makeconf.sh
install: makeconf
$(info backing up current nftables rules)
cp /etc/nftables.conf $(SRC)backup.conf || nft list ruleset > $(SRC)backup.conf
$(info installing new nftables rules)
cp $(SRC)$(NFT) /etc/nftables.conf
$(info reloading nftables rules)
nft -f /etc/nftables.conf
uninstall:
$(info replacing nftables.conf with backup)
cp $(SRC)backup.conf /etc/nftables.conf
$(info reloading nftables rules)
nft -f /etc/nftables.conf

27
defines.nft Normal file
View File

@ -0,0 +1,27 @@
# Networks
define VPN_SUBNET = 10.8.0.0/24
# TCP only services
define SSH_PORT1 = 22
define SSH_PORT2 = 8022
define HTTP_PORT = 80
define HTTPS_PORT = 443
define SYNCPLAY_PORT = 60000
define TERRARIA_PORT = 7777
define MAINPAGE_PORT = 3000
define NEXTCLOUD_PORT = 3001
define GITEA_PORT = 3002
define POSTGRESQL_PORT = 5432
# TCP and UDP services (needs to go in both sets)
define DNS_PORT = 53
define OPENTTD_PORT = 3979
# UDP only services
define DHCP_IN_PORT = 67
define DHCP_OUT_PORT = 68
define OPENVPN_PORT = 1194
define FACTORIO_PORT = 34197
define CSTRIKE_PORT = 27015
define SNMP_POLL_PORT = 161
define SNMP_TRAP_PORT = 162

View File

@ -1,17 +1,64 @@
#!/usr/bin/nft #!/usr/bin/nft
flush ruleset flush ruleset
include "./defines.nft"
include "/var/geoipsets/dbip/nftset/ipv4/*.ipv4"
table ip filter { table ip filter {
set allowed_tcp_ports {
type inet_service;
flags constant;
elements = {
$SSH_PORT1, $SSH_PORT2, $DNS_PORT, $HTTP_PORT, $HTTPS_PORT, $SYNCPLAY_PORT,
$TERRARIA_PORT, $OPENTTD_PORT, $MAINPAGE_PORT, $NEXTCLOUD_PORT, $GITEA_PORT,
$POSTGRESQL_PORT
};
}
set allowed_udp_ports_in {
type inet_service;
flags constant;
elements = { $DNS_PORT, $DHCP_IN_PORT, $OPENVPN_PORT, $FACTORIO_PORT, $OPENTTD_PORT, $CSTRIKE_PORT, $SNMP_POLL_PORT, $SNMP_TRAP_PORT }
}
set allowed_udp_ports_out {
type inet_service;
flags constant;
elements = { $DNS_PORT, $DHCP_OUT_PORT, $SNMP_POLL_PORT }
}
set ipv4_geo_blacklist {
type ipv4_addr;
flags interval;
elements = { };
}
chain in { chain in {
type filter hook input priority filter; policy drop; type filter hook input priority filter; policy drop;
ct state invalid drop; ip saddr @ipv4_geo_blacklist drop;
ct state {related,established} accept; ct state vmap { invalid : drop, related : accept, established : accept };
iifname "lo" accept;
icmp type echo-request accept;
tcp dport @allowed_tcp_ports accept;
udp dport @allowed_udp_ports_in accept;
} }
chain forward { chain forward {
type filter hook forward priority filter; policy drop; type filter hook forward priority filter; policy drop;
comment "this routes vpn traffic";
ct state related,established accept;
iifname "tun0" oifname "eth0" accept;
} }
chain out { chain out {
type filter hook output priority filter; policy drop; type filter hook output priority filter; policy drop;
ip daddr @ipv4_geo_blacklist drop;
ct state vmap { invalid : drop, related : accept, established : accept, new : accept };
udp dport @allowed_udp_ports_out accept;
oifname "lo" accept;
icmp type echo-reply accept;
} }
} }
include "./nat.nft"

50
makeconf.sh Executable file
View File

@ -0,0 +1,50 @@
#!/bin/bash
# ${1} is original filename
# ${2} is counter (start at 0)
# ${3} is file to replace from
replace(){
# change newlines to Ñ so we can use it as replacement pattern
local pattern=$(sed ':a;N;$!ba;s/\n/Ñ/g;s/\(\/\|\.\)/\\\1/g' "${3}")
if [ ${2} != "0" ]
# Ñ is changed back to newlines before saving file
then
local new_content="$(sed "1,/^include \"\.\/[a-z]\+\.nft\"$/{s/^include \"\.\/[a-z]\+\.nft\"$/${pattern}/}" "${1}""$(bc -l <<< "${2} - 1")".nft | sed 's/Ñ/\n/g')";
echo "${new_content}" > "${1}${2}".nft
else
local new_content="$(sed "1,/^include \"\.\/[a-z]\+\.nft\"$/{s/^include \"\.\/[a-z]\+\.nft\"$/${pattern}/}" "${1}".nft | sed 's/Ñ/\n/g')";
echo "${new_content}" > "${1}${2}".nft
fi
}
filename=filter
declare -i counter=0
# only replace local files
declare -a local_includes=( $(grep "include \"\./[a-z.]\+\"" filter.nft | awk '{print $2}' | tr -d \"))
for i in ${local_includes[@]}
do replace "${filename}" "${counter}" "${i}"
counter+=1
done
#rename last temp file to nftables.conf
counter=${counter}-1
mv "${filename}""${counter}".nft nftables.conf
counter=${counter}-1
while [ ${counter} -ge 0 ]
#delete the rest of the temp files to nftables.conf
do rm "${filename}""${counter}".nft
counter=${counter}-1
done
# figure out what countries, if any, we're blocking
declare -a countries=($(ls -1 /var/geoipsets/dbip/nftset/ipv4/))
# figure out which line defines the elements of the blacklist set
line="$(grep -nA3 blacklist nftables.conf | grep elements | awk 'BEGIN{FS="-"} {print $1}')"
# insert names of the countries to block into the line that defines the elements of the set
for i in ${countries[@]};
do sed -i "${line} s/elements = { \([A-Z]\{2\}\.ipv4,\? \)*/elements = { \1\$${i}, /" nftables.conf
done
# delete unnecesary last comma
sed -i "${line} s/, }/ }/" nftables.conf

12
nat.nft Normal file
View File

@ -0,0 +1,12 @@
table nat {
chain prerouting {
type nat hook prerouting priority 0;
comment "this is necessary even if empty";
}
chain postrouting {
type nat hook postrouting priority 100;
comment "enable NAT for VPN";
iifname "tun0" oifname "eth0" ip saddr $VPN_SUBNET masquerade;
}
}