View difference between Paste ID: F2GmyrCC and 4PptMAx6
SHOW: | | - or go back to the newest paste.
1
#!/bin/sh
2-
# version: 1.0.0, 28-sep-2021, by eibgrad
2+
#DEBUG= # uncomment/comment to enable/disable debug mode
3-
# href: https://tinyurl.com/crwtpkep
3+
4
#          name: merlin-ovpn-client-killswitch.sh
5
#       version: 2.0.0, 22-jul-2022, by eibgrad
6-
SCRIPT="$SCRIPTS_DIR/firewall-start"
6+
#       purpose: openvpn client firewall-based killswitch
7
#       type(s): firewall-start
8
#          href: https://tinyurl.com/35xww7ue
9
#  installation:
10
#    1. enable jffs custom scripts and configs (administration->system)
11-
cat << "EOF" > $SCRIPT
11+
#    2. ssh to router and copy/paste the following command:
12
#         curl -kLs bit.ly/merlin-installer|tr -d '\r'|sh -s F2GmyrCC
13-
set -x # uncomment/comment to enable/disable debug mode
13+
#    3. modify script w/ your preferred options using nano editor:
14
#         nano /jffs/scripts/merlin-ovpn-client-killswitch.sh
15
#    4. reboot
16
17-
# openvpn clients that will participate in the kill switch (all by default)
17+
18
SCRIPT1="$SCRIPTS_DIR/merlin-ovpn-client-killswitch.sh"
19
SCRIPT2="$SCRIPTS_DIR/firewall-start"
20
21
mkdir -p $SCRIPTS_DIR
22
23
# ------------------- begin merlin-ovpn-client-killswitch -------------------- #
24
cat << 'EOF' > $SCRIPT1
25
#!/bin/sh
26
#set -x # comment/uncomment to disable/enable debug mode
27
{
28
# ------------------------------ BEGIN OPTIONS ------------------------------- #
29
30
# openvpn clients that will participate in the killswitch (all by default)
31
VPN_CLIENTS='1 2 3 4 5'
32
33
# uncomment/comment to enable/disable autostart checking
34
VPN_AUTOSTART_ONLY= # only consider auto-started openvpn clients
35
36
# state checking: "state NEW" vs. no state
37
#   state NEW:
38
#     * any pre-existing LAN->WAN connections persist unless/until they
39
#       timeout/close
40
#     * remote access (WAN->LAN) is allowed (provided port forwarding is enabled)
41
#     * more efficient (only LAN->WAN packets used to establish NEW connections
42-
PBR_RULES="$(cat /jffs/openvpn/vpndirector_rulelist)"
42+
43-
FW_CHAIN='ovpn_block_wan'
43+
44-
WAN_IF="$(nvram get wan0_ifname)"
44+
45
#     * remote access (WAN->LAN) is denied (even if port forwarding is enabled)
46
#     * less efficient (every LAN->WAN packet is inspected)
47
48
# uncomment/comment to enable/disable state checking
49-
# function is_kill_switch_participant( vpn-client-number )
49+
50-
is_kill_switch_participant() { echo $VPN_CLIENTS | grep -q $1; }
50+
51
# ------------------------------- END OPTIONS -------------------------------- #
52
53
# ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
54
55
WAN_IF="$([ $1 ] && echo $1 || echo $(nvram get wan0_ifname))"
56
PBR_RULES="$(sed 's/\s//g' /jffs/openvpn/vpndirector_rulelist 2>/dev/null)"
57
FW_CHAIN='ovpnc_block_wan'
58
59
# function is_autostart_enabled( vpn-client-number )
60
is_autostart_enabled() { nvram get vpn_clientx_eas | grep -q $1; }
61
62
# function is_killswitch_participant( vpn-client-number )
63-
    # prerequisite: vpn client has "Yes(all)" routing policy
63+
is_killswitch_participant() { echo $VPN_CLIENTS | grep -q $1; }
64
65
# function is_redirect_all( vpn-client-number )
66
is_redirect_all() { [ "$(nvram get vpn_client${1}_rgw)" == '1' ]; }
67
68
# cleanup from possible prior execution
69
{
70
iptables -D FORWARD -i br+ -o $WAN_IF $FW_STATE -j REJECT
71
iptables -D FORWARD -i br+ -o $WAN_IF $FW_STATE -j $FW_CHAIN
72
iptables -F $FW_CHAIN && iptables -X $FW_CHAIN
73
} &>/dev/null
74
75
for i in $VPN_CLIENTS; do
76
    # handle vpn client w/ "Yes(all)" routing policy
77
    is_redirect_all $i || continue
78
79
    # prerequisite: vpn client has autostart enabled (when applicable)
80
    [ ${VPN_AUTOSTART_ONLY+x} ] && ! is_autostart_enabled $i && continue
81
82-
    # prerequisite: enabled vpn pbr rule
82+
83-
    { [ "$f1" == '1' ] && echo $f5 | grep -q 'OVPN'; } || continue
83+
84
85
    exit 0
86
done
87
88-
    # prerequisite: vpn client is kill switch participant
88+
89-
    is_kill_switch_participant $f5 || continue
89+
90
91
# iterate over the pbr (policy based routing) rules
92
for i in $(echo "$PBR_RULES" | tr '<' '\n'); do
93
    # parse the rule into separate fields (ignore description field (#2))
94
    for j in 1 3 4 5; do eval f$j="$(echo $i | cut -d'>' -f$j)"; done
95
96
    # prerequisite: enabled rule
97
    [ "$f1" == '1' ] || continue
98
99
    # handle wan pbr rule
100
    if echo $f5 | grep -q 'WAN'; then
101
        # do NOT deny access to this local and/or remote ip/network
102
        iptables -A $FW_CHAIN $([ "$f3" ] && echo "-s $f3") \
103-
#} >/tmp/$(basename $0).$$.log 2>&1
103+
            $([ "$f4" ] && echo "-d $f4") -j RETURN
104
        continue
105
    fi
106-
chmod +x $SCRIPT
106+
107
    # handle vpn pbr rule
108
    echo $f5 | grep -q 'OVPN' || continue
109-
if [ -f $SCRIPT ]; then
109+
110-
    echo "error: $SCRIPT already exists; requires manual installation"
110+
111
    f5="$(echo $f5 | grep -o [1-5])"
112
113-
    echo 'Done.'
113+
    # prerequisite: vpn client is killswitch participant
114-
fi
114+
    is_killswitch_participant $f5 || continue
115
116
    # prerequisite: vpn client has autostart enabled (when applicable)
117
    [ ${VPN_AUTOSTART_ONLY+x} ] && ! is_autostart_enabled $f5 && continue
118
119
    # deny access to wan for this local and/or remote ip/network
120
    iptables -A $FW_CHAIN $([ "$f3" ] && echo "-s $f3") \
121
        $([ "$f4" ] && echo "-d $f4") -j REJECT
122
done
123
124
# force LAN->WAN traffic thru user-defined chain for inspection
125
iptables -I FORWARD -i br+ -o $WAN_IF $FW_STATE -j $FW_CHAIN
126
127
exit 0
128
} 2>&1 | logger -t $(basename $0 .sh)[$$]
129
EOF
130
[ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT1
131
chmod +x $SCRIPT1
132
echo "installed: $SCRIPT1"
133
# -------------------- end merlin-ovpn-client-killswitch --------------------- #
134
135
# --------------------------- begin firewall-start --------------------------- #
136
create_script() {
137
cat << 'EOF' > $SCRIPT2
138
#!/bin/sh
139
#set -x # comment/uncomment to disable/enable debug mode
140
{
141
$SCRIPT1
142
} 2>&1 | logger -t $(basename $0)[$$]
143
EOF
144
[ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT2
145
sed "s:\$SCRIPT1:$SCRIPT1:g" -i $SCRIPT2
146
chmod +x $SCRIPT2
147
}
148
149
if [ -f $SCRIPT2 ]; then
150
    echo "error: $SCRIPT2 already exists; requires manual installation"
151
else
152
    create_script
153
    echo "installed: $SCRIPT2"
154
fi
155
# ---------------------------- end firewall-start ---------------------------- #