vpn-policy-routing: separation between auto/all proto; compatibility with mwan3;... 11728/head
authorStan Grishin <stangri@melmac.net>
Tue, 31 Mar 2020 23:05:35 +0000 (23:05 +0000)
committerStan Grishin <stangri@melmac.net>
Tue, 31 Mar 2020 23:05:35 +0000 (23:05 +0000)
Signed-off-by: Stan Grishin <stangri@melmac.net>
net/vpn-policy-routing/Makefile
net/vpn-policy-routing/files/README.md
net/vpn-policy-routing/files/vpn-policy-routing.init

index f446529ffa52c7742e7cc2800186096a7446e9bf..8a77f7a56583ad654a8302002ee1174972706427 100644 (file)
@@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=vpn-policy-routing
 PKG_VERSION:=0.2.1
-PKG_RELEASE:=3
+PKG_RELEASE:=7
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net>
 
index f2b8c8f3653e7d748f7abeafe2af720b0749945c..84fd6f8af96b92b317134bd685c9426d5999c455 100644 (file)
@@ -144,7 +144,7 @@ As per screenshots above, in the Web UI the ```vpn-policy-routing``` configurati
 |Advanced|supported_interface|list/string||Allows to specify the space-separated list of interface names (in lower case) to be explicitly supported by the ```vpn-policy-routing``` service. Can be useful if your OpenVPN tunnels have dev option other than tun\* or tap\*.|
 |Advanced|ignored_interface|list/string||Allows to specify the space-separated list of interface names (in lower case) to be ignored by the ```vpn-policy-routing``` service. Can be useful if running both VPN server and VPN client on the router.|
 |Advanced|boot_timeout|number|30|Allows to specify the time (in seconds) for ```vpn-policy-routing``` service to wait for WAN gateway discovery on boot. Can be useful on devices with ADSL modem built in.|
-|Advanced|iptables_rule_option|append/insert|append|Allows to specify the iptables parameter for rules: ```-A``` for ```append``` and ```-I``` for ```insert```. Append is generally speaking more compatible with other packages/firewall rules. Recommended to change to ```insert``` only to improve compatibility with the ```mwan3``` package.|
+|Advanced|iptables_rule_option|append/insert|append|Allows to specify the iptables parameter for rules: ```-A``` for ```append``` and ```-I``` for ```insert```. Append is generally speaking more compatible with other packages/firewall rules. Recommended to change to ```insert``` only to enable compatibility with the ```mwan3``` package.|
 |Advanced|iprule_enabled|boolean|0|Add an ```ip rule```, not an ```iptables``` entry for policies with just the local address. Use with caution to manipulate policies priorities.|
 |Advanced|icmp_interface|string||Set the default ICMP protocol interface (interface name in lower case). Use with caution.|
 |Advanced|append_src_rules|string||Append local IP Tables rules. Can be used to exclude local IP addresses from destinations for policies with local address set.|
@@ -179,7 +179,7 @@ The ```src_addr```, ```src_port```, ```dest_addr``` and ```dest_port``` options
 |src_port||List of space-separated local/source ports or port-ranges.|
 |dest_addr||List of space-separated remote/target IP addresses, CIDRs or hostnames/domain names.|
 |dest_port||List of space-separated remote/target ports or port-ranges.|
-|proto|all|Policy protocol, can be any valid protocol from ```/etc/protocols``` for CLI/uci or can be selected from the values set in ```webui_supported_protocol```. To display the ```Protocol``` column for policies in the WebUI, make sure to select ```Enabled``` for ```Show Protocol Column``` in the ```Web UI``` tab.|
+|proto|auto|Policy protocol, can be any valid protocol from ```/etc/protocols``` for CLI/uci or can be selected from the values set in ```webui_supported_protocol```. To display the ```Protocol``` column for policies in the WebUI, make sure to select ```Enabled``` for ```Show Protocol Column``` in the ```Web UI``` tab.<br/>Special cases: ```auto``` will try to intelligently insert protocol-agnostic policy and fall back to TCP/UDP if the protocol must be selected for specific policy; ```all``` will always insert a protocol-agnostic policy (which may fail depending on the policy).|
 |chain|PREROUTING|Policy chain, can be either ```PREROUTING```, ```FORWARDING```, ```INPUT``` or ```OUTPUT```. This setting is case-sensitive. To display the ```Chain``` column for policies in the WebUI, make sure to select ```Enabled``` for ```Show Chain Column``` in the ```Web UI``` tab.|
 
 ### Custom User Files Include Options
