From 03606eddee2c25b59d31a218534dab9e09539c05 Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Sat, 25 Jan 2020 21:14:38 -0700 Subject: [PATCH] https-dns-proxy: fix deleting server items, configurable dnsmasq settings change Signed-off-by: Stan Grishin --- net/https-dns-proxy/Makefile | 2 +- net/https-dns-proxy/files/README.md | 94 +++++++++++++++++++ .../files/https-dns-proxy.config | 7 +- .../files/https-dns-proxy.init | 91 ++++++++++-------- 4 files changed, 152 insertions(+), 42 deletions(-) create mode 100644 net/https-dns-proxy/files/README.md diff --git a/net/https-dns-proxy/Makefile b/net/https-dns-proxy/Makefile index 374f8fe69c..7e3d0a5ba5 100644 --- a/net/https-dns-proxy/Makefile +++ b/net/https-dns-proxy/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=https-dns-proxy PKG_VERSION:=2019-12-03 -PKG_RELEASE=2 +PKG_RELEASE=3 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy diff --git a/net/https-dns-proxy/files/README.md b/net/https-dns-proxy/files/README.md new file mode 100644 index 0000000000..d844399bb7 --- /dev/null +++ b/net/https-dns-proxy/files/README.md @@ -0,0 +1,94 @@ +# DNS Over HTTPS Proxy (https-dns-proxy) + +A lean RFC8484-compatible (no JSON API support) DNS-over-HTTPS (DoH) proxy service which supports DoH servers ran by AdGuard, CleanBrowsing, Cloudflare, Google, ODVR (nic.cz) and Quad9. Please see the [README](https://github.com/stangri/openwrt_packages/blob/master/https-dns-proxy/files/README.md) for further information. Based on [@aarond10](https://github.com/aarond10)'s [https-dns-proxy](https://github.com/aarond10/https_dns_proxy). + +## Features + +- [RFC8484](https://tools.ietf.org/html/rfc8484)-compatible DoH Proxy. +- Compact size. +- Web UI (```luci-app-https-dns-proxy```) available. +- (By default) automatically updates DNSMASQ settings to use DoH proxy when it's started and reverts to old DNSMASQ resolvers when DoH proxy is stopped. + +## Screenshots (luci-app-https-dns-proxy) + +![screenshot](https://raw.githubusercontent.com/stangri/openwrt_packages/master/screenshots/https-dns-proxy/screenshot01.png "https-dns-proxy screenshot") + +## Requirements + +This proxy requires the following packages to be installed on your router: ```libc```, ```libcares```, ```libcurl```, ```libev```, ```ca-bundle```. They will be automatically installed when you're installing ```https-dns-proxy```. + +## 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 + +Install ```https-dns-proxy``` and ```luci-app-https-dns-proxy``` packages from Web UI or run the following in the command line: + +```sh +opkg update; opkg install https-dns-proxy luci-app-https-dns-proxy; +``` + +## Default Settings + +Default configuration has service enabled and starts the service with Google and Cloudflare DoH servers. In most configurations, you will keep the default ```DNSMASQ``` service installed to handle requests from devices in your local network and point ```DNSMASQ``` to use ```https-dns-proxy``` for name resolution. + +By default, the service will intelligently override existing ```DNSMASQ``` servers settings on start to use the DoH servers and restores original ```DNSMASQ``` servers on stop. See the [Configuration Settings](#configuration-settings) section below for more information and how to disable this behavior. + +## Configuration Settings + +Configuration contains the (named) "main" config section where you can configure which ```DNSMASQ``` settings the service will automatically affect and the typed (unnamed) https-dns-proxy instance settings. The original config file is included below: + +```text +config main 'config' + option update_dnsmasq_config '*' + +config https-dns-proxy + option bootstrap_dns '8.8.8.8,8.8.4.4' + option resolver_url 'https://dns.google/dns-query' + option listen_addr '127.0.0.1' + option listen_port '5053' + option user 'nobody' + option group 'nogroup' + +config https-dns-proxy + option bootstrap_dns '1.1.1.1,1.0.0.1' + option resolver_url 'https://cloudflare-dns.com/dns-query' + option listen_addr '127.0.0.1' + option listen_port '5054' + option user 'nobody' + option group 'nogroup'``` +``` + +The ```update_dnsmasq_config``` option can be set to dash (set to ```'-'``` to not change ```DNSMASQ``` server settings on start/stop), can be set to ```'*'``` to affect all ```DNSMASQ``` instance server settings or have a space-separated list of ```DNSMASQ``` instances to affect (like ```'0 4 5'```). If this option is omitted, the default setting is ```'*'```. + +Starting with ```https-dns-proxy``` version ```2019-12-03-3``` and higher, when the service is set to update the DNSMASQ servers setting on start/stop, it does not override entries which contain either ```#``` or ```/```, so the entries like listed below will be kept in use: + +```test + list server '/onion/127.0.0.1#65453' + list server '/openwrt.org/8.8.8.8' + list server '/pool.ntp.org/8.8.8.8' + list server '127.0.0.1#15353' + list server '127.0.0.1#55353' + list server '127.0.0.1#65353' +``` + +The https-dns-proxy instance settings are: + +|Parameter|Type|Default|Description| +| --- | --- | --- | --- | +|bootstrap_dns|IP Address||The non-encrypted DNS servers to be used to resolve the DoH server name on start.| +|edns_subnet|Subnet||EDNS Subnet address can be supplied to supported DoH servers to provide local resolution results.| +|listen_addr|IP Address|127.0.0.1|The local IP address to listen to requests.| +|listen_port|port|5053 and up|If this setting is omitted, the service will start the first https-dns-proxy instance on port 5053, second on 5054 and so on.| +|logfile|Full filepath||Full filepath to the file to log the instance events to.| +|resolver_url|URL||The https URL to the RFC8484-compatible resolver.| +|proxy_server|URL||Local proxy server to use when accessing resolvers.| +|user|String|nobody|Local user to run instance under.| +|group|String|nogroup|Local group to run instance under.| +|use_http1|Boolean|0|If set to 1, use HTTP/1 on installations with broken/outdated ```curl``` package. Included for posterity reasons, you will most likely not ever need it on OpenWrt.| +|verbosity|Integer||Use setting between 1 to 4 to control the logging verbosity level.|String + +## Thanks + +This OpenWrt package wouldn't have been possible without [@aarond10](https://github.com/aarond10)'s [https-dns-proxy](https://github.com/aarond10/https_dns_proxy) and his active participation in the OpenWrt package itself. Special thanks to [@jow-](https://github.com/jow-) for general package/luci guidance. diff --git a/net/https-dns-proxy/files/https-dns-proxy.config b/net/https-dns-proxy/files/https-dns-proxy.config index 3b4441fe1c..3c5eecf4d1 100644 --- a/net/https-dns-proxy/files/https-dns-proxy.config +++ b/net/https-dns-proxy/files/https-dns-proxy.config @@ -1,3 +1,6 @@ +config main 'config' + option update_dnsmasq_config '*' + config https-dns-proxy option bootstrap_dns '8.8.8.8,8.8.4.4' option resolver_url 'https://dns.google/dns-query' @@ -5,8 +8,6 @@ config https-dns-proxy option listen_port '5053' option user 'nobody' option group 'nogroup' - option ipv4_resolvers '1' - option verbosity '0' # fatal = 0, error = 1, warning = 2, info = 3, debug = 4 config https-dns-proxy option bootstrap_dns '1.1.1.1,1.0.0.1' @@ -15,5 +16,3 @@ config https-dns-proxy option listen_port '5054' option user 'nobody' option group 'nogroup' - option ipv4_resolvers '1' - option verbosity '0' # fatal = 0, error = 1, warning = 2, info = 3, debug = 4 diff --git a/net/https-dns-proxy/files/https-dns-proxy.init b/net/https-dns-proxy/files/https-dns-proxy.init index e56eb8a821..0767da9353 100755 --- a/net/https-dns-proxy/files/https-dns-proxy.init +++ b/net/https-dns-proxy/files/https-dns-proxy.init @@ -5,6 +5,8 @@ export START=80 export USE_PROCD=1 +dnsmasqConfig='' + PROG=/usr/sbin/https-dns-proxy xappend() { param="$param $1"; } @@ -31,8 +33,18 @@ append_parm() { xappend "$switch $_loctmp" } +append_match() { + local section="$1" + local option="$2" + local value="$3" + local match="$4" + local _loctmp + config_get_bool _loctmp "$section" "$option" + [ "$_loctmp" = "$match" ] && xappend "$value" +} + start_instance() { - local cfg="$1" param listen_addr listen_port + local cfg="$1" param listen_addr listen_port i append_parm "$cfg" 'listen_addr' '-a' '127.0.0.1' append_parm "$cfg" 'listen_port' '-p' "$p" @@ -44,37 +56,27 @@ start_instance() { append_parm "$cfg" 'proxy_server' '-t' append_parm "$cfg" 'logfile' '-l' append_bool "$cfg" 'use_http1' '-x' - append_bool "$cfg" 'ipv4_resolvers' '-4' - - config_get verbosity "$cfg" 'verbosity' "0" - for i in $(seq 1 $verbosity); do - xappend "-v" - done + append_match "$cfg" 'verbosity' '-v' '1' + append_match "$cfg" 'verbosity' '-vv' '2' + append_match "$cfg" 'verbosity' '-vvv' '3' + append_match "$cfg" 'verbosity' '-vvvv' '4' procd_open_instance # shellcheck disable=SC2086 - procd_set_param command ${PROG} ${param} - procd_set_param stderr 1 - procd_set_param stdout 1 + procd_set_param command ${PROG} -4 ${param} procd_set_param respawn procd_close_instance config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1' config_get listen_port "$cfg" 'listen_port' "$p" - - # Don't add the any address to dnsmasq - case $listen_addr in - 0.0.0.0|::ffff:0.0.0.0) - listen_addr='127.0.0.1' - ;; - ::) - listen_addr='::1' - ;; - esac - - config_load 'dhcp' -# shellcheck disable=SC2154 - config_foreach dnsmasq_add_doh_server 'dnsmasq' "${listen_addr}#${listen_port}" + if [ "$dnsmasqConfig" = "*" ]; then + config_load 'dhcp' + config_foreach dnsmasq_add_doh_server 'dnsmasq' "${listen_addr}#${listen_port}" + elif [ -n "$dnsmasqConfig" ]; then + for i in $dnsmasqConfig; do + dnsmasq_add_doh_server "@dnsmasq[${i}]" "${listen_addr}#${listen_port}" + done + fi p="$((p+1))" } @@ -84,12 +86,11 @@ service_triggers() { start_service() { local p=5053 + config_load 'https-dns-proxy' + config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*' dhcp_backup 'create' config_load 'https-dns-proxy' config_foreach start_instance 'https-dns-proxy' - if [ -z "$(uci -q get dhcp.@dnsmasq[0].server)" ]; then - dhcp_backup 'restore' - fi if [ -n "$(uci -q changes dhcp)" ]; then uci -q commit dhcp [ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1 @@ -97,6 +98,8 @@ start_service() { } stop_service() { + config_load 'https-dns-proxy' + config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*' dhcp_backup 'restore' if [ -n "$(uci -q changes dhcp)" ]; then uci -q commit dhcp @@ -110,35 +113,49 @@ service_triggers() { dnsmasq_add_doh_server() { local cfg="$1" value="$2" + uci -q del_list dhcp."$cfg".server="$value" uci -q add_list dhcp."$cfg".server="$value" } dnsmasq_create_server_backup() { - local cfg="$1" i - if ! uci -q get "dhcp.$cfg.doh_backup_server" >/dev/null; then - for i in $(uci -q get "dhcp.$cfg.server"); do - uci -q add_list dhcp."$cfg".doh_backup_server="$i" - done - fi - uci -q del "dhcp.$cfg.server" + local cfg="$1" + local i + uci -q get "dhcp.$cfg.doh_backup_server" >/dev/null && return 0 + for i in $(uci -q get "dhcp.$cfg.server"); do + uci -q add_list dhcp."$cfg".doh_backup_server="$i" + if [ "$i" = "${i//127.0.0.1}" ] && [ "$i" = "$(echo "$i" | tr -d /)" ]; then + uci -q del_list dhcp."$cfg".server="$i" + fi + done } dnsmasq_restore_server_backup() { - local cfg="$1" i + local cfg="$1" + local i if uci -q get "dhcp.$cfg.doh_backup_server" >/dev/null; then uci -q del "dhcp.$cfg.server" for i in $(uci -q get "dhcp.$cfg.doh_backup_server"); do uci -q add_list dhcp."$cfg".server="$i" done + uci -q del "dhcp.$cfg.doh_backup_server" fi } dhcp_backup() { + local i config_load 'dhcp' case "$1" in create) - config_foreach dnsmasq_create_server_backup 'dnsmasq';; + if [ "$dnsmasqConfig" = "*" ]; then + config_foreach dnsmasq_create_server_backup 'dnsmasq' + elif [ -n "$dnsmasqConfig" ]; then + for i in $dnsmasqConfig; do + dnsmasq_create_server_backup "@dnsmasq[${i}]" + done + fi + ;; restore) - config_foreach dnsmasq_restore_server_backup 'dnsmasq';; + config_foreach dnsmasq_restore_server_backup 'dnsmasq' + ;; esac } -- 2.30.2