· 7 years ago · Oct 29, 2018, 08:40 PM
1#Author: Rieper2
2#Source: https://forum.dd-wrt.com/phpBB2/viewtopic.php?p=1037913#1037913
3
4#!/bin/sh
5
6echo "`date` Running routing/block script..."
7
8# name: setup_firewall_and_routes
9# version: 1.0, 02-Jul-2016, by rieper2
10# purpose: block access LAN->WAN for IPs in OpenVPN client policy based routing and allow selective routing for specific domains
11# script type: firewall and routing
12# highly based in this script by ebigrad: http://www.dd-wrt.com/phpBB2/viewtopic.php?t=288852
13# instructions:
14# 1. set VPN_ENABLED_ONLY to your preference
15# 2. set FW_STATE to your preference
16# 3. install this script on an USB stick in the router to support persistent storage
17# 4. activate this script in the crontab to catch DNS changes
18# 5. reboot router
19
20VPN_ENABLED_ONLY="1" # (0 = apply rules 24/7, 1 = apply rules only if VPN enabled)
21
22# state checking: "state NEW" vs. no state
23# state NEW (default):
24# * any pre-existing LAN->WAN connections persist until/unless they timeout/close
25# * remote access (WAN->LAN) is allowed (provided port forwarding is enabled)
26# * more efficient (only LAN->WAN packets used to establish NEW connections are inspected)
27# no state:
28# * any pre-existing LAN->WAN connections are stopped/blocked
29# * remote access (WAN->LAN) is denied (even if port forwarding is enabled)
30# * less efficient (every LAN->WAN packet is inspected)
31
32FW_STATE="-m state --state NEW"
33#FW_STATE="" # uncomment/comment to disable/enable state checking
34
35# if OpenVPN client disabled, nothing to do
36[ "$(nvram get openvpncl_enable)" == "0" ] && exit
37
38# if OpenVPN client not using policy based routing, nothing to do
39[ -z "$(nvram get openvpncl_route)" ] && exit
40
41# wait for VPN's routing table to be established
42while [ -z "$(ip route show table 10)" ]; do sleep 10; done
43
44WAN_GW="$(nvram get wan_gateway)"
45
46# quit if vpn disabled (unless firewall rules still need to be enforced)
47[[ "$(nvram get openvpncl_enable)" == "0" && "$VPN_ENABLED_ONLY" != "0" ]] && exit
48
49WAN_IF="$(ip route | awk '/^default/{print $NF}')"
50FW_CHAIN="blocked-ips"
51
52# cleanup firewall from possible prior execution
53#(
54#iptables -D FORWARD -o $WAN_IF $FW_STATE -j $FW_CHAIN
55#iptables -F $FW_CHAIN
56#iptables -X $FW_CHAIN
57#) > /dev/null 2>&1
58
59# create firewall chain for blocked IPs
60iptables -N $FW_CHAIN
61
62# read local IP addresses from OpenVPN client policy based routing
63echo -e "$(nvram get openvpncl_route)" | \
64 while read ip; do
65 ip=${ip//$'\r'} # remove carriage returns
66
67 [ -z "$ip" ] && continue # skip blank lines
68
69 #Allow access through WAN if destination is certain IPs... e.g. primary router.
70 iptables -D $FW_CHAIN -p tcp -s $ip -d 192.168.249.1 -j ACCEPT
71 iptables -A $FW_CHAIN -p tcp -s $ip -d 192.168.249.1 -j ACCEPT
72 9ip route add 192.168.249.1 via 192.168.249.1 table 10
73
74 # dd-wrt selective domain routing
75 # list domains for selective routing
76 for domain in "de.vpn.airdns.org" \
77 "ipleak.net" \
78 "whatsmyip.org";
79 do
80 # extract ip addresses for domains to route directly (not through vpn)
81 for ip2 in $(nslookup $domain | awk '/^Name:/,0{if (/^Addr/)print $3}'); do
82
83 #add route to ensure routing directly and not through VPN for this domains IP
84 #echo "Adding: ip route add $ip2 via $WAN_GW table 10"
85 ip route add $ip2 via $WAN_GW table 10
86
87 #Add firewall rule to allow access to this domains IP. Delete first if it already exists to avoid duplicates.
88 iptables -D $FW_CHAIN -p tcp -s $ip -d $ip2 -j ACCEPT
89 #echo "Adding: iptables -D $FW_CHAIN -p tcp -s $ip -d $ip2 -j ACCEPT"
90 iptables -A $FW_CHAIN -p tcp -s $ip -d $ip2 -j ACCEPT
91 done
92 done
93
94 # Block access LAN->WAN for this IP address
95 # Remove block rules from the chain (which was inserted in the last run) to avoid duplicates
96 iptables -D $FW_CHAIN -p tcp -s $ip -j REJECT --reject-with tcp-reset
97 iptables -A $FW_CHAIN -p tcp -s $ip -j REJECT --reject-with tcp-reset
98 iptables -D $FW_CHAIN -s $ip -j REJECT --reject-with icmp-host-prohibited
99 iptables -A $FW_CHAIN -s $ip -j REJECT --reject-with icmp-host-prohibited
100 done
101
102# begin blocking: force LAN->WAN traffic thru firewall chain for inspection
103iptables -I FORWARD -o $WAN_IF $FW_STATE -j $FW_CHAIN
104
105echo "`date` Done processing"