From a4c4f316360b6a2bfd73f7e581b65132d75c029b Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Tue, 31 Mar 2020 23:05:35 +0000 Subject: [PATCH] vpn-policy-routing: separation between auto/all proto; compatibility with mwan3; README update Signed-off-by: Stan Grishin --- net/vpn-policy-routing/Makefile | 2 +- net/vpn-policy-routing/files/README.md | 10 ++--- .../files/vpn-policy-routing.init | 43 +++++++++---------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/net/vpn-policy-routing/Makefile b/net/vpn-policy-routing/Makefile index f446529ff..8a77f7a56 100644 --- a/net/vpn-policy-routing/Makefile +++ b/net/vpn-policy-routing/Makefile @@ -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 diff --git a/net/vpn-policy-routing/files/README.md b/net/vpn-policy-routing/files/README.md index f2b8c8f36..84fd6f8af 100644 --- a/net/vpn-policy-routing/files/README.md +++ b/net/vpn-policy-routing/files/README.md @@ -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.
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). diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.init b/net/vpn-policy-routing/files/vpn-policy-routing.init index 06aaa2c28..0d90432e1 100755 --- a/net/vpn-policy-routing/files/vpn-policy-routing.init +++ b/net/vpn-policy-routing/files/vpn-policy-routing.init @@ -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