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
 | |
| 
 | 
