vpnbypass: bugfix: PROCD command not found on stop
authorStan Grishin <stangri@melmac.net>
Mon, 21 Oct 2019 04:21:30 +0000 (21:21 -0700)
committerStan Grishin <stangri@melmac.net>
Mon, 21 Oct 2019 04:21:30 +0000 (21:21 -0700)
Signed-off-by: Stan Grishin <stangri@melmac.net>
net/vpnbypass/Makefile
net/vpnbypass/files/README.md
net/vpnbypass/files/vpnbypass.init

index 2c0b545cff67ea3f1c8d7a43b00ae8e23fa91f24..84973c15c5656ac5ec45dc99f6e9e54dfe3ea2d2 100644 (file)
@@ -1,12 +1,12 @@
-# Copyright (c) 2017 Stan Grishin (stangri@melmac.net)
+# Copyright 2017-2018 Stan Grishin (stangri@melmac.net)
 # This is free software, licensed under the GNU General Public License v3.
 
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=vpnbypass
 PKG_VERSION:=1.3.1
-PKG_RELEASE:=1
-PKG_LICENSE:=GPL-3.0+
+PKG_RELEASE:=4
+PKG_LICENSE:=GPL-3.0-or-later
 PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net>
 
 include $(INCLUDE_DIR)/package.mk
@@ -54,43 +54,34 @@ define Package/vpnbypass/install
 endef
 
 
-define Package/$(PKG_NAME)/postinst
+define Package/vpnbypass/postinst
        #!/bin/sh
        # check if we are on real system
        if [ -z "$${IPKG_INSTROOT}" ]; then
-               while [ ! -z "$(uci -q get ucitrack.@vpnbypass[-1] 2>/dev/null)" ] ; do
-                       uci -q delete ucitrack.@vpnbypass[-1]
-               done
+               /etc/init.d/vpnbypass enable
 
-               while [ ! -z "$(uci -q get ucitrack.@firewall[-1].affects 2>/dev/null | awk '/vpnbypass/')" ] ; do
-                       uci -q del_list ucitrack.@firewall[-1].affects='vpnbypass'
-               done
+               while uci -q del ucitrack.@vpnbypass[-1]; do :; done
 
                uci -q batch <<-EOF >/dev/null
                        add ucitrack vpnbypass
-                       set ucitrack.@vpnbypass[-1].init='vpnbypass'
-                       add_list ucitrack.@firewall[-1].affects='vpnbypass'
+                       set ucitrack.@vpnbypass[0].init='vpnbypass'
+                       del_list ucitrack.@firewall[0].affects='vpnbypass'
+                       add_list ucitrack.@firewall[0].affects='vpnbypass'
                        commit ucitrack
        EOF
        fi
        exit 0
 endef
 
-define Package/$(PKG_NAME)/prerm
+define Package/vpnbypass/prerm
        #!/bin/sh
        # check if we are on real system
        if [ -z "$${IPKG_INSTROOT}" ]; then
+               while uci -q delete ucitrack.@vpnbypass[-1]; do :; done
+               uci -q del_list ucitrack.@firewall[0].affects='vpnbypass'
                echo "Stopping service and removing rc.d symlink for vpnbypass"
                /etc/init.d/vpnbypass stop || true
-               /etc/init.d/vpnbypass disable
-
-               while [ ! -z "$(uci -q get ucitrack.@vpnbypass[-1] 2>/dev/null)" ] ; do
-                       uci -q delete ucitrack.@vpnbypass[-1]
-               done
-
-               while [ ! -z "$(uci -q get ucitrack.@firewall[-1].affects 2>/dev/null | awk '/vpnbypass/')" ] ; do
-                       uci -q del_list ucitrack.@firewall[-1].affects='vpnbypass'
-               done
+               /etc/init.d/vpnbypass disable || true
        fi
        exit 0
 endef
index eaccd2ca597c779ba9b1af43f8bdd7f3cf5fe075..e73754d1e2997e6a7b6b621d1bf96ac2bf301ce1 100644 (file)
@@ -1,7 +1,9 @@
 # VPN Bypass
+
 A simple PROCD-based ```vpnbypass``` service for OpenWrt/LEDE Project. Useful if your router accesses internet thru VPN client/tunnel, but you want specific traffic (ports, IP ranges, domains or local IP ranges) to be routed outside of this tunnel.
 
 ## Features
