Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- export DEBUG= # uncomment/comment to enable/disable debug mode
- # ---------------------------------------------------------------------------- #
- # ddwrt-ovpn-split.sh: v1.0.4, 20 January 2017, by eibgrad
- # ---------------------------------------------------------------------------- #
- OVPN_DIR="/tmp"
- OVPN_SPLIT="$OVPN_DIR/ovpn-split.sh"
- OVPN_SPLIT_BOOT="$OVPN_DIR/ovpn-split-boot.sh"
- # ----------------------------- BEGIN OVPN_SPLIT ----------------------------- #
- cat << "EOF" > $OVPN_SPLIT
- #!/bin/sh
- dev_type="$(grep -Em1 '^dev ' /tmp/openvpncl/openvpn.conf | \
- awk '{print substr($2,0,3)}')"
- # this script is only applicable to routed (tun) tunnels
- [ "$dev_type" != "tun" ] && exit
- (
- [ ${DEBUG+x} ] && set -x
- # ---------------------------------------------------------------------------- #
- # GW_MODE="WAN" : make WAN default gateway, firewall rules bypass WAN for VPN
- # GW_MODE="VPN" : make VPN default gateway, firewall rules bypass VPN for WAN
- # GW_MODE="" : firewall rules bypass current default gateway for WAN/VPN
- # ---------------------------------------------------------------------------- #
- #GW_MODE="WAN"
- #GW_MODE="VPN"
- GW_MODE=""
- TID="200"
- FW_MARK="0x88"
- VPN_IF="$(grep -Em1 '^dev ' /tmp/openvpncl/openvpn.conf | awk '{print $2}')"
- VPN_GW="$(ifconfig $VPN_IF | awk '/inet addr/ {split ($3,A,":"); print A[2]}')"
- WAN_IF="$(ip route | awk '/^default/{print $NF}')"
- WAN_GW="$(nvram get wan_gateway)"
- DFLT_GW_MASK='^default|^0.0.0.0/1|^128.0.0.0/1'
- is_gw_redirected() {
- # scan main routing table for VPN default gateway
- ip route show | grep -E $DFLT_GW_MASK | grep -Eqm1 "$VPN_IF"
- }
- change_main_default_gw() {
- # add more specific default routes to WAN/VPN in main routing table
- ip route add 0.0.0.0/2 via $1
- ip route add 64.0.0.0/2 via $1
- ip route add 128.0.0.0/2 via $1
- ip route add 192.0.0.0/2 via $1
- }
- # if GW_MODE unspecified/invalid, assume current default gateway
- if [[ "$GW_MODE" != "WAN" && "$GW_MODE" != "VPN" ]]; then
- is_gw_redirected && GW_MODE="VPN" || GW_MODE="WAN"
- fi
- # copy main routing table to bypass routing table (exclude all
- # default gateways)
- ip route show | grep -Ev $DFLT_GW_MASK \
- | while read route; do
- ip route add $route table $TID
- done
- # determine whether to add WAN or VPN to bypass routing table,
- # and whether main routing table needs default gateway changed
- if [ "$GW_MODE" == "WAN" ]; then
- # add VPN as default gateway to bypass routing table
- ip route add default via $VPN_GW table $TID
- # add WAN as default gateway to main routing table
- is_gw_redirected && change_main_default_gw $WAN_GW
- else # "$GW_MODE" == "VPN"
- # add WAN as default gateway to bypass routing table
- ip route add default via $WAN_GW table $TID
- # add VPN as default gateway to main routing table
- is_gw_redirected || change_main_default_gw $VPN_GW
- fi
- # force routing system to recognize our changes
- ip route flush cache
- # disable reverse path filtering
- for i in /proc/sys/net/ipv4/conf/*/rp_filter; do
- echo 0 > $i
- done
- # install additional iptables modules
- insmod xt_mac 2>/dev/null
- insmod ipt_mac 2>/dev/null
- # useful abbreviations
- IPT_MARK="-j MARK --set-mark $FW_MARK"
- IPT_RTR="iptables -t mangle -A OUTPUT"
- IPT_LAN="iptables -t mangle -A PREROUTING"
- # WARNING: IPT_MARK must be specified last when used in any firewall rules or
- # else dd-wrt will generate a segmentation fault!
- # bypass WAN/VPN (router only)
- # --------------------------- BEGIN FIREWALL RULES --------------------------- #
- $IPT_RTR -p tcp -m multiport --sports 2222,8080 $IPT_MARK # router services
- # ---------------------------- END FIREWALL RULES ---------------------------- #
- # bypass WAN/VPN (lan only)
- # --------------------------- BEGIN FIREWALL RULES --------------------------- #
- $IPT_LAN -s 192.168.1.113 $IPT_MARK
- $IPT_LAN -p tcp -s 192.168.1.42 --sport 22 $IPT_MARK # port forward
- $IPT_LAN -p tcp -s 192.168.1.107 --sport 80 $IPT_MARK # port forward
- $IPT_LAN -p tcp -s 192.168.1.155 --sport 80 $IPT_MARK # port forward
- $IPT_LAN -p tcp --dport 443 $IPT_MARK
- $IPT_LAN -m mac --mac-source b8:70:f4:b3:4d:6a $IPT_MARK
- # ---------------------------- END FIREWALL RULES ---------------------------- #
- # if NAT enabled, then NAT everything (router and all)
- if iptables -t nat -vnL POSTROUTING | grep -q $VPN_IF; then
- # enable NAT for all over WAN
- iptables -t nat -I POSTROUTING -o $WAN_IF -j MASQUERADE
- # enable NAT for all over VPN
- iptables -t nat -I POSTROUTING -o $VPN_IF -j MASQUERADE
- fi
- # start split tunnel
- ip rule add fwmark $FW_MARK table $TID
- ) 2>&1 | logger -t $(basename $0)[$$]
- EOF
- chmod +x $OVPN_SPLIT
- # ------------------------------ END OVPN_SPLIT ------------------------------ #
- # -------------------------- BEGIN OVPN_SPLIT_BOOT --------------------------- #
- cat << "EOF" > $OVPN_SPLIT_BOOT
- #!/bin/sh
- (
- [ ${DEBUG+x} ] && set -x
- WAIT_TIME="10"
- # wait for OpenVPN to start
- while ! pidof openvpn >/dev/null 2>&1; do
- sleep $WAIT_TIME
- done
- # wait for OpenVPN network interface to be defined
- while :; do
- VPN_IF="$(grep -Em1 '^dev ' /tmp/openvpncl/openvpn.conf 2>/dev/null | \
- awk '{print $2}')"
- [ ! "$VPN_IF" ] && sleep $WAIT_TIME || break
- done
- # wait for OpenVPN network interface to be initialized (w/ ip address)
- while :; do
- VPN_GW="$(ifconfig $VPN_IF | \
- awk '/inet addr/ {split ($3,A,":"); print A[2]}')"
- [ ! "$VPN_GW" ] && sleep $WAIT_TIME || break
- done
- # wait for OpenVPN initialized network interface to appear in routing table
- while ! ip route show | grep -m1 $VPN_GW | grep -q $VPN_IF; do
- sleep $WAIT_TIME
- done
- # start split tunnel
- $OVPN_SPLIT &
- ) 2>&1 | logger -t $(basename $0)[$$]
- EOF
- sed -i "s:\$OVPN_SPLIT:$OVPN_SPLIT:" $OVPN_SPLIT_BOOT
- chmod +x $OVPN_SPLIT_BOOT
- # --------------------------- END OVPN_SPLIT_BOOT ---------------------------- #
- # start bootstrap
- $OVPN_SPLIT_BOOT &
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement