diff --git a/net/vpnbypass/Makefile b/net/vpnbypass/Makefile index 618ca6a6d..83a4786ba 100644 --- a/net/vpnbypass/Makefile +++ b/net/vpnbypass/Makefile @@ -4,8 +4,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=vpnbypass -PKG_VERSION:=1.3.1 -PKG_RELEASE:=10 +PKG_VERSION:=1.3.2 +PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Stan Grishin @@ -15,6 +15,7 @@ define Package/vpnbypass SECTION:=net CATEGORY:=Network TITLE:=VPN Bypass Service + URL:=https://docs.openwrt.melmac.net/vpnbypass/ DEPENDS:=+ipset +iptables PKGARCH:=all endef @@ -31,12 +32,6 @@ define Package/vpnbypass/conffiles /etc/config/vpnbypass endef -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR)/files/ - $(CP) ./files/vpnbypass.init $(PKG_BUILD_DIR)/files/vpnbypass.init - sed -i "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(PKG_BUILD_DIR)/files/vpnbypass.init -endef - define Build/Configure endef @@ -44,11 +39,10 @@ define Build/Compile endef define Package/vpnbypass/install - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/vpnbypass.init $(1)/etc/init.d/vpnbypass - $(INSTALL_DIR) $(1)/etc/config - $(INSTALL_CONF) ./files/vpnbypass.conf $(1)/etc/config/vpnbypass - $(INSTALL_DIR) $(1)/etc/hotplug.d/firewall + $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/hotplug.d/firewall + $(INSTALL_BIN) ./files/vpnbypass.init $(1)/etc/init.d/vpnbypass + $(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/vpnbypass + $(INSTALL_CONF) ./files/vpnbypass.config $(1)/etc/config/vpnbypass $(INSTALL_DATA) ./files/vpnbypass.hotplug $(1)/etc/hotplug.d/firewall/94-vpnbypass endef diff --git a/net/vpnbypass/files/README.md b/net/vpnbypass/files/README.md index 50fdb8c92..886ac7c55 100644 --- a/net/vpnbypass/files/README.md +++ b/net/vpnbypass/files/README.md @@ -1,100 +1,3 @@ - -# VPN Bypass +# README -[![HitCount](http://hits.dwyl.com/stangri/openwrt/vpnbypass.svg)](http://hits.dwyl.com/stangri/openwrt/vpnbypass) - -A simple [procd](https://openwrt.org/docs/techref/procd)-based ```vpnbypass``` service for OpenWrt/LEDE Project. This is useful if your router accesses Internet through a VPN client/tunnel, but you want specific traffic (ports, IP ranges, domains or local IP ranges) to be routed outside of this tunnel. - -## Features - -- Define local ports so traffic to them is routed outside of the VPN tunnel (by default it routes Plex Media Server traffic (port 32400) outside of the VPN tunnel). -- Define IPs/subnets in local networks so their traffic is routed outside the VPN tunnel (by default it routes traffic from 192.168.1.81-192.168.1.87 outside the VPN tunnel). -- Define remote IP ranges that are accessed outside the VPN tunnel (by default, LogmeIn Hamachi traffic (25.0.0.0/8) is routed outside the VPN tunnel). -- Creates list of domain names which should be accessed outside the VPN tunnel (useful for Netflix, Hulu, etc). -- Does not reside in RAM -- creates `iptables` rules which are automatically updated on WAN up/down events. -- A companion package (`luci-app-vpnbypass`) is provided so all features may be configured from the Web UI. -- Proudly made in Canada, using locally-sourced electrons. - -## Screenshot (luci-app-vpnbypass) - -![screenshot](https://cdn.jsdelivr.net/gh/stangri/openwrt_packages/screenshots/vpnbypass/screenshot02.png "screenshot") - -## Requirements - -This service requires the following packages to be installed on your router: ```ipset``` and ```iptables```. Additionally, if you want to use the 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 via ssh to your router 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 - -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 - - -Please ensure that the [requirements](#requirements) are satisfied and install ```vpnbypass``` and ```luci-app-vpnbypass``` from the 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 following instructions on [GitHub](https://github.com/stangri/openwrt_packages/blob/master/README.md#on-your-router)/[jsDelivr](https://cdn.jsdelivr.net/gh/stangri/openwrt_packages/README.md#on-your-router) first. - -These packages have been designed to be backwards compatible with OpenWrt 19.07, OpenWrt 18.06, LEDE Project 17.01 and OpenWrt 15.05. However, on systems older than OpenWrt 18.06.6 and/or a system which has deviated too far (or haven't been updated to keep in-sync) with official OpenWrt release you may get a message about missing ```luci-compat``` dependency, which (and only which) you can safely ignore and force-install the luci app using ```opkg install --force-depends``` command instead of ```opkg install```. - -## Default Settings - -The default configuration ships with the service disabled, use the Web UI to enable/start the service or run ```uci set vpnbypass.config.enabled=1; uci commit vpnbypass;```. It routes Plex Media Server traffic (port 32400) and LogmeIn Hamachi traffic (25.0.0.0/8) outside of the VPN tunnel. Internet traffic from local IPs `192.168.1.81-192.168.1.87` is also routed outside the VPN tunnel. You can safely delete these example rules if they do not apply to you. - -## Documentation / Discussion - -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 the following format/syntax: ```/domain1.com/domain2.com/vpnbypass```. Please do not forget the leading ```/``` and trailing ```/vpnbypass```. There is no validation if you enter something incorrectly -- it simply will not work. Please see [Notes/Known Issues](#notesknown-issues) if you wish to edit this setting manually, without using the Web UI. - -## What's New - -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, starts and stops the service. - -## 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 the 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 the [Requirements](#requirements) section for more details. +README has been moved to [https://docs.openwrt.melmac.net/vpnbypass/](https://docs.openwrt.melmac.net/vpnbypass/). diff --git a/net/vpnbypass/files/vpnbypass.conf b/net/vpnbypass/files/vpnbypass.config similarity index 100% rename from net/vpnbypass/files/vpnbypass.conf rename to net/vpnbypass/files/vpnbypass.config diff --git a/net/vpnbypass/files/vpnbypass.init b/net/vpnbypass/files/vpnbypass.init index 241f5543b..03a95ae68 100644 --- a/net/vpnbypass/files/vpnbypass.init +++ b/net/vpnbypass/files/vpnbypass.init @@ -1,6 +1,6 @@ #!/bin/sh /etc/rc.common # Copyright 2017-2020 Stan Grishin (stangri@melmac.net) -# shellcheck disable=SC2039,SC1091,SC2086 +# shellcheck disable=SC2039,SC1091,SC2086,SC3043,SC3057,SC3060 PKG_VERSION='dev-test' # shellcheck disable=SC2034 @@ -8,8 +8,13 @@ START=94 # shellcheck disable=SC2034 USE_PROCD=1 +if type extra_command 1>/dev/null 2>&1; then + extra_command 'version' 'Show version information' +else # shellcheck disable=SC2034 -extra_command "version" "Print version information" + EXTRA_COMMANDS='version' +fi + version() { echo "$PKG_VERSION"; } readonly __ERROR__='\033[0;31mERROR\033[0m' @@ -65,13 +70,13 @@ is_enabled() { [ -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"; + sleep 2; network_flush_cache; sleepCount=$((sleepCount+1)); done [ -n "$wan_gw" ] && return 0 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_ovpn() { local dev i; for i in ifname device; do [ -z "$dev" ] && dev="$(uci -q get "network.${1}.${i}")"; done; 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; } @@ -98,20 +103,20 @@ start_service() { 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; } >/dev/null 2>&1 - ipt -t mangle -A VPNBYPASS -m set --match-set $IPSET dst -j MARK --set-mark ${FW_MARK}/${FW_MASK} >/dev/null 2>&1 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" ip rule add fwmark "$FW_MARK" table "$TID" + ipset -q -exist create "$IPSET" hash:ip; ipset -q flush "$IPSET" { modprobe xt_set; modprobe ip_set; modprobe ip_set_hash_ip; } >/dev/null 2>&1 - for ll in ${ranges}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -s "$ll"; done - 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 + 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; } >/dev/null 2>&1 + ipt -t mangle -A VPNBYPASS -m set --match-set $IPSET dst -j MARK --set-mark ${FW_MARK}/${FW_MASK} >/dev/null 2>&1 + for ll in ${ranges}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -s "$ll"; done + for ll in ${lports}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --sport "${ll//-/:}"; done + for ll in ${routes}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -d "$ll"; done + for ll in ${rports}; do ipt -t mangle -A VPNBYPASS -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" } @@ -127,11 +132,15 @@ stop_service() { service_triggers_load_interface() { is_supported_interface "$1" && ifaces="${ifaces}${1} "; } service_triggers() { - local ifaces n - config_load network; config_foreach service_triggers_load_interface 'interface'; - procd_add_reload_trigger 'firewall' 'openvpn' 'vpnbypass' - procd_open_trigger - 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\\n" - procd_close_trigger + local ifaces n + config_load network; config_foreach service_triggers_load_interface 'interface'; + procd_open_trigger + procd_add_reload_trigger 'openvpn' + if type procd_add_service_trigger 1>/dev/null 2>&1; then + procd_add_service_trigger "service.restart" "firewall" /etc/init.d/${packageName} reload + fi + procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload + 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\\n" + procd_close_trigger } diff --git a/net/vpnbypass/test.sh b/net/vpnbypass/test.sh index e51c48056..45469ed96 100644 --- a/net/vpnbypass/test.sh +++ b/net/vpnbypass/test.sh @@ -1,3 +1,3 @@ #!/bin/sh -/etc/init.d/"$1" version 2>&1 | grep "$2" \ No newline at end of file +/etc/init.d/"$1" version 2>&1 | grep "$2"