+
 - Allows to define local ports so that traffic to them is routed outside of the VPN tunnel (by default routes Plex Media Server traffic (port 32400) outside of the VPN tunnel).
 - Allows to define IPs/subnets in local network so that their traffic is routed outside of the VPN tunnel (by default routes traffic from 192.168.1.81-192.168.1.87 outside of the VPN tunnel).
 - Allows to define remote IPs/ranges that they are accessed outside of the VPN tunnel (by default routes LogmeIn Hamachi traffic (25.0.0.0/8) outside of the VPN tunnel).
@@ -11,25 +13,31 @@ A simple PROCD-based ```vpnbypass``` service for OpenWrt/LEDE Project. Useful if
 - Proudly made in Canada, using locally-sourced electrons.
 
 ## Screenshot (luci-app-vpnbypass)
-![screenshot](https://raw.githubusercontent.com/stangri/screenshots/master/vpnbypass/screenshot02.png "screenshot")
+
+![screenshot](https://raw.githubusercontent.com/stangri/openwrt_packages/master/screenshots/vpnbypass/screenshot02.png "screenshot")
 
 ## Requirements
+
 This service requires following packages to be installed on your router: ```ipset``` and ```iptables```. Additionally, if you want to use Domain Bypass feature, you need to install ```dnsmasq-full``` (```dnsmasq-full``` requires you uninstall ```dnsmasq``` first).
 
 To fully satisfy the requirements for both IP/Port VPN Bypass and Domain Bypass features connect to your router via ssh and run the following commands:
+
 ```sh
 opkg update; opkg remove dnsmasq; opkg install ipset iptables dnsmasq-full
 ```
 
 To satisfy the requirements for just IP/Port VPN Bypass connect to your router via ssh and run the following commands:
+
 ```sh
 opkg update; opkg install ipset iptables
 ```
 
-#### Unmet dependencies
+### Unmet dependencies
+
 If you are running a development (trunk/snapshot) build of OpenWrt/LEDE Project on your router and your build is outdated (meaning that packages of the same revision/commit hash are no longer available and when you try to satisfy the [requirements](#requirements) you get errors), please flash either current LEDE release image or current development/snapshot image.
 
 ## How to install
+
 <!---
 #### From Web UI/Luci
 Navigate to System->Software page on your router and then perform the following actions:
@@ -43,77 +51,45 @@ If you get an ```Unknown package 'vpnbypass'``` error, your router is not set up
 #### From console/ssh
 --->
 Please make sure that the [requirements](#requirements) are satisfied and install ```vpnbypass``` and ```luci-app-vpnbypass``` from Web UI or connect to your router via ssh and run the following commands:
+
 ```sh
 opkg update
 opkg install vpnbypass luci-app-vpnbypass
 ```
-If these packages are not found in the official feed/repo for your version of OpenWrt/LEDE Project, you will need to [add a custom repo to your router](#add-custom-repo-to-your-router) first.
-
-#### Add custom repo to your router
-If your router is not set up with the access to repository containing these packages you will need to add custom repository to your router by connecting to your router via ssh and running the following commands:
 
-###### OpenWrt 15.05.1
-```sh
-opkg update; opkg install ca-certificates wget libopenssl
-echo -e -n 'untrusted comment: public key 7ffc7517c4cc0c56\nRWR//HUXxMwMVnx7fESOKO7x8XoW4/dRidJPjt91hAAU2L59mYvHy0Fa\n' > /tmp/stangri-repo.pub && opkg-key add /tmp/stangri-repo.pub
-! grep -q 'stangri_repo' /etc/opkg/customfeeds.conf && echo 'src/gz stangri_repo https://raw.githubusercontent.com/stangri/openwrt-repo/master' >> /etc/opkg/customfeeds.conf
-opkg update
-```
-
-###### LEDE Project 17.01.x and OpenWrt 18.xx or later
-```sh
-opkg update; opkg install uclient-fetch libustream-mbedtls
-echo -e -n 'untrusted comment: public key 7ffc7517c4cc0c56\nRWR//HUXxMwMVnx7fESOKO7x8XoW4/dRidJPjt91hAAU2L59mYvHy0Fa\n' > /tmp/stangri-repo.pub && opkg-key add /tmp/stangri-repo.pub
-! grep -q 'stangri_repo' /etc/opkg/customfeeds.conf && echo 'src/gz stangri_repo https://raw.githubusercontent.com/stangri/openwrt-repo/master' >> /etc/opkg/customfeeds.conf
-opkg update
-```
+If these packages are not found in the official feed/repo for your version of OpenWrt/LEDE Project, you will need to [add a custom repo to your router](https://github.com/stangri/openwrt_packages/blob/master/README.md#on-your-router) first.
 
 ## Default Settings
-Default configuration has service disabled (use Web UI to enable/start service or run ```uci set vpnbypass.config.enabled=1```) and routes Plex Media Server traffic (port 32400) outside of the VPN tunnel, routes LogmeIn Hamachi traffic (25.0.0.0/8) outside of the VPN tunnel and also routes internet traffic from local IPs 192.168.1.81-192.168.1.87 outside of the VPN tunnel. You can safely delete these example rules if they do not apply to you.
+
+Default configuration has service disabled (use Web UI to enable/start service or run ```uci set vpnbypass.config.enabled=1; uci commit vpnbypass;```) and routes Plex Media Server traffic (port 32400) outside of the VPN tunnel, routes LogmeIn Hamachi traffic (25.0.0.0/8) outside of the VPN tunnel and also routes internet traffic from local IPs 192.168.1.81-192.168.1.87 outside of the VPN tunnel. You can safely delete these example rules if they do not apply to you.
 
 ## Documentation / Discussion
-Please head to [LEDE Project Forum](https://forum.lede-project.org/t/vpn-bypass-split-tunneling-service-luci-ui/1106) for discussions of this service.
 
-#### Bypass Domains Format/Syntax
+Please head to [OpenWrt Forum](https://forum.openwrt.org/t/vpn-bypass-split-tunneling-service-luci-ui/1106) for discussions of this service.
+
+### Bypass Domains Format/Syntax
+
 Domain lists should be in following format/syntax: ```/domain1.com/domain2.com/vpnbypass```. Please don't forget the leading ```/``` and trailing ```/vpnbypass```. There's no validation if you enter something incorrectly -- it just won't work. Please see [Notes/Known Issues](#notesknown-issues) if you want to edit this setting manually, without Web UI.
 
 ## What's New
-1.3.0
+
+1.3.0:
+
 - No longer depends on hardcoded WAN interface name (```wan```) works with other interface names (like ```wwan```).
 - Table ID, IPSET name and FW_MARK as well as FW_MASK can be defined in config file.
 - Uses iptables, not ip rules for handling local IPs/ranges.
 - More reliable creation/destruction of VPNBYPASS iptables chain.
 - Updated Web UI enables/start and stops service.
-- Beautified output.
-
-1.2.0
-- More elegant handling of iptables (thanks [@hnyman](https://github.com/hnyman) and [@tohojo](https://github.com/tohojo)!).
-
-1.1.1
-- More reliable way of obtaining WAN gateway on boot (thanks [@dibdot](https://github.com/dibdot) for the hint!).
-
-1.1.0:
-- Detects individual IP addresses in the config and converts them to subnet automatically.
-- Proper implementation of reload on vpnbypass config change.
-
-1.0.0:
-- Hotplug script created during install.
-
-0.1.0:
-- Package built.
-- Support for user-defined ports implemented.
-- Support for user-defined routes implemented.
-- Support for user-defined local ranges implemented.
-
-0.0.1:
-- Initial release.
 
 ## Notes/Known Issues
+
 1. Domains to be accessed outside of VPN tunnel are handled by dnsmasq and thus are not defined in ```/etc/config/vpnpass```, but rather in ```/etc/config/dhcp```. To add/delete/edit domains you can use VPN Bypass Web UI or you can edit ```/etc/config/dhcp``` manually or run following commands:
+
 ```sh
 uci add_list dhcp.@dnsmasq[-1].ipset='/github.com/plex.tv/google.com/vpnbypass'
 uci add_list dhcp.@dnsmasq[-1].ipset='/hulu.com/netflix.com/nhl.com/vpnbypass'
 uci commit dhcp
 /etc/init.d/dnsmasq restart
 ```
+
 This feature requires ```dnsmasq-full``` to work. See [Requirements](#requirements) paragraph for more details.
index de7ff5ac2ac4327bcac8b17af0816f6ef283c886..756b36d728c9829b50e36adf03d9f440ca563710 100644 (file)
@@ -13,7 +13,21 @@ readonly _ERROR_='\033[0;31mERROR\033[0m'
 
 export serviceEnabled verbosity=2 TID='200' IPSET='vpnbypass' FW_MARK='0x010000' FW_MASK='0xff0000' wan_if4 wan_gw
 
-output() { [[ $# -ne 1 ]] && { [[ ! $((verbosity & $1)) -gt 0 ]] && return 0 || shift; }; local msg; msg=$(echo -n "${1/$serviceName /service }" | sed 's|\\033\[[0-9]\?;\?[0-9]\?[0-9]\?m||g'); [[ -t 1 ]] && echo -e -n "$1"; [[ $(echo -e -n "$msg" | wc -l) -gt 0 ]] && logger -t "${packageName:-service} [$$]" "$(echo -e -n ${logmsg}${msg})" && logmsg='' || logmsg=${logmsg}${msg}; }
+output() {
+# Can take a single parameter (text) to be output at any verbosity
+# Or target verbosity level and text to be output at specifc verbosity
+       if [ $# -ne 1 ]; then
+               if [ ! $((verbosity & $1)) -gt 0 ]; then return 0; else shift; fi
+       fi
+       [ -t 1 ] && echo -e -n "$1"
+       local msg=$(echo -n "${1/$serviceName /service }" | sed 's|\\033\[[0-9]\?;\?[0-9]\?[0-9]\?m||g');
+       if [ "$(echo -e -n "$msg" | wc -l)" -gt 0 ]; then
+               logger -t "${packageName:-service} [$$]" "$(echo -e -n "${logmsg}${msg}")"
+               logmsg=''
+       else
+               logmsg="${logmsg}${msg}"
+       fi
+}
 readonly packageName='vpnbypass'
 readonly serviceName="$packageName $PKG_VERSION"
 
@@ -21,7 +35,10 @@ load_package_config() {
        config_load "$packageName"
        config_get_bool serviceEnabled 'config' 'enabled' 1
        config_get verbosity           'config' 'verbosity' '2'
-       source  /lib/functions/network.sh
+       if [ -z "${verbosity##*[!0-9]*}" ] || [ "$verbosity" -lt 0 ] || [ "$verbosity" -gt 2 ]; then
+               verbosity=1
+       fi
+       . /lib/functions/network.sh
 }
 
 is_enabled() {
@@ -29,45 +46,49 @@ is_enabled() {
        load_package_config
        while : ; do
                network_find_wan wan_if4
-               [ $serviceEnabled -gt 0 ] || return 1
-               [ -n "$wan_if4" ] && network_get_gateway wan_gw $wan_if4
-               [[ $sleepCount -ge 25 || -n "$wan_gw" ]] && break
-               output "$serviceName waiting for wan gateway...\n"
+               [ "$serviceEnabled" -gt 0 ] || return 1
+               [ -n "$wan_if4" ] && network_get_gateway wan_gw "$wan_if4"
+               if [ $sleepCount -ge 25 ] || [ -n "$wan_gw" ]; then break; fi
+               output "$serviceName waiting for wan gateway...\\n"
                sleep 2; network_flush_cache; let "sleepCount+=1";
        done
        [ -n "$wan_gw" ] && return 0
-       output "$__ERROR__: $serviceName failed to discover WAN gateway.\n"; return 1;
+       output "$__ERROR__: $serviceName failed to discover WAN gateway.\\n"; return 1;
 }
 
-is_ovpn() { local dev; dev=$(uci -q get network.$1.ifname); if [[ "${dev:0:3}" == "tun" || "${dev:0:3}" == "tap" || -f "/sys/devices/virtual/net/${dev}/tun_flags" ]]; then return 0; else return 1; fi; }
-is_wan() { if [ -n "$wan_if4" ] && [ "$1" == "$wan_if4" ]; then return 0; else return 1; fi; }
+is_ovpn() { local dev; dev=$(uci -q get network."$1".ifname); if [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; then return 0; else return 1; fi; }
+is_wan() { if [ -n "$wan_if4" ] && [ "$1" = "$wan_if4" ]; then return 0; else return 1; fi; }
 is_supported_interface() { if is_wan "$1" || is_ovpn "$1"; then return 0; else return 1; fi; }
 
+# shellcheck disable=SC2086
 ipt() {
-    local d; d=$(echo "$*" | sed s/-A/-D/g);
-    [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
-    d=$(echo "$*" | sed s/-I/-D/g)
-    [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
-               d=$(echo "$*" | sed s/-N/-F/g)
-    [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
-               d=$(echo "$*" | sed s/-N/-X/g)
-    [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
-               d="$*"
-               iptables $d >/dev/null 2>&1 || output "\n$__ERROR__: iptables $d\n"
+  local d; 
+  d="${*//-A/-D}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
+  d="${*//-I/-D}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
+  d="${*//-N/-F}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
+  d="${*//-N/-X}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1
+       d="$*"; iptables $d >/dev/null 2>&1 || output "\\n$__ERROR__: iptables $d\\n"
 }
 
 start_service() {
-       local ll lports rports routes ranges
+  local ll lports rports routes ranges
   is_enabled || return 1
   config_get lports   'config' 'localport'
   config_get rports   'config' 'remoteport'
   config_get routes   'config' 'remotesubnet'
   config_get ranges   'config' 'localsubnet'
 
-       iptables -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS >/dev/null 2>&1
+       procd_open_instance "main"
+       procd_set_param command /bin/true
+       procd_set_param stdout 1
+       procd_set_param stderr 1
+       procd_close_instance
+
+       ipt -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS >/dev/null 2>&1
        ipt -t mangle -N VPNBYPASS; ipt -t mangle -A PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS;
        ipt -t mangle -A VPNBYPASS -m set --match-set $IPSET dst -j MARK --set-mark ${FW_MARK}/${FW_MASK}
-       ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; ipset -q flush "$IPSET"; ipset -q destroy "$IPSET";
+       ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; 
+       ipset -q flush "$IPSET"; ipset -q destroy "$IPSET";
        ip route flush table "$TID"; ip route flush cache;
        ip route add default via "$wan_gw" table "$TID"; ip route flush cache;
        ipset -q -exist create "$IPSET" hash:ip; ipset -q flush "$IPSET"
@@ -77,16 +98,17 @@ start_service() {
        for ll in ${lports}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --sport "${ll//-/:}"; done
        for ll in ${routes}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -d "$ll"; done
        for ll in ${rports}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --dport "${ll//-/:}"; done
-       output "$serviceName started with TID: $TID; FW_MARK: $FW_MARK\n"
+       output "$serviceName started with TID: $TID; FW_MARK: $FW_MARK\\n"
 }
 
 stop_service() {
   load_package_config
-       ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; ipset -q flush "$IPSET"; ipset -q destroy "$IPSET";
+       ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; 
+       ipset -q flush "$IPSET"; ipset -q destroy "$IPSET";
        ip route flush table "$TID"; ip route flush cache;
        ipt -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS
        ipt -t mangle -F VPNBYPASS; ipt -t mangle -X VPNBYPASS;
-       output "$serviceName stopped\n"
+       output "$serviceName stopped\\n"
 }
 
 service_triggers_load_interface() { is_supported_interface "$1" && ifaces="${ifaces}${1} "; }
@@ -96,7 +118,7 @@ service_triggers() {
                procd_add_reload_trigger 'firewall'
                procd_add_reload_trigger 'openvpn'
                procd_open_trigger
-                       for n in $ifaces; do procd_add_reload_interface_trigger "$n"; procd_add_interface_trigger "interface.*" "$n" /etc/init.d/${packageName} reload; done;
-                       output 2 "$serviceName monitoring interfaces: $ifaces $_OK_\n"
+                       for n in $ifaces; do procd_add_reload_interface_trigger "$n"; procd_add_interface_trigger "interface.*" "$n" /etc/init.d/vpnbypass reload; done;
+                       output "$serviceName monitoring interfaces: $ifaces $_OK_\\n"
                procd_close_trigger
 }