263 lines
10 KiB
Makefile
263 lines
10 KiB
Makefile
# ██████ ██ ▄█▀▒███████▒ █ █░ ▄████
|
|
#▒██ ▒ ██▄█▒ ▒ ▒ ▒ ▄▀░ ▓█░ █ ░█░ ██▒ ▀█▒
|
|
#░ ▓██▄ ▓███▄░ ░ ▒ ▄▀▒░ ░█▒░ █ ▒█░ █░█ ▒ ██░▄▄▄░
|
|
# ▒ ██▒▓██ █▄ ▄▀▒ ░ ░█░ █ ░█ ░▓█ ██▓
|
|
#▒██████▒▒▒██▒ █▄▒███████▒ ░░██▒██▓ ░▒▓███▀▒
|
|
#▒ ▒▓▒ ▒ ░▒ ▒▒ ▓▒░▒▒ ▓░▒░▒ ░ ▓░▒ ▒ ░▒ ▒
|
|
#░ ░▒ ░ https://git.sk4.nz/sk4nz/skz-wg ░ ░
|
|
# ░ ░ ░ ░ ░ ░
|
|
|
|
.PHONY: clean deps info restart
|
|
#.SILENT:
|
|
|
|
# ░▒▓█ CONFIGURATION █▓▒░
|
|
|
|
# Change this list to always create clients
|
|
# CLIENTS= client1 client2
|
|
CLIENTS?=
|
|
.poison empty (CLIENTS)
|
|
|
|
# Install packages, always keep this line before the next block (for curl)
|
|
INSTALLPKG!= [ -f .installed ] || (pkg_add -I wireguard-tools libqrencode curl && touch .installed)
|
|
|
|
# Network configuration
|
|
SERVER?!= curl -s ifconfig.co
|
|
WG_PORT= 5353
|
|
WG_LAN= 10.10.10.1/24
|
|
WAN!= route -n show -inet | grep default | awk '{print $$NF}'
|
|
|
|
# Packet Filter configuration for allowed ports
|
|
OUT_TCP= http ftp whois https ssh
|
|
IN_TCP= http https ssh
|
|
OUT_UDP= domain ntp $(WG_PORT)
|
|
IN_UDP= $(WG_PORT)
|
|
VPN_TCP= $(IN_TCP)
|
|
|
|
# Server private key
|
|
WG_KEY!= cat server.key 2> /dev/null || wg genkey
|
|
.poison empty $(WG_KEY)
|
|
|
|
# Ads lists
|
|
ADS_URLS= https://winhelp2002.mvps.org/hosts.txt
|
|
ADS_URLS+= https://pgl.yoyo.org/as/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext
|
|
ADS_URLS+= https://adaway.org/hosts.txt
|
|
ADS_URLS+= https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
|
|
|
# ░▒▓█ TARGETS █▓▒░
|
|
|
|
all: /etc/pf.wg /var/unbound/etc/unbound.conf
|
|
# Enable IPv4 forwarding permanently, if not already
|
|
grep forwarding /etc/sysctl.conf 2> /dev/null || (printf 'net.inet.ip.forwarding=1\n' >> /etc/sysctl.conf && sysctl net.inet.ip.forwarding=1)
|
|
# Write new pf.conf
|
|
grep 'pf.header' /etc/pf.conf || printf 'include "/etc/pf.header"\n' > /etc/pf.conf
|
|
grep 'pf.wg' /etc/pf.conf || printf 'include "/etc/pf.wg"\n' >> /etc/pf.conf
|
|
# Validate and start new pf.conf
|
|
pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
|
|
# Restart the WireGuard interface
|
|
$(MAKE) restart
|
|
$(MAKE) info
|
|
|
|
restart:
|
|
sh /etc/netstart wg0
|
|
|
|
/etc/pf.bogons:
|
|
# Reserved IP addresses to drop, see https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
|
printf '0.0.0.0\
|
|
\n10.0.0.0/8\
|
|
\n100.64.0.0/10\
|
|
\n127.0.0.0/8\
|
|
\n128.0.0.0/16\
|
|
\n169.254.0.0/16\
|
|
\n172.16.0.0/12\
|
|
\n191.255.0.0/16\
|
|
\n192.0.0.0/24\
|
|
\n192.0.2.0/24\
|
|
\n192.88.99.0/24\
|
|
\n192.168.0.0/16\
|
|
\n198.18.0.0/15\
|
|
\n198.51.100.0/24\
|
|
\n203.0.113.0/24\
|
|
\n223.255.255.0/24\
|
|
\n224.0.0.0/4\
|
|
\n240.0.0.0/4\
|
|
\n255.255.255.255\n' > $@
|
|
|
|
/etc/pf.abuse_ssh /etc/pf.abuse_tcp:
|
|
# Anti-DDoS persistent tables
|
|
touch $@
|
|
|
|
/etc/pf.header:
|
|
# The original pf header
|
|
printf 'set skip on lo\nblock return\npass\
|
|
\nblock return in on ! lo0 proto tcp to port 6000:6010\
|
|
\nblock return out log proto {tcp udp} user _pbuild\n' > $@
|
|
|
|
/etc/pf.wg: /etc/pf.bogons /etc/pf.abuse_ssh /etc/pf.abuse_tcp /etc/pf.header /etc/pf.conf.orig
|
|
# Define allowed PF ports
|
|
printf 'out_tcp_ports = "{ $(OUT_TCP) }"\
|
|
\nout_udp_ports = "{ $(OUT_UDP) }"\
|
|
\nvpn_tcp_ports = "{ $(VPN_TCP) }"\
|
|
\nin_tcp_ports = "{ $(IN_TCP) }"\
|
|
\nin_udp_ports = "{ $(IN_UDP) }"\n' > $@
|
|
# Rules
|
|
printf '# BEGIN PF.WG\
|
|
\n### Macros \
|
|
\n# statefull tracking options - sto\
|
|
\n# SSH is considered under abuse when there are more than 6 connections per minute \
|
|
\nssh_sto = "(max-src-conn-rate 6/60, overload <t_abuse_ssh> flush global)"\
|
|
\n# TCP is considered under abuse when there are more than 300 simultaneous connections or 600 per minute\
|
|
\ntcp_sto = "(max-src-conn 300, max-src-conn-rate 600/60, overload <t_abuse_tcp> flush global)"\
|
|
\n# TCP flags \
|
|
\nflag_syn = "flags S/SA modulate state"\
|
|
\n# define e (egress) and i (ingress) macros\
|
|
\nedropin = "block drop in quick on egress from"\
|
|
\nedropout = "block drop out log quick on egress from"\
|
|
\nepassout = "pass out log on egress proto tcp to any port"\
|
|
\ninblocktcp = "block in log quick proto tcp from"\
|
|
\ninpasstcp = "pass in on egress proto tcp to any port"\
|
|
\ninvpntcp = "pass in log on wg0 proto tcp to any port"\
|
|
\n# Persitent tables\
|
|
\ntable <t_bogons> persist file "/etc/pf.bogons"\
|
|
\ntable <t_abuse_tcp> persist file "/etc/pf.abuse_tcp"\
|
|
\ntable <t_abuse_ssh> persist file "/etc/pf.abuse_ssh"\
|
|
\n# Various security-related options\
|
|
\nset block-policy return\
|
|
\nset optimization conservative\
|
|
\nset reassemble yes\
|
|
\nset syncookies adaptive (start 25%%, end 12%%)\
|
|
\nset ruleset-optimization profile\
|
|
\nset skip on lo\
|
|
\nantispoof for { lo, egress }\
|
|
\nmatch in all scrub (max-mss 1440 no-df random-id reassemble tcp)\
|
|
\n### Rules \
|
|
\n# Prevent dns leaks \
|
|
\nblock in log on egress inet proto { tcp udp } from any to ! egress port 53\
|
|
\n# Block bogons - DEACTIVATED \
|
|
\n# TODO : change pf.bogons to allow LAN\
|
|
\n#$edropin { <t_bogons> } to any\
|
|
\n#$edropout any to { <t_bogons> }\
|
|
\n# block abusers\
|
|
\n$inblocktcp <t_abuse_ssh> to any port ssh\
|
|
\n$inblocktcp <t_abuse_tcp> to any port $in_tcp_ports\
|
|
\n# Default rule : block stateless traffic\
|
|
\nblock\
|
|
\n# Enable ICMP echo request, reply, unreach\
|
|
\npass quick inet proto icmp all icmp-type { echoreq, echorep, unreach }\
|
|
\n# Enable IPv4 traceroute\
|
|
\npass out on egress proto udp to port 33433:33626\
|
|
\n# Pass ingress \
|
|
\n$inpasstcp ssh $$flag_syn $$ssh_sto\
|
|
\n$inpasstcp http $$flag_syn $$tcp_sto\
|
|
\n$inpasstcp https $$flag_syn $$tcp_sto\
|
|
\n$invpntcp $$vpn_tcp_ports $$flag_syn $$tcp_sto\
|
|
\npass in on egress proto udp to any port $$in_udp_ports\
|
|
\n# Pass egress\
|
|
\n$epassout $$out_tcp_ports $$flag_syn\
|
|
\npass out on egress proto udp to any port $$out_udp_ports allow-opts\
|
|
\n# Pass Wireguard-LAN\
|
|
\npass out log on wg0 proto tcp to any port $$vpn_tcp_ports\
|
|
\npass in on wg0 proto udp to any port $$out_udp_ports allow-opts\
|
|
\n# END PF.WG\n' >> $@
|
|
# NAT the WireGuard interface to WAN
|
|
printf 'pass out on $(WAN) inet from wg0:network to any nat-to ($(WAN))' >> $@
|
|
|
|
ad-blacklist:
|
|
rm -rf /var/unbound/ad-blacklist.conf
|
|
$(MAKE) /var/unbound/ad-blacklist.conf
|
|
|
|
/var/unbound/ad-blacklist.conf:
|
|
# For the lying DNS resolver
|
|
for url in "$(ADS_URLS)"; do curl -s $$url >> /tmp/ads-daily; done
|
|
awk -v white='/(api.solvemedia.com)/' '$$1 ~ /^127\.|^0\./ && $$2 !~white {gsub("\r",""); print tolower($$2)}' /tmp/ads-daily | sort | uniq | awk '{printf "server:\n", $$1; printf "local-data: \"%s A 127.0.0.1\"\n", $$1}' > $@
|
|
rm -rf /tmp/ads-daily
|
|
# Update lists daily
|
|
grep 'ad-blacklist' /etc/daily.local || printf 'make -C $(PWD) ad-blacklist\nrcctl restart unbound\n' >> /etc/daily.local
|
|
|
|
/etc/pf.conf.orig:
|
|
# Save original pf.conf
|
|
cp /etc/pf.conf $@
|
|
|
|
/etc/hostname.wg0: server.key $(CLIENTS)
|
|
# The WireGuard interface configuration
|
|
printf 'wgkey "$(WG_KEY)"\
|
|
\nwgport $(WG_PORT)\
|
|
\ninet $(WG_LAN)\n' > $@
|
|
# Add peers
|
|
for cli in $(CLIENTS); do \
|
|
N=$$(sha256 -qs $$cli | cut -b 1-2);\
|
|
PUB=$$(cat $$cli/$$cli.pub);\
|
|
PSK=$$(cat $$cli/$$cli.psk);\
|
|
printf "# $$cli\nwgpeer \"$$PUB\" wgpsk \"$$PSK\" wgpka 25 wgaip $(WG_LAN:H:S/.1$/./)"$$(printf $$((0x$$N)))"/32\n" >> $@;\
|
|
done
|
|
printf 'up\n' >> $@
|
|
chmod 640 $@
|
|
# Start the wg interface
|
|
sh /etc/netstart wg0
|
|
|
|
/var/unbound/etc/unbound.conf: /etc/hostname.wg0 ad-blacklist
|
|
# Unbound configuration, with lying DNS and DNSSEC validation
|
|
printf 'server:\
|
|
\n\tinterface: 127.0.0.1\
|
|
\n\tinterface: $(WG_LAN:H)\
|
|
\n\tdo-ip6: no\
|
|
\n\taccess-control: 0.0.0.0/0 refuse\
|
|
\n\taccess-control: 127.0.0.0/8 allow\
|
|
\n\taccess-control: $(WG_LAN) allow\
|
|
\n\tauto-trust-anchor-file: "/var/unbound/db/root.key"\
|
|
\n\taggressive-nsec: yes\
|
|
\n\tinclude: /var/unbound/ad-blacklist.conf\
|
|
\n\nremote-control:\
|
|
\n\tcontrol-enable: yes\
|
|
\n\tcontrol-interface: /var/run/unbound.sock\n' > $@
|
|
rcctl enable unbound
|
|
rcctl start unbound
|
|
|
|
info:
|
|
printf '\033[1mWireguard: \033[32m$(SERVER):$(WG_PORT) \033[0m$(WG_LAN)\n'
|
|
T=$$(wg show all transfer); for cli in $(CLIENTS); do\
|
|
N=$$(sha256 -qs $$cli | cut -b 1-2);\
|
|
PUB=$$(cat $$cli/$$cli.pub);\
|
|
IN=$$(printf "$$T\n" | grep $$PUB | awk '{print $$(NF-1)}');\
|
|
OUT=$$(printf "$$T\n" | grep $$PUB | awk '{print $$(NF)}');\
|
|
printf '- \033[1m\033[33m%15s\033[0m $(WG_LAN:H:S/.1$/./)%-3s in: %-10s out: '$$OUT'\n' $$cli $$(printf $$((0x$$N))) $$IN;\
|
|
done
|
|
|
|
server.conf: server.pub
|
|
# Generate the server configuration header (deprecated)
|
|
printf '[Interface] # VOID - Tunnel gateway: $(WG_LAN:H)\n#Address = $(WG_LAN:H)\nListenPort = $(WG_PORT)\nPrivateKey = '$$(cat server.key)'\n' > server.conf;
|
|
|
|
server.key:
|
|
# Generate server private key if not already present
|
|
printf $(WG_KEY) > $@
|
|
chmod 600 $@
|
|
|
|
server.pub: server.key
|
|
# Generate server pub key if not already present
|
|
cat server.key | wg pubkey > $@
|
|
chmod 600 $@
|
|
|
|
$(CLIENTS): server.conf
|
|
mkdir -p $@
|
|
# Generate priv/pub keys
|
|
wg genkey | tee $@/$@.key | wg pubkey > $@/$@.pub
|
|
# Generate PSK
|
|
touch $@/$@.psk && chmod 600 $@/$@.psk
|
|
wg genpsk > $@/$@.psk
|
|
# Append to server.conf (deprecated) and the client configuration
|
|
PSK=$$(cat $@/$@.psk); PUB=$$(cat $@/$@.pub); N=$$(sha256 -qs $@ | cut -b 1-2);\
|
|
echo -e '[Peer] # '$@'\nAllowedIPs = $(WG_LAN:H:S/.1$/./)'$$(echo $$((0x$$N)))'/32\nPublicKey = '$$PUB'\nPresharedKey = '$$PSK'\n' >> server.conf;\
|
|
echo -e '[Interface] # Local tunnel address: $(WG_LAN:H:S/.1$/./)'$$(echo $$((0x$$N))) router: $(WG_LAN:H)'\nAddress = $(WG_LAN:H:S/.1$/./)'$$(echo $$((0x$$N)))/32'\nPrivateKey = '$$(cat $@/$@.key)'\nDNS = $(WG_LAN:H)\n[Peer] # Tunnel endpoint: $(SERVER)\nEndpoint = $(SERVER):$(WG_PORT)\nPublicKey = '$$(cat server.pub)'\nPresharedKey = '$$PSK'\nAllowedIPs = 0.0.0.0/0' > $@/$@.conf
|
|
cat $@/$@.conf | qrencode -t ansiutf8 -o $@/$@.qr
|
|
chmod -R 600 $@
|
|
|
|
clean:
|
|
-ifconfig wg0 down
|
|
-rcctl stop unbound
|
|
-rcctl disable unbound
|
|
-rm -rf $(CLIENTS) *.key *.pub server.conf /var/unblound/ad-blacklist.sh /etc/pf.wg /etc/hostname.wg0 /var/unbound/etc/unbound.conf /etc/pf.header
|
|
-sed -i '/ad-blacklist/d' /etc/daily.local
|
|
-sed -i '/rcctl restart unbound/d' /etc/daily.local
|
|
-cp /etc/pf.conf.orig /etc/pf.conf
|
|
pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
|
|
|