-
-
Save dreamcat4/2ff8c6a3747d11a42d7819d1295aa698 to your computer and use it in GitHub Desktop.
VPN.SH script to tunnel specific VLAN through a WireGuard tunnel on an UDM Pro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
INTERFACE="vpn0" | |
MARK=100 | |
TABLE="vpn" | |
SCRIPT_NAME="/etc/wireguard/scripts/vpn.sh" | |
# set this to the interface(s) on which you want WAN traffic to | |
# be routed through vpn. separate interfaces with spaces. | |
# e.g. "br0" or "br0 br1" etc. | |
INTERFACES="br100 wg0" # Proxied wifi and WireGuard tunnel from phone to use pihole etc. | |
# set this to the ASN networks which you want to exlude traffic from | |
# being routed through vpn. separate networks with spaces. | |
EXCLUDED_ASN="AS2906" # AS2906 = Netflix | |
EXCLUDED_DOMAINS="www.netflix.com netflix.com nflxext.com nflximg.net nflxso.net nflxvideo.net ichnaea-web.netflix.com" | |
################################# DO NOT EDIT ################################# | |
MANGLE_CHAIN=$(echo ${TABLE} | tr a-z A-Z) | |
### ASN LIST ### | |
function setup_asn_lists() { | |
for asn in ${EXCLUDED_ASN}; do | |
ipset create ${asn} hash:net -exist | |
PREFIXES=`curl -s https://api.bgpview.io/asn/${asn}/prefixes | jq -r '.data.ipv4_prefixes[].prefix'` | |
for prefix in ${PREFIXES}; do | |
ipset add ${asn} ${prefix} -exist | |
done | |
done | |
} | |
function remove_asn_lists() { | |
for asn in ${EXCLUDED_ASN}; do | |
ipset destroy ${asn} | |
done; | |
} | |
### DMOAIN LIST ### | |
function setup_domain_list() { | |
ipset create VPN_EXCLUDED hash:ip -exist | |
ipset flush VPN_EXCLUDED | |
for domain in ${EXCLUDED_DOMAINS}; do | |
IPS=`nslookup -type=a ${domain} | grep "Address" | awk '{print $2}' | sed '1d'` | |
for ip in ${IPS}; do | |
ipset add VPN_EXCLUDED ${ip} -exist | |
done | |
done | |
} | |
function remove_domain_list() { | |
ipset destroy VPN_EXCLUDED | |
} | |
### IP4TABLES MANGLE ### | |
function add_ip4tables_mangle() { | |
iptables -w -t mangle -C ${1} || iptables -w -t mangle -A ${1} | |
} | |
function remove_ip4tables_mangle() { | |
iptables -w -t mangle -D ${1} | |
} | |
### IP RULE ### | |
function add_ip_rule() { | |
# Apply policy on mangle mark | |
if [[ $(ip rule show fwmark ${MARK} | wc -l) -eq 0 ]]; then | |
ip rule add fwmark ${MARK} table ${TABLE} | |
fi | |
} | |
function remove_ip_rule() { | |
# Remove policy on mangle mark | |
if [[ $(ip rule show fwmark ${MARK} | wc -l) -gt 0 ]]; then | |
ip rule delete fwmark ${MARK} table ${TABLE} | |
fi | |
} | |
### IP ROUTE ### | |
function add_ip_route() { | |
# Create routing table | |
if [[ $(cat /etc/iproute2/rt_tables | grep "${MARK} ${TABLE}" | wc -l) -eq 0 ]]; then | |
echo "${MARK} ${TABLE}" >> /etc/iproute2/rt_tables | |
fi | |
# Add default route to table | |
if [[ $(ip route show table ${TABLE} | wc -l) -eq 0 ]]; then | |
ip route add default dev ${INTERFACE} table ${TABLE} | |
fi | |
} | |
function remove_ip_route() { | |
# Remove default route to table | |
if [[ $(ip route show table ${TABLE} | wc -l) -gt 0 ]]; then | |
ip route delete default dev ${INTERFACE} table ${TABLE} | |
fi | |
} | |
### RULE WATCHER ### | |
# Kill the rule watcher (previously running up/down script for the tunnel device). | |
kill_rule_watcher() { | |
for p in $(pgrep -f "/bin/sh.*$(basename "$0") monitor"); do | |
if [ $p != $$ ]; then | |
kill -9 $p | |
fi | |
done | |
# ip rule del $ip_rule &> /dev/null || true | |
# ip -6 rule del $ip_rule &> /dev/null || true | |
} | |
# Run the rule watcher which will be used to re-add the policy-based ip rules | |
# if removed. Rule watcher keeps this script running in the background. | |
run_rule_watcher() { | |
kill_rule_watcher | |
(while :; do | |
add_ip_rule | |
sleep 5 | |
done) & | |
} | |
### IP TABLES ### | |
function setup_iptables() { | |
# Add chain | |
iptables -t mangle -F ${MANGLE_CHAIN} || iptables -t mangle -N ${MANGLE_CHAIN} | |
# Exclude private networks | |
add_ip4tables_mangle "${MANGLE_CHAIN} -d 192.168.0.0/16 -j RETURN" | |
add_ip4tables_mangle "${MANGLE_CHAIN} -d 172.16.0.0/12 -j RETURN" | |
add_ip4tables_mangle "${MANGLE_CHAIN} -d 10.0.0.0/8 -j RETURN" | |
# Exclude defined ASN | |
for asn in ${EXCLUDED_ASN}; do | |
add_ip4tables_mangle "${MANGLE_CHAIN} -m set --match-set ${asn} dst -j RETURN" | |
done | |
# Exclude domains | |
add_ip4tables_mangle "${MANGLE_CHAIN} -m set --match-set VPN_EXCLUDED dst -j RETURN" | |
# Mark unmatched traffic | |
add_ip4tables_mangle "${MANGLE_CHAIN} -j MARK --set-mark ${MARK}" | |
# Apply PREROUTING | |
for intfc in ${INTERFACES}; do | |
add_ip4tables_mangle "PREROUTING -i ${intfc} -j ${MANGLE_CHAIN}" | |
done | |
# Add Masquerade | |
iptables -w -t nat -A POSTROUTING -o ${INTERFACE} -j MASQUERADE | |
# Add firewall rules - Block VPN from coming in | |
iptables -w -I FORWARD -i ${INTERFACE} -j DROP | |
iptables -w -I FORWARD -i ${INTERFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT | |
iptables -w -I FORWARD -o ${INTERFACE} -j ACCEPT | |
} | |
function remove_iptables() { | |
# Remove PREROUTING | |
for intfc in ${INTERFACES}; do | |
remove_ip4tables_mangle "PREROUTING -i ${intfc} -j ${MANGLE_CHAIN}" | |
done | |
# Remove chain | |
iptables -w -t mangle -F ${MANGLE_CHAIN} | |
iptables -w -t mangle -X ${MANGLE_CHAIN} | |
# Remove Masquerade | |
iptables -w -t nat -D POSTROUTING -o ${INTERFACE} -j MASQUERADE | |
# Remove firewall rules - Block VPN from coming in | |
iptables -w -D FORWARD -i ${INTERFACE} -j DROP | |
iptables -w -D FORWARD -i ${INTERFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT | |
iptables -w -D FORWARD -o ${INTERFACE} -j ACCEPT | |
} | |
if [[ $# -lt 1 ]]; then | |
echo "Uncorrect usage, use {up|down|monitor}" | |
exit 1 | |
fi | |
case $1 in | |
monitor) | |
run_rule_watcher | |
;; | |
up) | |
# Apply rules and routes | |
setup_asn_lists | |
setup_domain_list | |
setup_iptables | |
add_ip_rule | |
add_ip_route | |
${SCRIPT_NAME} monitor | |
;; | |
down) | |
# Remove rules and routes | |
kill_rule_watcher | |
remove_ip_route | |
remove_ip_rule | |
remove_iptables | |
remove_domain_list | |
remove_asn_lists | |
;; | |
*) | |
echo "Uncorrect usage, use {up|down|monitor}" | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment