Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- #DEBUG= # uncomment/comment to enable/disable debug mode
- # name: merlin-ovpn-client-killswitch.sh
- # version: 2.0.0, 22-jul-2022, by eibgrad
- # purpose: openvpn client firewall-based killswitch
- # type(s): firewall-start
- # href: https://tinyurl.com/35xww7ue
- # installation:
- # 1. enable jffs custom scripts and configs (administration->system)
- # 2. ssh to router and copy/paste the following command:
- # curl -kLs bit.ly/merlin-installer|tr -d '\r'|sh -s F2GmyrCC
- # 3. modify script w/ your preferred options using nano editor:
- # nano /jffs/scripts/merlin-ovpn-client-killswitch.sh
- # 4. reboot
- SCRIPTS_DIR="/jffs/scripts"
- SCRIPT1="$SCRIPTS_DIR/merlin-ovpn-client-killswitch.sh"
- SCRIPT2="$SCRIPTS_DIR/firewall-start"
- mkdir -p $SCRIPTS_DIR
- # ------------------- begin merlin-ovpn-client-killswitch -------------------- #
- cat << 'EOF' > $SCRIPT1
- #!/bin/sh
- #set -x # comment/uncomment to disable/enable debug mode
- {
- # ------------------------------ BEGIN OPTIONS ------------------------------- #
- # openvpn clients that will participate in the killswitch (all by default)
- VPN_CLIENTS='1 2 3 4 5'
- # uncomment/comment to enable/disable autostart checking
- VPN_AUTOSTART_ONLY= # only consider auto-started openvpn clients
- # state checking: "state NEW" vs. no state
- # state NEW:
- # * any pre-existing LAN->WAN connections persist unless/until they
- # timeout/close
- # * remote access (WAN->LAN) is allowed (provided port forwarding is enabled)
- # * more efficient (only LAN->WAN packets used to establish NEW connections
- # are inspected)
- # no state (default):
- # * any pre-existing LAN->WAN connections are stopped/blocked
- # * remote access (WAN->LAN) is denied (even if port forwarding is enabled)
- # * less efficient (every LAN->WAN packet is inspected)
- # uncomment/comment to enable/disable state checking
- #FW_STATE='-m state --state NEW'
- # ------------------------------- END OPTIONS -------------------------------- #
- # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
- WAN_IF="$([ $1 ] && echo $1 || echo $(nvram get wan0_ifname))"
- PBR_RULES="$(sed 's/\s//g' /jffs/openvpn/vpndirector_rulelist 2>/dev/null)"
- FW_CHAIN='ovpnc_block_wan'
- # function is_autostart_enabled( vpn-client-number )
- is_autostart_enabled() { nvram get vpn_clientx_eas | grep -q $1; }
- # function is_killswitch_participant( vpn-client-number )
- is_killswitch_participant() { echo $VPN_CLIENTS | grep -q $1; }
- # function is_redirect_all( vpn-client-number )
- is_redirect_all() { [ "$(nvram get vpn_client${1}_rgw)" == '1' ]; }
- # cleanup from possible prior execution
- {
- iptables -D FORWARD -i br+ -o $WAN_IF $FW_STATE -j REJECT
- iptables -D FORWARD -i br+ -o $WAN_IF $FW_STATE -j $FW_CHAIN
- iptables -F $FW_CHAIN && iptables -X $FW_CHAIN
- } &>/dev/null
- for i in $VPN_CLIENTS; do
- # handle vpn client w/ "Yes(all)" routing policy
- is_redirect_all $i || continue
- # prerequisite: vpn client has autostart enabled (when applicable)
- [ ${VPN_AUTOSTART_ONLY+x} ] && ! is_autostart_enabled $i && continue
- # deny access to wan by *all* lan clients
- iptables -I FORWARD -i br+ -o $WAN_IF $FW_STATE -j REJECT
- exit 0
- done
- # create user-defined chain
- iptables -N $FW_CHAIN
- # iterate over the pbr (policy based routing) rules
- for i in $(echo "$PBR_RULES" | tr '<' '\n'); do
- # parse the rule into separate fields (ignore description field (#2))
- for j in 1 3 4 5; do eval f$j="$(echo $i | cut -d'>' -f$j)"; done
- # prerequisite: enabled rule
- [ "$f1" == '1' ] || continue
- # handle wan pbr rule
- if echo $f5 | grep -q 'WAN'; then
- # do NOT deny access to this local and/or remote ip/network
- iptables -A $FW_CHAIN $([ "$f3" ] && echo "-s $f3") \
- $([ "$f4" ] && echo "-d $f4") -j RETURN
- continue
- fi
- # handle vpn pbr rule
- echo $f5 | grep -q 'OVPN' || continue
- # isolate vpn client number
- f5="$(echo $f5 | grep -o [1-5])"
- # prerequisite: vpn client is killswitch participant
- is_killswitch_participant $f5 || continue
- # prerequisite: vpn client has autostart enabled (when applicable)
- [ ${VPN_AUTOSTART_ONLY+x} ] && ! is_autostart_enabled $f5 && continue
- # deny access to wan for this local and/or remote ip/network
- iptables -A $FW_CHAIN $([ "$f3" ] && echo "-s $f3") \
- $([ "$f4" ] && echo "-d $f4") -j REJECT
- done
- # force LAN->WAN traffic thru user-defined chain for inspection
- iptables -I FORWARD -i br+ -o $WAN_IF $FW_STATE -j $FW_CHAIN
- exit 0
- } 2>&1 | logger -t $(basename $0 .sh)[$$]
- EOF
- [ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT1
- chmod +x $SCRIPT1
- echo "installed: $SCRIPT1"
- # -------------------- end merlin-ovpn-client-killswitch --------------------- #
- # --------------------------- begin firewall-start --------------------------- #
- create_script() {
- cat << 'EOF' > $SCRIPT2
- #!/bin/sh
- #set -x # comment/uncomment to disable/enable debug mode
- {
- $SCRIPT1
- } 2>&1 | logger -t $(basename $0)[$$]
- EOF
- [ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT2
- sed "s:\$SCRIPT1:$SCRIPT1:g" -i $SCRIPT2
- chmod +x $SCRIPT2
- }
- if [ -f $SCRIPT2 ]; then
- echo "error: $SCRIPT2 already exists; requires manual installation"
- else
- create_script
- echo "installed: $SCRIPT2"
- fi
- # ---------------------------- end firewall-start ---------------------------- #
Add Comment
Please, Sign In to add comment