@@ -482,7 +482,7 @@ config vpn-policy-routing 'config'
 config policy
   option name 'Wireguard Server'
   option interface 'wan'
-  option proto 'tcp'
+  option proto 'udp'
   option src_port '61820'
   option chain 'OUTPUT'
 ```
@@ -810,7 +810,7 @@ If you want to target traffic using HTTP/3 protocol, you can use the ```AUTO```
 
 Some browsers, like [Mozilla Firefox](https://support.mozilla.org/en-US/kb/firefox-dns-over-https#w_about-dns-over-https) or [Google Chrome/Chromium](https://blog.chromium.org/2019/09/experimenting-with-same-provider-dns.html) have [DNS-over-HTTPS proxy](https://en.wikipedia.org/wiki/DNS_over_HTTPS) built-in. Their requests to web-sites cannot be affected if the ```dnsmasq.ipset``` is set for the ```dest_ipset``` option. To fix this, you can try either of the following:
 
-  1. Disable the DNS-over-HTTPS support in your browser and use the OpenWrt's [net/https-dns-proxy](https://github.com/openwrt/packages/tree/master/net/https-dns-proxy) package and set it up either [manually](https://openwrt.org/docs/guide-user/services/dns/doh_dnsmasq_https-dns-proxy?s[]=https&s[]=dns&s[]=proxy) or auto-magically with [https-dns-proxy luci app](https://github.com/openwrt/luci/tree/master/applications/luci-app-https_dns_proxy). You can then continue to use ```dnsmasq.ipset``` setting for the ```dest_ipset``` in VPN Policy Routing.
+  1. Disable the DNS-over-HTTPS support in your browser and use the OpenWrt's [net/https-dns-proxy](https://github.com/openwrt/packages/tree/master/net/https-dns-proxy) package with optional [https-dns-proxy luci app](https://github.com/openwrt/luci/tree/master/applications/luci-app-https_dns_proxy). You can then continue to use ```dnsmasq.ipset``` setting for the ```dest_ipset``` in VPN Policy Routing.
 
   2. Continue using DNS-over-HTTPS in your browser (which, by the way, also limits your options for router-level AdBlocking as described [in ```dnsmasq.ipset``` option description here](https://github.com/openwrt/packages/tree/master/net/simple-adblock/files#dns-resolution-option)), you than would either have to disable the  ```dest_ipset``` or switch it to ```ipset```. Please note, you will lose all the benefits of [```dnsmasq.ipset```](#use-dnsmasq-ipset) option.
 
@@ -843,4 +843,4 @@ WARNING: while paste.ee uploads are unlisted/not indexed at the web-site, they a
 
 ## Thanks
 
-I'd like to thank everyone who helped create, test and troubleshoot this service. Without contributions from [@hnyman](https://github.com/hnyman), [@dibdot](https://github.com/dibdot), [@danrl](https://github.com/danrl), [@tohojo](https://github.com/tohojo), [@cybrnook](https://github.com/cybrnook), [@nidstigator](https://github.com/nidstigator), [@AndreBL](https://github.com/AndreBL) and [@dz0ny](https://github.com/dz0ny) and rigorous testing/bugreporting by [@dziny](https://github.com/dziny), [@bluenote73](https://github.com/bluenote73), [@buckaroo](https://github.com/pgera), [@Alexander-r](https://github.com/Alexander-r), [n8v8R](https://github.com/n8v8R) and [psherman](https://forum.openwrt.org/u/psherman) it wouldn't have been possible. Wireguard/IPv6 support is courtesy of [Mullvad](https://www.mullvad.net), [IVPN](https://www.ivpn.net/) and [WireVPN](https://www.wirevpn.net).
+I'd like to thank everyone who helped create, test and troubleshoot this service. Without contributions from [@hnyman](https://github.com/hnyman), [@dibdot](https://github.com/dibdot), [@danrl](https://github.com/danrl), [@tohojo](https://github.com/tohojo), [@cybrnook](https://github.com/cybrnook), [@nidstigator](https://github.com/nidstigator), [@AndreBL](https://github.com/AndreBL), [@dz0ny](https://github.com/dz0ny), rigorous testing/bugreporting by [@dziny](https://github.com/dziny), [@bluenote73](https://github.com/bluenote73), [@buckaroo](https://github.com/pgera), [@Alexander-r](https://github.com/Alexander-r), [n8v8R](https://github.com/n8v8R), [psherman](https://forum.openwrt.org/u/psherman), multiple contributions from [dl12345](https://github.com/dl12345), [trendy](https://forum.openwrt.org/u/trendy) and feedback from other OpenWrt users it wouldn't have been possible. Wireguard/IPv6 support is courtesy of [Mullvad](https://www.mullvad.net), [IVPN](https://www.ivpn.net/) and [WireVPN](https://www.wirevpn.net).
index 06aaa2c28ecf46f06454cf44adddea9474d30737..0d90432e1744394418391a5d0350f1706c14ea60 100755 (executable)
@@ -1,7 +1,6 @@
 #!/bin/sh /etc/rc.common
 # Copyright 2017-2019 Stan Grishin (stangri@melmac.net)
-# shellcheck disable=SC2039
-# shellcheck disable=SC1091
+# shellcheck disable=SC2039,SC1091,SC2018,SC2019
 PKG_VERSION='dev-test'
 
 export START=94
@@ -40,6 +39,9 @@ output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; }
 # str_contains() { [ "$1" != "$(str_replace "$1" "$2" "")" ]; }
 # shellcheck disable=SC2018,SC2019
 str_to_lower() { echo "$1" | tr 'A-Z' 'a-z'; }
+str_extras_to_underscore() { echo "$1" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_'; }
+str_extras_to_space() { echo "$1" | tr ';{}' ' '; }
+
 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
@@ -272,7 +274,7 @@ ips() {
        else
                if [[ -z "$appendix" && -z "$remoteIpset" ]] || \
                         [[ -n "$appendix" && "$localIpset" -eq 0 ]]; then
-                       return 1
+                       return 1
                fi
        fi
 
@@ -316,7 +318,7 @@ insert_tor_policy() {
        [ -n "$lport" ] && param="$param -p tcp -m multiport --sport ${lport//-/:}"
        [ -n "$raddr" ] && param="$param -d $raddr"
        [ -n "$rport" ] && param="$param -p $proto -m multiport --dport ${rport//-/:}"
-       [ -n "$comment" ] && param="$param -m comment --comment $(echo "$comment" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_')"
+       [ -n "$comment" ] && param="$param -m comment --comment $(str_extras_to_underscore "$comment")"
 # Here be dragons
        return 0
 }
@@ -334,15 +336,11 @@ insert_policy() {
                return 0
        fi
 
-       if [ -z "$proto" ] || [ "$proto" = 'all' ]; then
-               if [ -z "${lport}${raddr}${rport}" ] && [ -n "$laddr" ]; then
-                       proto='all'
-               elif [ -z "${laddr}${lport}${rport}" ] && [ -n "$raddr" ]; then
-                       proto='all'
-               elif [ -n "$lport" ] || [ -n "$rport" ]; then 
+       if [ -z "$proto" ]; then
+               if [ -n "$lport" ] || [ -n "$rport" ]; then 
                        proto='tcp udp'
                else
-                       proto='tcp'
+                       proto='all'
                fi
        fi
 
@@ -406,7 +404,7 @@ insert_policy() {
                        param="$param -m multiport $valueNeg --dport ${value//-/:}"
                fi
 
-               [ -n "$comment" ] && param="$param -m comment --comment $(echo "$comment" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_')"
+               [ -n "$comment" ] && param="$param -m comment --comment $(str_extras_to_underscore "$comment")"
                ipt "$param" || processPolicyError="${processPolicyError}${_ERROR_}: iptables $param\\n"
        done
        return 0
@@ -415,16 +413,16 @@ insert_policy() {
 r_process_policy(){
        local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto="$7" chain="$8" resolved_laddr resolved_raddr i ipsFailFlag
        if [ "${laddr//[ ;\{\}]/}" != "$laddr" ]; then
-               for i in $(echo "$laddr" | tr ';{}' ' '); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done
+               for i in $(str_extras_to_space "$laddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done
                return 0
        elif [ "${lport//[ ;\{\}]/}" != "$lport" ]; then
-               for i in $(echo "$lport" | tr ';{}' ' '); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$i" "$raddr" "$rport" "$proto" "$chain"; done
+               for i in $(str_extras_to_space "$lport"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$i" "$raddr" "$rport" "$proto" "$chain"; done
                return 0
        elif [ "${raddr//[ ;\{\}]/}" != "$raddr" ]; then
-               for i in $(echo "$raddr" | tr ';{}' ' '); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$i" "$rport" "$proto" "$chain"; done
+               for i in $(str_extras_to_space "$raddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$i" "$rport" "$proto" "$chain"; done
                return 0
        elif [ "${rport//[ ;\{\}]/}" != "$rport" ]; then
-               for i in $(echo "$rport" | tr ';{}' ' '); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$i" "$proto" "$chain"; done
+               for i in $(str_extras_to_space "$rport"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$i" "$proto" "$chain"; done
                return 0
        fi
 
@@ -495,8 +493,8 @@ process_policy(){
        config_get_bool enabled "$1" 'enabled' 1
 
        [ "$enabled" -gt 0 ] || return 0
+       proto="$(str_to_lower "$proto")"
        [ "$proto" = 'auto' ] && unset proto
-       [ "$proto" = 'AUTO' ] && unset proto
 
        comment="${comment:-$name}"
        output 2 "Routing '$comment' via $iface "
@@ -504,7 +502,7 @@ process_policy(){
        if [ -z "$comment" ]; then
                errorSummary="${errorSummary}${_ERROR_}: Policy name is empty\\n"
                output_fail; return 1;
-       fi
+       fi
        if [ -z "${laddr}${lport}${raddr}${rport}" ]; then
                errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' missing all IPs/ports\\n"
                output_fail; return 1;
@@ -575,7 +573,7 @@ table_create(){
                        fi
                done
                ip -4 route flush cache || ipv4_error=1
-               ip -4 rule add fwmark "$mark" table "$tid" || ipv4_error=1
+               ip -4 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1
        fi
 
        if [ "$ipv6Enabled" -ne 0 ]; then
@@ -588,7 +586,7 @@ table_create(){
                                done
                        fi
                        ip -6 route flush cache || ipv6_error=1
-                       ip -6 rule add fwmark "$mark" table "$tid" || ipv6_error=1
+                       ip -6 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv6_error=1
                fi
        fi
 
@@ -778,7 +776,7 @@ start_service() {
                done
 
                if [ "$modprobeStatus" -gt 0 ] && ! is_chaos_calmer; then
-                       errorSummary="${errorSummary}${_ERROR_}: Failed to load kernel modules\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: Failed to load kernel modules\\n"
                fi
 
                for i in PREROUTING FORWARD INPUT OUTPUT; do
@@ -806,7 +804,7 @@ start_service() {
                [ "$dnsmasqNewHash" != "$dnsmasqStoredHash" ] && dnsmasq_restart
 
                if [ -z "$gatewaySummary" ]; then
-                       errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway\\n"
                else
                        output "$serviceName started with gateways:\\n${gatewaySummary}"
                        [ -n "$errorSummary" ] && output "${errorSummary}"
@@ -886,6 +884,7 @@ service_triggers() {
 }
 
 input() { local data; while read -r data; do echo "$data" | tee -a /var/${packageName}-support; done; }
+status_service() { support "$@"; }
 support() {
        local dist vers out id s param status set_d set_p tableCount i=0 dev dev6
        is_enabled