· 6 years ago · Apr 09, 2019, 11:44 PM
1#!/bin/sh
2####################################################################################################
3# Script: IPSET_Netflix_Domains.sh
4# Version 1.0.1
5# Author: Xentrk
6# Date: 7-September-2018
7#
8# Description:
9# Selective Routing Script for Netflix using Asuswrt-Merlin firmware. This version uses the ipset method
10# built into dnsmasq.
11#
12# Grateful:
13# Thank you to @Martineau on snbforums.com for sharing his Selective Routing expertise
14# and on-going support!
15#
16####################################################################################################
17logger -t "($(basename "$0"))" $$ Starting Script Execution
18
19# Uncomment the line below for debugging
20#set -x
21
22PROGNAME=$(basename "$0")
23LOCKFILE_DIR=/tmp
24LOCK_FD=200
25
26lock() {
27 local prefix=$1
28 local fd=${2:-$LOCK_FD}
29 local lock_file=$LOCKFILE_DIR/$prefix.lock
30
31 # create lock file
32 eval "exec $fd>$lock_file"
33
34 # acquier the lock
35 flock -n "$fd" \
36 && return 0 \
37 || return 1
38}
39
40error_exit() {
41 error_str="$@"
42 logger -t "($(basename "$0"))" $$ "$error_str"
43 exit 1
44}
45
46main() {
47 lock "$PROGNAME" || error_exit "Exiting $PROGNAME. Only one instance of $PROGNAME can run at one time."
48
49### Define interface/bitmask to route traffic to below
50set_fwmark_parms () {
51 FWMARK_WAN="0x8000/0x8000"
52 FWMARK_OVPNC1="0x1000/0x1000"
53 FWMARK_OVPNC2="0x2000/0x2000"
54 FWMARK_OVPNC3="0x4000/0x4000"
55 FWMARK_OVPNC4="0x7000/0x7000"
56 FWMARK_OVPNC5="0x3000/0x3000"
57}
58
59create_fwmarks () {
60# WAN
61 ip rule del fwmark "$FWMARK_WAN" 2>/dev/null
62 ip rule add from 0/0 fwmark "$FWMARK_WAN" table 254 prio 9990
63
64#VPN Client 1
65 ip rule del fwmark "$FWMARK_OVPNC1" 2>/dev/null
66 ip rule add from 0/0 fwmark "$FWMARK_OVPNC1" table 111 prio 9995
67
68#VPN Client 2
69 ip rule del fwmark "$FWMARK_OVPNC2" 2>/dev/null
70 ip rule add from 0/0 fwmark "$FWMARK_OVPNC2" table 112 prio 9994
71
72#VPN Client 3
73 ip rule del fwmark "$FWMARK_OVPNC3" 2>/dev/null
74 ip rule add from 0/0 fwmark "$FWMARK_OVPNC3" table 113 prio 9993
75
76#VPN Client 4
77 ip rule del fwmark "$FWMARK_OVPNC4" 2>/dev/null
78 ip rule add from 0/0 fwmark "$FWMARK_OVPNC4" table 114 prio 9992
79
80#VPN Client 5
81 ip rule del fwmark "$FWMARK_OVPNC5" 2>/dev/null
82 ip rule add from 0/0 fwmark "$FWMARK_OVPNC5" table 115 prio 9991
83
84 ip route flush cache
85}
86
87
88# Chk_Entware function provided by @Martineau at snbforums.com
89
90Chk_Entware () {
91
92 # ARGS [wait attempts] [specific_entware_utility]
93
94 local READY=1 # Assume Entware Utilities are NOT available
95 local ENTWARE="opkg"
96 ENTWARE_UTILITY= # Specific Entware utility to search for
97 local MAX_TRIES=30
98
99 if [ -n "$2" ] && [ -n "$(echo "$2" | grep -E '^[0-9]+$')" ];then
100 local MAX_TRIES=$2
101 fi
102
103 if [ -n "$1" ] && [ -z "$(echo "$1" | grep -E '^[0-9]+$')" ];then
104 ENTWARE_UTILITY=$1
105 else
106 if [ -z "$2" ] && [ -n "$(echo "$1" | grep -E '^[0-9]+$')" ];then
107 MAX_TRIES=$1
108 fi
109 fi
110
111 # Wait up to (default) 30 seconds to see if Entware utilities available.....
112 local TRIES=0
113
114 while [ "$TRIES" -lt "$MAX_TRIES" ];do
115 if [ -n "$(which "$ENTWARE")" ] && [ "$("$ENTWARE" -v | grep -o "version")" == "version" ];then
116 if [ -n "$ENTWARE_UTILITY" ];then # Specific Entware utility installed?
117 if [ -n "$("$ENTWARE" list-installed "$ENTWARE_UTILITY")" ];then
118 READY=0 # Specific Entware utility found
119 else
120 # Not all Entware utilities exists as a stand-alone package e.g. 'find' is in package 'findutils'
121 if [ -d /opt ] && [ -n "$(find /opt/ -name "$ENTWARE_UTILITY")" ];then
122 READY=0 # Specific Entware utility found
123 fi
124 fi
125 else
126 READY=0 # Entware utilities ready
127 fi
128 break
129 fi
130 sleep 1
131 logger -st "($(basename "$0"))" $$ "Entware" $ENTWARE_UTILITY "not available - wait time" $((MAX_TRIES - TRIES-1))" secs left"
132 local TRIES=$((TRIES + 1))
133 done
134
135 return $READY
136}
137
138# check if /jffs/configs/dnsmasq.conf.add contains entry for Netflix domains
139check_dnsmasq () {
140
141DNSMASQ_PARM_OLD="ipset=/akamaitechnologies.com/x3mRouting_NETFLIX_DNSMASQ"
142DNSMASQ_PARM_NEW="ipset=/akamaitechnologies.com/x3mRouting_NETFLIX_DNSMASQ"
143
144 if [ -s /jffs/configs/dnsmasq.conf.add ]; then # dnsmasq.conf.add file exists
145 if [ "$(grep -c "$DNSMASQ_PARM_OLD" "/jffs/configs/dnsmasq.conf.add")" -eq "1" ]; then # see if line exists for x3mRouting_NETFLIX_DNSMASQ
146 sed -i "\\~$DNSMASQ_PARM_OLD~d" "/jffs/configs/dnsmasq.conf.add"
147 fi
148 if [ "$(grep -c "$DNSMASQ_PARM_NEW" "/jffs/configs/dnsmasq.conf.add")" -eq "0" ]; then # see if line exists for x3mRouting_NETFLIX_DNSMASQ
149 echo "$DNSMASQ_PARM_NEW" >> /jffs/configs/dnsmasq.conf.add # add NETFLIX entry to dnsmasq.conf.add
150 service restart_dnsmasq > /dev/null 2>&1
151 fi
152 else
153 echo "$DNSMASQ_PARM_NEW\n" > /jffs/configs/dnsmasq.conf.add # dnsmasq.conf.add does not exist, create dnsmasq.conf.add
154 service restart_dnsmasq > /dev/null 2>&1
155 fi
156}
157
158check_ipset_list () {
159 if [ "$(ipset list -n x3mRouting_NETFLIX_DNSMASQ 2>/dev/null)" != "x3mRouting_NETFLIX_DNSMASQ" ]; then #does NETFLIX ipset list exist?
160 if [ -s /opt/tmp/x3mRouting_NETFLIX_DNSMASQ ]; then # does x3mRouting_NETFLIX_DNSMASQ ipset restore file exist?
161 ipset restore -! < /opt/tmp/x3mRouting_NETFLIX_DNSMASQ # Restore ipset list if restore file exists at /opt/tmp/x3mRouting_NETFLIX_DNSMASQ
162 else
163 ipset create x3mRouting_NETFLIX_DNSMASQ hash:net family inet hashsize 1024 maxelem 65536 # No restore file, so create x3mRouting_NETFLIX_DNSMASQ ipset list from scratch
164 fi
165 fi
166}
167
168# if ipset list NETFLIX is older than 24 hours, save the current ipset list to disk
169check_NETFLIX_restore_file_age () {
170 if [ -s /opt/tmp/x3mRouting_NETFLIX_DNSMASQ ]; then
171 if [ "$(find /opt/tmp/x3mRouting_NETFLIX_DNSMASQ -name x3mRouting_NETFLIX_DNSMASQ -mtime +1 -print 2>/dev/null)" = "/opt/tmp/x3mRouting_NETFLIX_DNSMASQ" ] ; then
172 ipset save x3mRouting_NETFLIX_DNSMASQ > /opt/tmp/x3mRouting_NETFLIX_DNSMASQ
173 fi
174 fi
175}
176
177# If cronjob to back up the NETFLIX ipset list every 24 hours @ 2:00 AM does not exist, then create it
178check_cron_job () {
179 cru l | grep x3mRouting_NETFLIX_DNSMASQ_ipset_list
180 if [ "$?" = "1" ]; then # no cronjob entry found, create it
181 cru a x3mRouting_NETFLIX_DNSMASQ "0 2 * * * ipset save x3mRouting_NETFLIX_DNSMASQ > /opt/tmp/x3mRouting_NETFLIX_DNSMASQ"
182 fi
183}
184
185# Route Netflix to WAN
186create_routing_rules () {
187 iptables -t mangle -D PREROUTING -i br0 -m set --match-set x3mRouting_NETFLIX_DNSMASQ dst -j MARK --set-mark "$FWMARK_WAN" 2>/dev/null
188 iptables -t mangle -A PREROUTING -i br0 -m set --match-set x3mRouting_NETFLIX_DNSMASQ dst -j MARK --set-mark "$FWMARK_WAN" 2>/dev/null
189}
190
191set_fwmark_parms
192create_fwmarks
193Chk_Entware
194check_dnsmasq
195check_ipset_list
196check_NETFLIX_restore_file_age
197check_cron_job
198create_routing_rules
199
200logger -t "($(basename "$0"))" $$ Completed Script Execution
201}
202main