From: RISCi_ATOM Date: Wed, 27 Nov 2019 00:13:39 +0000 (-0500) Subject: Add darkstat and stubby : issue libreCMC/#101 Package-feed/#8 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=51617337bcc4eb78f8f2c4543374a9c112c003fe;p=librecmc%2Fpackage-feed.git Add darkstat and stubby : issue libreCMC/#101 Package-feed/#8 --- diff --git a/libs/getdns/Config.in b/libs/getdns/Config.in new file mode 100644 index 0000000..f6658d4 --- /dev/null +++ b/libs/getdns/Config.in @@ -0,0 +1,16 @@ +menu "Configuration" + depends on PACKAGE_getdns + +config GETDNS_ENABLE_STUB_ONLY + bool "GETDNS_ENABLE_STUB_ONLY" + help + getdns can be configured for stub resolution mode only. (Removes libunbound dependency) + default y + +config GETDNS_ENABLE_IDN_LIBIDN2 + bool "GETDNS_ENABLE_IDN_LIBIDN2" + help + getdns can be configured with some IDN Support. (Requires libidn2 dependency) + default n + +endmenu diff --git a/libs/getdns/Makefile b/libs/getdns/Makefile new file mode 100644 index 0000000..b26be3c --- /dev/null +++ b/libs/getdns/Makefile @@ -0,0 +1,80 @@ +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=getdns +PKG_VERSION:=1.5.2 +PKG_RELEASE:=2 + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Jonathan Underwood + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://getdnsapi.net/dist/ +PKG_HASH:=1826a6a221ea9e9301f2c1f5d25f6f5588e841f08b967645bf50c53b970694c0 + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +PKG_CONFIG_DEPENDS:= \ + CONFIG_GETDNS_ENABLE_STUB_ONLY \ + CONFIG_GETDNS_ENABLE_IDN_LIBIDN2 + +include $(INCLUDE_DIR)/package.mk + +define Package/getdns/Default + TITLE:=getdns + URL:=https://getdnsapi.net/ +endef + +define Package/getdns + $(call Package/getdns/Default) + SECTION:=libs + CATEGORY:=Libraries + TITLE+= (library) + DEPENDS+= +libopenssl +!GETDNS_ENABLE_STUB_ONLY:libunbound +GETDNS_ENABLE_IDN_LIBIDN2:libidn2 + MENU:=1 +endef + +define Package/getdns/description + This package contains the getdns library (libgetdns). + This package also contains the "getdns_query" command line wrapper for getdns exposing the features of this implementation (both in the official API and the additional API functions). +endef + +define Package/getdns/config + source "$(SOURCE)/Config.in" +endef + +CONFIGURE_ARGS += \ + $(if $(CONFIG_GETDNS_ENABLE_STUB_ONLY), --enable-stub-only, ) \ + --without-libidn \ + $(if $(CONFIG_GETDNS_ENABLE_IDN_LIBIDN2), , --without-libidn2 ) \ + --with-ssl="$(STAGING_DIR)/usr" \ + +# This will make 'configure' think that our libbsd.so is missing the +# functions inet_pton, inet_ntop, strlcpy and use the builtin. This +# removes the libbsd dependency +CONFIGURE_VARS += LIBBSD_LIBS=-lc + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/getdns/ + $(CP) $(PKG_INSTALL_DIR)/usr/include/getdns/getdns*.h $(1)/usr/include/getdns/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgetdns*.{a,so*} $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/getdns*.pc $(1)/usr/lib/pkgconfig/ +endef + + +define Package/getdns/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgetdns.so.* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/getdns_query $(1)/usr/sbin/getdns_query +endef + +$(eval $(call BuildPackage,getdns)) diff --git a/libs/yaml/Makefile b/libs/yaml/Makefile new file mode 100644 index 0000000..a01109d --- /dev/null +++ b/libs/yaml/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2008-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=yaml +PKG_VERSION:=0.2.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://pyyaml.org/download/libyaml/ +PKG_HASH:=4a9100ab61047fd9bd395bcef3ce5403365cafd55c1e0d0299cde14958e47be9 + +PKG_MAINTAINER:= +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=COPYING +PKG_CPE_ID:=cpe:/a:pyyaml_project:pyyaml + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/libyaml + SUBMENU:=Languages + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Fast YAML 1.1 parser and emitter library + URL:=https://pyyaml.org/wiki/LibYAML +endef + +TARGET_CFLAGS += $(FPIC) + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/yaml.h $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libyaml*.{a,so*} $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/yaml*.pc $(1)/usr/lib/pkgconfig/ +endef + +define Package/libyaml/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libyaml*.so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libyaml)) diff --git a/net/darkstat/Makefile b/net/darkstat/Makefile new file mode 100644 index 0000000..f7c8508 --- /dev/null +++ b/net/darkstat/Makefile @@ -0,0 +1,67 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=darkstat +PKG_VERSION:=3.0.719 +PKG_RELEASE:=4 + +PKG_MAINTAINER:=Jean-Michel Lacroix + +PKG_LICENSE:=GPL-2.0 BSD-ISC +PKG_LICENSE_FILES:=COPYING.GPL LICENSE + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://unix4lyfe.org/darkstat +PKG_HASH:=aeaf909585f7f43dc032a75328fdb62114e58405b06a92a13c0d3653236dedd7 + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/darkstat + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libpcap +zlib + TITLE:=Network bandwidth monitor + URL:=http://unix4lyfe.org/darkstat/ +endef + +define Package/darkstat/description +darkstat is a packet sniffer that runs as a background process on a cable/DSL +router, gathers all sorts of statistics about network usage, and serves them +over HTTP. +endef + +define Package/darkstat/conffiles +/etc/config/darkstat +endef + +CONFIGURE_ARGS += \ + --disable-debug \ + --with-chroot-dir=/var/empty + +CONFIGURE_VARS += \ + ac_cv_search_setproctitle=no \ + ac_cv_search_strlcpy=no \ + ac_cv_search_strlcat=no + +define Build/Compile + $(HOSTCC) $(PKG_BUILD_DIR)/static/c-ify.c \ + -o $(PKG_BUILD_DIR)/c-ify + $(call Build/Compile/Default) +endef + +define Package/darkstat/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/darkstat $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/darkstat.init $(1)/etc/init.d/darkstat + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/darkstat.config $(1)/etc/config/darkstat +endef + +$(eval $(call BuildPackage,darkstat)) diff --git a/net/darkstat/files/darkstat.config b/net/darkstat/files/darkstat.config new file mode 100644 index 0000000..ebe5718 --- /dev/null +++ b/net/darkstat/files/darkstat.config @@ -0,0 +1,21 @@ +config darkstat + option interface 'lan' + option syslog false + option verbose false + option no_promisc false + option no_dns false + option no_macs false + option no_lastseen false + option httpaddr '0.0.0.0' +# option httpport '667' +# option network_filter 'not (src net 192.168.1 and dst net 192.168.1)' +# option network_netmask '192.168.1.0/255.255.255.0' + option local_only false +# option hosts_max '1000' +# option hosts_keep '500' +# option ports_max '60' +# option ports_keep '30' +# option highest_port '65534' +# option export_file 'darkstat_export.log' +# option import_file 'darkstat_export.log' +# option daylog_file 'darkstat_daylog.log' diff --git a/net/darkstat/files/darkstat.init b/net/darkstat/files/darkstat.init new file mode 100755 index 0000000..4cd8b3e --- /dev/null +++ b/net/darkstat/files/darkstat.init @@ -0,0 +1,100 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2018 Jean-Michel Lacroix + +USE_PROCD=1 + +START=60 + +APP=darkstat +RUN_D=/var/empty +PID_F=$RUN_D/$APP.pid +CONFIGNAME=darkstat +USER=nobody +GROUP=nogroup + +CONFIGSTR="" +FILTERSTR="" + +export_bool () { + local option="$1" + local section="$2" + local _keystr="$3" + local _loctmp + config_get_bool _loctmp "$section" "$option" + if [ -n "$_loctmp" ]; then + if [ 1 -eq "$_loctmp" ]; then + CONFIGSTR="$CONFIGSTR${_keystr} " + fi + fi +} + +set_config_string(){ + mkdir -p $RUN_D + chown $USER:$GROUP $RUN_D + . /lib/functions/network.sh + config_load $CONFIGNAME + config_foreach build_config_string darkstat +} + +build_config_string() { + local cfg="$1" + config_get interface $cfg interface + network_get_device ifname "$interface" + CONFIGSTR=" -i $ifname " + export_bool syslog $cfg "--syslog" + export_bool verbose $cfg "--verbose" + # We need the --no-daemon parameter as with PROCD the process has to run in the background + CONFIGSTR="$CONFIGSTR--no-daemon " + export_bool no_promisc $cfg "--no-promisc" + export_bool no_dns $cfg "--no-dns" + export_bool no_macs $cfg "--no-macs" + export_bool no_lastseen $cfg "--no-lastseen" + config_get httpaddr $cfg httpaddr + CONFIGSTR="$CONFIGSTR${httpaddr:+-b "$httpaddr"} " + config_get httpport $cfg httpport + CONFIGSTR="$CONFIGSTR${httpport:+-p "$httpport"} " + config_get network_netmask $cfg network_netmask + CONFIGSTR="$CONFIGSTR${network_netmask:+-l "$network_netmask"} " + export_bool local_only $cfg "--local-only" + config_get hosts_max $cfg hosts_max + CONFIGSTR="$CONFIGSTR${hosts_max:+--hosts-max "$hosts_max"} " + config_get hosts_keep $cfg hosts_keep + CONFIGSTR="$CONFIGSTR${ports_keep:+--ports-keep "$ports_keep"} " + config_get highest_port $cfg highest_port + CONFIGSTR="$CONFIGSTR${highest_port:+--highest-port "$highest_port"} " + config_get export_file $cfg export_file + CONFIGSTR="$CONFIGSTR${export_file:+--export "$export_file"} " + config_get import_file $cfg import_file + CONFIGSTR="$CONFIGSTR${import_file:+--import "$import_file"} " + config_get daylog_file $cfg daylog_file + CONFIGSTR="$CONFIGSTR${daylog_file:+--daylog "$daylog_file"} " + CONFIGSTR="$CONFIGSTR--chroot $RUN_D --pidfile $PID_F" + # Now that we have the configuration string (CONFIGSTR), let us get the filter (FILTERSTR) + config_get network_filter $cfg network_filter + FILTERSTR="${network_filter:+$network_filter}" +} + +service_triggers() { + procd_add_reload_trigger $CONFIGNAME +} + +start_service() { + set_config_string + procd_open_instance + procd_set_param command /usr/sbin/$APP + procd_append_param command $CONFIGSTR + # Let us check if we have a filter string and apply it if we do + if [ "$FILTERSTR" != "" ]; then + procd_append_param command "-f" "$FILTERSTR" + fi + procd_close_instance +} + +stop_service() { + rm -f $PID_F +} + +reload_service() { + stop + start +} diff --git a/net/darkstat/patches/100-do-not-use-NI_IDN.patch b/net/darkstat/patches/100-do-not-use-NI_IDN.patch new file mode 100644 index 0000000..7f7eecd --- /dev/null +++ b/net/darkstat/patches/100-do-not-use-NI_IDN.patch @@ -0,0 +1,12 @@ +--- a/dns.c ++++ b/dns.c +@@ -347,9 +347,6 @@ dns_main(void) + + reply.addr = ip; + flags = NI_NAMEREQD; +-# ifdef NI_IDN +- flags |= NI_IDN; +-# endif + switch (ip.family) { + case IPv4: + sin.sin_family = AF_INET; diff --git a/net/stubby/Makefile b/net/stubby/Makefile new file mode 100644 index 0000000..20e60ad --- /dev/null +++ b/net/stubby/Makefile @@ -0,0 +1,69 @@ +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=stubby +PKG_VERSION:=0.2.6 +PKG_RELEASE:=1 + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Jonathan Underwood + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/getdnsapi/$(PKG_NAME) +PKG_SOURCE_VERSION:=v$(PKG_VERSION) +PKG_MIRROR_HASH:=af896c471ac67b31c2263d11fcdfcdb32a213621c2f8789f4b0a4ceca4437108 + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/stubby/Default + TITLE:=stubby + URL:=https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby +endef + +define Package/stubby + $(call Package/stubby/Default) + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE+= - (daemon that uses getdns) + USERID:=stubby=410:stubby=410 + DEPENDS:= +libyaml +getdns +ca-certificates +endef + +define Package/stubby/description + This package contains the Stubby daemon (which utilizes the getdns library). + + See https://github.com/openwrt/packages/blob/master/net/stubby/files/README.md for more details. +endef + +define Package/stubby/conffiles +/etc/stubby/stubby.yml +endef + +define Package/stubby/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/stubby $(1)/usr/sbin/stubby + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/stubby.init $(1)/etc/init.d/stubby + $(INSTALL_DIR) $(1)/etc/stubby + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/stubby/stubby.yml $(1)/etc/stubby/stubby.yml.default + $(INSTALL_DATA) ./files/stubby.yml $(1)/etc/stubby/stubby.yml + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/stubby.conf $(1)/etc/config/stubby +endef + + +define Package/stubby/conffiles + /etc/stubby/stubby.yml + /etc/config/stubby +endef + +$(eval $(call BuildPackage,stubby)) diff --git a/net/stubby/files/README.md b/net/stubby/files/README.md new file mode 100644 index 0000000..12fcef3 --- /dev/null +++ b/net/stubby/files/README.md @@ -0,0 +1,454 @@ + +# Stubby for OpenWRT + +## Stubby Description + +[Stubby](https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby) is +an application that acts as a local DNS Privacy stub resolver (using +DNS-over-TLS). Stubby encrypts DNS queries sent from a client machine to a DNS +Privacy resolver increasing end user privacy. + +Stubby is useful on an OpenWRT device, because it can sit between the usual DNS +resolver (dnsmasq by default) and the upstream DNS resolver and be used to +ensure that DNS traffic is encrypted between the OpenWRT device and the +resolver. + +Stubby is developed by the [getdns](http://getdnsapi.net/) project. + +For more background and FAQ see the [About +Stubby](https://dnsprivacy.org/wiki/display/DP/About+Stubby) page. + + +## Installation + +Installation of this package can be achieved at the command line using `opkg +install stubby`, or via the LUCI Web Interface. Installing the stubby package +will also install the required dependency packages, including the +`ca-certificates` package. + +## Configuration + +The default configuration of the package has been chosen to ensure that stubby +should work after installation. + +By default, configuration of stubby is integrated with the OpenWRT UCI system +using the file `/etc/config/stubby`. The configuration options available are +also documented in that file. If for some reason you wish to configure stubby +using the `/etc/stubby/stubby.yml` file, then you simply need to set `option +manual '1'` in `/etc/config/stubby` and all other settings in +`/etc/config/stubby` will be ignored. + +### Stubby port and addresses + +The default configuration ensures that stubby listens on port 5453 on the +loopback interfaces for IPv4 and IPv6. As such, by default, stubby will respond +only to lookups from the OpenWRT device itself. + +By setting the listening ports to non-standard values, this allows users to keep +the main name server daemon in place (dnsmasq/unbound/etc.) and have that name +server forward to stubby. + +### Upstream resolvers + +The default package configuration uses the CloudFlare resolvers, configured for +both IPv4 and IPv6. + +CloudFlare have not published SPKI pinsets, and even though they are available, +they have made no commitment to maintaining them. Using the currently known SPKI +pinsets for CloudFlare brings the risk that in the future they may be changed by +CloudFlare, and DNS would stop working. The default configuration has those SPKI +entries commented out for this reason. + +[CloudFlare's privacy +statement](https://developers.cloudflare.com/1.1.1.1/commitment-to-privacy/) +details how they treat data from DNS requests. + +More resolvers are available in the [upstream stubby example +configuration](https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example) +and the [DNS Privacy +list](https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers). + +## Integration of stubby with dnsmasq + +The recommended way to use stubby on an OpenWRT device is to integrate it with a +caching resolver. The default caching resolver in OpenWRT is dnsmasq. + +### Set dnsmasq to send DNS requests to stubby + +Since dnsmasq responds to LAN DNS requests on port 53 of the OpenWRT device by +default, all that is required is to have dnsmasq forward those requests to +stubby which is listening on port 5453 of the OpenWRT device. To achieve this, +we need to set the `server` option in the dnsmasq configuration in the +`/etc/config/dhcp` file to `'127.0.0.1#5453'`. We also need to tell dnsmasq not +to use resolvers found in `/etc/resolv.conf` by setting the dnsmasq option +`noresolv` to `1` in the same file. This can be achieved by editing the +`/etc/config/dhcp` file directly or executing the following commands at the +command line: + + uci add_list dhcp.@dnsmasq[-1].server='127.0.0.1#5453' + uci set dhcp.@dnsmasq[-1].noresolv=1 + uci commit && reload_config + +The same outcome can be achieved in the LUCI web interface as follows: + +1. Select the Network->DHCP and DNS menu entry. +2. In the "General Settings" tab, enter the address `127.0.0.1#5453` as the only + entry in the "DNS Forwardings" dialogue. +3. In the "Resolv and Host files" tab tick the "Ignore resolve file" checkbox. + +### Disable sending DNS requests to ISP provided DNS servers + +The configuration changes in the previous section ensure that DNS queries are +sent over TLS encrypted connections *once dnsmasq and stubby are started*. When +the OpenWRT device is first brought up, there is a possibility that DNS queries +can go to ISP provided DNS servers ahead of dnsmasq and stubby being active. In +order to mitigate this leakage, it's necessary to ensure that upstream resolvers +aren't available, and the only DNS resolver used by the system is +dnsmasq+stubby. + +This requires setting the option `peerdns` to `0` and the option `dns` to the +loopback address for both the `wan` and `wan6` interfaces in the +`/etc/config/network` file. This can be achieved by editing the +`/etc/config/network` file directly, or by executing the following commands: + + uci set network.wan.peerdns='0' + uci set network.wan.dns='127.0.0.1' + uci set network.wan6.peerdns='0' + uci set network.wan6.dns='0::1' + uci commit && reload_config + +The same outcome can also be achieved using the LUCI web interface as follows: + +1. Select the Network->Interfaces menu entry. +2. Click on Edit for the WAN interfaces. +3. Choose the Advanced Settings tab. +4. Unselect the "Use DNS servers advertised by peer" checkbox +5. Enter `127.0.0.1` in the "Use custom DNS servers" dialogue box. +6. Repeat the above steps for the WAN6 interface, but use the address `0::1` + instead of `127.0.0.1`. + +### Enabling DNSSEC + +The configuration described above ensures that DNS queries are executed over TLS +encrypted links. However, the responses themselves are not validated; DNSSEC +provides the ability to validate returned DNS responses, and mitigate against +DNS poisoning risks. + +With the combination of stubby+dnsmasq there are two possible ways to enable +DNSSEC: + +1. Configure stubby to perform DNSSEC validation, and configure dnsmasq to proxy + the DNSSEC data to clients. +2. Configure stubby not to perform DNSSEC validation and configure dnsmasq to + require DNSSEC validation. + +Either option achieves the same outcome, and there appears to be little reason +for choosing one over the other other than that the second option is easier to +configure in the LUCI web interface. Both options are detailed below, and both +require that the `dnsmasq` package on the OpenWRT device is replaced with the +`dnsmasq-full` package. That can be achieved by running the following command: + + opkg install dnsmasq-full --download-only && opkg remove dnsmasq && opkg install dnsmasq-full --cache . && rm *.ipk + +#### DNSSEC by stubby + +Configuring stubby to perform DNSSEC validation requires setting the stubby +configuration option `dnssec_return_status` to `'1'` in `/etc/config/stubby`, +which can be done by editing the file directly or by executing the commands: + + uci set stubby.global.dnssec_return_status=1 + uci commit && reload_config + +With stubby performing DNSSEC validation, dnsmasq needs to be configured to +proxy the DNSSEC data to clients. This requires setting the option `proxydnssec` +to 1 in the dnsmasq configuration in `/etc/config/dhcp`. That can be achieved by +the following commands: + + uci set dhcp.@dnsmasq[-1].proxydnssec=1 + uci commit && reload_config + +#### DNSSEC by dnsmasq + +Configuring dnsmasq to perform DNSSEC validation requires setting the dnsmasq +option `dnssec` to `1` in the `/etc/config/dhcp` file. In addition, it is +advisable to also set the dnsmasq option `dnsseccheckunsigned` to `1`. this can +be achieved by editing the file `/etc/config/dhcp` or by executing the following +commands: + + uci set dhcp.@dnsmasq[-1].dnssec=1 + uci set dhcp.@dnsmasq[-1].dnsseccheckunsigned=1 + uci commit && reload_config + +The same options can be set in the LUCI web interface as follows: + +1. Select the "Network->DHCP and DNS" menu entry. +2. Select the "Advanced Settings" tab. +3. Ensure both the "DNSSEC" and "DNSSEC check unsigned" check boxes are ticked. + +#### Validating DNSSEC operation + +Having configured DNSSEC validation using one of the two approaches above, it's +important to check it's actually working. The following command can be used: + + dig dnssectest.sidn.nl +dnssec +multi @192.168.1.1 + +This command should return output like the following: + + ; <<>> DiG 9.11.4-P1-RedHat-9.11.4-5.P1.fc28 <<>> dnssectest.sidn.nl +dnssec +multi @192.168.1.1 + ;; global options: +cmd + ;; Got answer: + ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26579 + ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 + + ;; OPT PSEUDOSECTION: + ; EDNS: version: 0, flags: do; udp: 512 + ;; QUESTION SECTION: + ;dnssectest.sidn.nl. IN A + + ;; ANSWER SECTION: + dnssectest.sidn.nl. 14399 IN A 213.136.9.12 + dnssectest.sidn.nl. 14399 IN RRSIG A 8 3 14400 ( + 20181104071058 20181005071058 42033 sidn.nl. + YAQl3tef36M9EQUOmCneHKCCkxox3csLpfUOql5i/6ND + zPrQFsNr3g32HPoxOsi+hD2BE5+bEsnARayDSVLyx0qU + 6Hpi2rzQ0zGNZZkCJhCsdp3wnM1BWlMgPrCD0iIsJDok + +DH5zu+yYufVUdSLQrMqA3MZDFUIqDUqSZuYDF4= ) + + ;; Query time: 77 msec + ;; SERVER: 192.168.1.1#53(192.168.1.1) + ;; WHEN: Sat Oct 06 20:36:25 BST 2018 + ;; MSG SIZE rcvd: 230 + +The key thing to note is the `flags: qr rd ra ad` part - the `ad` flag signifies +that DNSSEC validation is working. If that flag is absent DNSSEC validation is +not working. + +## Appendix: stubby configuration options + +This section details the options available for use in the `/etc/config/stubby` +file. The `global` configuration section specifies the configuration parameters +for the stubby daemon. One or more `resolver` sections are used to configure +upstream resolvers for the stubby daemon to use. + +### `global` section options + +#### `option manual` + +Specify whether to use this file to configure the stubby service. If this is set +to `'1'` stubby will be configured using the file `/etc/stubby/stubby.yml`. If this +is set to `'0'`, configuration options will be taken from this file, and the service +will be managed through UCI. + +#### `option trigger` + +This specifies an interface to trigger stubby start up on; stubby startup will +be triggered by a procd signal associated with this interface being ready. If +this interface is restarted, stubby will also be restarted. + +This option can also be set to `'timed'`, in which case a time, specified by the +option `triggerdelay`, will be waited before starting stubby. + + +#### `option triggerdelay` + +If the `trigger` option specifies an interface, this option sets the time that +is waited after the procd signal is received before starting stubby. + +If `trigger` is set to `'timed'` then this is the delay before starting stubby. +This option is specified in seconds and defaults to the value `'2'`. + +#### `list dns_transport` + +The `dns_transport` list specifies the allowed transports. Allowed values are: +`GETDNS_TRANSPORT_UDP`, `GETDNS_TRANSPORT_TCP` and `GETDNS_TRANSPORT_TLS`. The +transports are tried in the order listed. + +#### `option tls_authentication` + +This option specifies whether TLS authentication is mandatory. A value of `'1'` +mandates TLS authentication, and is the default. + +If this is set to `'0'`, and `GETDNS_TRANSPORT_TCP` or `GETDNS_TRANSPORT_UDP` +appears in the `dns_transport` list, stubby is allowed to fall back to non-TLS +authenticated lookups. You probably don't want this though. + +#### `option tls_query_padding_blocksize` + +This option specifies the block size to pad DNS queries to. You shouldn't need +to set this to anything but `'128'` (the default), as recommended by +https://tools.ietf.org/html/draft-ietf-dprive-padding-policy-03 + +#### `option tls_connection_retries` + +This option specifies the number of connection failures stubby permits before +Stubby backs-off from using an individual upstream resolver. You shouldn't need +to change this from the default value of `'2'`. + +#### `option tls_backoff_time` + +This option specifies the maximum time in seconds Stubby will back-off from +using an individual upstream after failures. You shouldn't need to change this +from the default value of `'3600'`. + +#### `option timeout` + +This option specifies the timeout on getting a response to an individual +request. This is specified in milliseconds. You shouldn't need to change this +from the default value of ` '5000'`. + +#### `option dnssec_return_status` + +This option specifies whether stubby should require DNSSEC validation. Specify +to `'1'` to turn on validation, and `'0'` to turn it off. By default it is off. + +#### `option appdata_dir` + +This option specifies the location for storing stubby runtime data. In +particular, if DNSSEC is turned on, stubby will store its automatically +retrieved trust anchor data here. The default value is `'/var/lib/stubby'`. + +#### `option trust_anchors_backoff_time` + +When Zero configuration DNSSEC failed, because of network unavailability or +failure to write to the appdata directory, stubby will backoff trying to refetch +the DNSSEC trust-anchor for a specified amount of time expressed in milliseconds +(which defaults to two and a half seconds). + +#### `option dnssec_trust_anchors` + +This option sets the location of the file containing the trust anchor data used +for DNSSEC validation. If this is not specified, stubby will automatically +retrieve a trust anchor at startup. It's unlikely you'll want to manage the +trust anchor data manually, so in most cases this is not needed. By default, +this is unset. + +#### `option edns_client_subnet_private` + +This option specifies whether to enforce ECS client privacy. The default is +`'1'`. Set to `'0'` to disable client privacy. + +For more details see Section 7.1.2 [here](https://tools.ietf.org/html/rfc7871). + +#### `option idle_timeout` + +This option specifies the time (in milliseconds) to hold TLS connections open to +avoid the overhead of opening a new connection for every query. You should not +normally need to change this from the default value (currently `'10000'`). + +See [here](https://tools.ietf.org/html/rfc7828) for more details. + +#### `option round_robin_upstreams` + +This option specifies how stubby will use the upstream DNS resolvers. Set to +`'1'` (the default) to instruct stubby to distribute queries across all +available name servers - this will use multiple simultaneous connections which +can give better performance in most (but not all) cases. Set to `'0'` to treat +the upstream resolvers as an ordered list and use a single upstream resolver +until it becomes unavailable, then use the next one. + +#### `list listen_address` + +This list sets the addresses and ports for the stubby daemon to listen for +requests on. the default configuration configures stubby to listen on port 5453 +on the loopback interface for both IPv4 and IPv6. + +#### `option log_level` + +If set, this option specifies the level of logging from the stubby +daemon. By default, this option is not set. + +The possible levels are: + + '0': EMERG - System is unusable + '1': ALERT - Action must be taken immediately + '2': CRIT - Critical conditions + '3': ERROR - Error conditions + '4': WARN - Warning conditions + '5': NOTICE - Normal, but significant, condition + '6': INFO - Informational message + '7': DEBUG - Debug-level message + +#### `option command_line_arguments` + +This option specifies additional command line arguments for +stubby daemon. By default, this is an empty string. + +#### `option tls_cipher_list` + +If set, this specifies the acceptable ciphers for DNS over TLS. With OpenSSL +1.1.1 this list is for TLS1.2 and older only. Ciphers for TLS1.3 should be set +with the `tls_ciphersuites` option. This option can also be given per upstream +resolver. By default, this option is not set. + +#### `option tls_ciphersuites` + +If set, this specifies the acceptable cipher for DNS over TLS1.3. OpenSSL +version 1.1.1 or greater is required for this option. This option can also be +given per upstream resolver. By default, this option is not set. + +#### `option tls_min_version` + +If set, this specifies the minimum acceptable TLS version. Works with OpenSSL +1.1.1 or greater only. This option can also be given per upstream resolver. By +default, this option is not set. + +#### `option tls_max_version` + +If set, this specifies the maximum acceptable TLS version. Works with OpenSSL +1.1.1 or greater only. This option can also be given per upstream resolver. By +default, this option is not set. + + +### `resolver` section options + +#### `option address` + +This option specifies the resolver IP address, and can either be an IPv4 or an +IPv6 address. + +#### `option tls_auth_name` + +This option specifies the upstream domain name used for TLS authentication with +the supplied server certificate + +#### `option tls_port` + +This option specifies the TLS port for the upstream resolver. If not specified, +this defaults to 853. + +#### `option tls_cipher_list` + +If set, this specifies the acceptable ciphers for DNS over TLS. With OpenSSL +1.1.1 this list is for TLS1.2 and older only. Ciphers for TLS1.3 should be set +with the `tls_ciphersuites` option. By default, this option is not set. If set, +this overrides the global value. + +#### `option tls_ciphersuites` + +If set, this specifies the acceptable cipher for DNS over TLS1.3. OpenSSL +version 1.1.1 or greater is required for this option. By default, this option is +not set. If set, this overrides the global value. + +#### `option tls_min_version` + +If set, this specifies the minimum acceptable TLS version. Works with OpenSSL +1.1.1 or greater only. By default, this option is not set. If set, this +overrides the global value. + +#### `option tls_max_version` + +If set, this specifies the maximum acceptable TLS version. Works with OpenSSL +1.1.1 or greater only. By default, this options is not set. If set, this +overrides the global value. + +#### `list spki` + +This list specifies the SPKI pinset which is verified against the keys in the +server cerrtificate. The value takes the form `'/value>'`, where +the `digest type` is the hashing algorithm used, and the value is the Base64 +encoded hash of the public key. At present, only `sha256` is +supported for the digest type. + +This should ONLY be used if the upstream resolver has committed to maintaining +the pinset. CloudFlare have made no such commitment, and so we do not specify +the SPKI values in the default configuration, even though they are available. diff --git a/net/stubby/files/stubby.conf b/net/stubby/files/stubby.conf new file mode 100644 index 0000000..f722a43 --- /dev/null +++ b/net/stubby/files/stubby.conf @@ -0,0 +1,66 @@ +config stubby 'global' + option manual '0' + option trigger 'wan' + # option triggerdelay '2' + list dns_transport 'GETDNS_TRANSPORT_TLS' + option tls_authentication '1' + option tls_query_padding_blocksize '128' + # option tls_connection_retries '2' + # option tls_backoff_time '3600' + # option timeout '5000' + # option dnssec_return_status '0' + option appdata_dir '/var/lib/stubby' + # option trust_anchors_backoff_time 2500 + # option dnssec_trust_anchors '/var/lib/stubby/getdns-root.key' + option edns_client_subnet_private '1' + option idle_timeout '10000' + option round_robin_upstreams '1' + list listen_address '127.0.0.1@5453' + list listen_address '0::1@5453' + # option log_level '7' + # option command_line_arguments '' + # option tls_cipher_list 'EECDH+AESGCM:EECDH+CHACHA20' + # option tls_ciphersuites 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256' + # option tls_min_version '1.2' + # option tls_max_version '1.3' + +# Upstream resolvers are specified using 'resolver' sections. +config resolver + option address '2606:4700:4700::1111' + option tls_auth_name 'cloudflare-dns.com' + # option tls_port 853 + # list spki 'sha256/yioEpqeR4WtDwE9YxNVnCEkTxIjx6EEIwFSQW+lJsbc=' + # option tls_cipher_list 'EECDH+AESGCM:EECDH+CHACHA20' + # option tls_ciphersuites 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256' + # option tls_min_version '1.2' + # option tls_max_version '1.3' + +config resolver + option address '2606:4700:4700::1001' + option tls_auth_name 'cloudflare-dns.com' + # option tls_port 853 + # list spki 'sha256/yioEpqeR4WtDwE9YxNVnCEkTxIjx6EEIwFSQW+lJsbc=' + # option tls_cipher_list 'EECDH+AESGCM:EECDH+CHACHA20' + # option tls_ciphersuites 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256' + # option tls_min_version '1.2' + # option tls_max_version '1.3' + +config resolver + option address '1.1.1.1' + option tls_auth_name 'cloudflare-dns.com' + # option tls_port 853 + # list spki 'sha256/yioEpqeR4WtDwE9YxNVnCEkTxIjx6EEIwFSQW+lJsbc=' + # option tls_cipher_list 'EECDH+AESGCM:EECDH+CHACHA20' + # option tls_ciphersuites 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256' + # option tls_min_version '1.2' + # option tls_max_version '1.3' + +config resolver + option address '1.0.0.1' + option tls_auth_name 'cloudflare-dns.com' + # option tls_port 853 + # list spki 'sha256/yioEpqeR4WtDwE9YxNVnCEkTxIjx6EEIwFSQW+lJsbc=' + # option tls_cipher_list 'EECDH+AESGCM:EECDH+CHACHA20' + # option tls_ciphersuites 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256' + # option tls_min_version '1.2' + # option tls_max_version '1.3' diff --git a/net/stubby/files/stubby.init b/net/stubby/files/stubby.init new file mode 100755 index 0000000..cf051a1 --- /dev/null +++ b/net/stubby/files/stubby.init @@ -0,0 +1,273 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 + +START=30 +STOP=51 + +stubby="/usr/sbin/stubby" +stubby_init="/etc/init.d/stubby" +stubby_config_dir="/var/etc/stubby" +stubby_config="$stubby_config_dir/stubby.yml" +stubby_pid_file="/var/run/stubby.pid" +stubby_manual_config="/etc/stubby/stubby.yml" + +boot() +{ + stubby_boot=1 + rc_procd start_service +} + +generate_config() +{ + local config_file="$1" + local round_robin + local tls_authentication + local tls_query_padding_blocksize + local edns_client_subnet_private + local idle_timeout + local appdata_dir + local trust_anchors_backoff_time + local tls_connection_retries + local tls_backoff_time + local timeout + local dnssec_return_status + local dnssec_trust_anchors + local listen_addresses_section=0 + local dns_transport_list_section=0 + local upstream_recursive_servers_section=0 + local command_line_arguments + local log_level + local tls_cipher_list + local tls_ciphersuites + local tls_min_version + local tls_max_version + + # Generate configuration. See: https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example + echo "# Autogenerated configuration from uci data" > "$config_file" + echo "resolution_type: GETDNS_RESOLUTION_STUB" >> "$config_file" + + config_get round_robin "global" round_robin_upstreams "1" + echo "round_robin_upstreams: $round_robin" >> "$config_file" + + config_get appdata_dir "global" appdata_dir "/var/lib/stubby" + echo "appdata_dir: \"$appdata_dir\"" >> "$config_file" + + config_get trust_anchors_backoff_time "global" trust_anchors_backoff_time "2500" + echo "trust_anchors_backoff_time: $trust_anchors_backoff_time" >> "$config_file" + + config_get tls_connection_retries "global" tls_connection_retries "" + if [ -n "$tls_connection_retries" ]; then + echo "tls_connection_retries: $tls_connection_retries" >> "$config_file" + fi + + config_get tls_backoff_time "global" tls_backoff_time "" + if [ -n "$tls_backoff_time" ]; then + echo "tls_backoff_time: $tls_backoff_time" >> "$config_file" + fi + + config_get timeout "global" timeout "" + if [ -n "$timeout" ]; then + echo "timeout: $timeout" >> "$config_file" + fi + + config_get_bool tls_authentication "global" tls_authentication "1" + if [ "$tls_authentication" = "1" ]; then + echo "tls_authentication: GETDNS_AUTHENTICATION_REQUIRED" >> "$config_file" + else + echo "tls_authentication: GETDNS_AUTHENTICATION_NONE" >> "$config_file" + fi + + config_get_bool dnssec_return_status "global" dnssec_return_status "0" + if [ "$dnssec_return_status" = "1" ]; then + echo "dnssec_return_status: GETDNS_EXTENSION_TRUE" >> "$config_file" + fi + + config_get dnssec_trust_anchors "global" dnssec_trust_anchors "" + if [ -n "$dnssec_trust_anchors" ]; then + echo "dnssec_trust_anchors: \"$dnssec_trust_anchors\"" >> "$config_file" + fi + + config_get tls_query_padding_blocksize "global" tls_query_padding_blocksize "128" + echo "tls_query_padding_blocksize: $tls_query_padding_blocksize" >> "$config_file" + + config_get_bool edns_client_subnet_private "global" edns_client_subnet_private "1" + echo "edns_client_subnet_private: $edns_client_subnet_private" >> "$config_file" + + config_get idle_timeout "global" idle_timeout "10000" + echo "idle_timeout: $idle_timeout" >> "$config_file" + + config_get tls_cipher_list "global" tls_cipher_list "" + if [ -n "$tls_cipher_list" ]; then + echo "tls_cipher_list: \"$tls_cipher_list\"" >> "$config_file" + fi + + config_get tls_ciphersuites "global" tls_ciphersuites "" + if [ -n "$tls_ciphersuites" ]; then + echo "tls_ciphersuites: \"$tls_ciphersuites\"" >> "$config_file" + fi + + config_get tls_min_version "global" tls_min_version "" + if [ -n "$tls_min_version" ]; then + echo "tls_min_version: GETDNS_TLS${tls_min_version/\./_}" >> "$config_file" + fi + + config_get tls_max_version "global" tls_max_version "" + if [ -n "$tls_max_version" ]; then + echo "tls_max_version: GETDNS_TLS${tls_max_version/\./_}" >> "$config_file" + fi + + handle_listen_address_value() + { + local value="$1" + + if [ "$listen_addresses_section" = 0 ]; then + echo "listen_addresses:" >> "$config_file" + listen_addresses_section=1 + fi + echo " - $value" >> "$config_file" + } + config_list_foreach "global" listen_address handle_listen_address_value + + handle_dns_transport_list_value() + { + local value="$1" + + if [ "$dns_transport_list_section" = 0 ]; then + echo "dns_transport_list:" >> "$config_file" + dns_transport_list_section=1 + fi + echo " - $value" >> "$config_file" + } + config_list_foreach "global" dns_transport handle_dns_transport_list_value + + handle_resolver() + { + local config=$1 + local address + local tls_auth_name + local tls_port + local tls_pubkey_pinset_section=0 + local tls_cipher_list + local tls_ciphersuites + local tls_min_version + local tls_max_version + + if [ "$upstream_recursive_servers_section" = 0 ]; then + echo "upstream_recursive_servers:" >> "$config_file" + upstream_recursive_servers_section=1 + fi + config_get address "$config" address + echo " - address_data: $address" >> "$config_file" + + config_get tls_auth_name "$config" tls_auth_name + echo " tls_auth_name: \"$tls_auth_name\"" >> "$config_file" + + config_get tls_auth_port "$config" tls_port "" + if [ -n "$tls_port" ]; then + echo " tls_port: $tls_port" >> "$config_file" + fi + + config_get tls_cipher_list "$config" tls_cipher_list "" + if [ -n "$tls_cipher_list" ]; then + echo " tls_cipher_list: \"$tls_cipher_list\"" >> "$config_file" + fi + + config_get tls_ciphersuites "$config" tls_ciphersuites "" + if [ -n "$tls_ciphersuites" ]; then + echo " tls_ciphersuites: \"$tls_ciphersuites\"" >> "$config_file" + fi + + config_get tls_min_version "$config" tls_min_version "" + if [ -n "$tls_min_version" ]; then + echo " tls_min_version: GETDNS_TLS${tls_min_version/\./_}" >> "$config_file" + fi + + config_get tls_max_version "$config" tls_max_version "" + if [ -n "$tls_max_version" ]; then + echo " tls_max_version: GETDNS_TLS${tls_max_version/\./_}" >> "$config_file" + fi + + handle_resolver_spki() + { + local val="$1" + local digest="${val%%/*}" + local value="${val#*/}" + + if [ "$tls_pubkey_pinset_section" = 0 ]; then + echo " tls_pubkey_pinset:" >> "$config_file" + tls_pubkey_pinset_section=1 + fi + echo " - digest: \"$digest\"" >> "$config_file" + echo " value: $value" >> "$config_file" + } + config_list_foreach "$config" spki handle_resolver_spki + } + + config_foreach handle_resolver resolver +} + +start_service() { + local config_file_tmp + local manual + local log_level + local command_line_arguments + + mkdir -p "$stubby_config_dir" + + config_load "stubby" + + config_get_bool manual "global" manual "0" + + if [ "$manual" = "1" ]; then + cp "$stubby_manual_config" "$stubby_config" + else + config_file_tmp="$stubby_config.$$" + generate_config "$config_file_tmp" + mv "$config_file_tmp" "$stubby_config" + fi + + config_get command_line_arguments "global" command_line_arguments "" + + config_get log_level "global" log_level "" + + if [ "$("$stubby_init" enabled; printf "%u" $?)" -eq 0 ]; then + if [ -n "$stubby_boot" ]; then + local trigger + trigger="$(uci_get stubby global trigger)" + if [ "$trigger" != "timed" ]; then + return 0 + fi + fi + procd_open_instance "stubby" + procd_set_param command "$stubby" -C "$stubby_config" + if [ -n "$log_level" ]; then + procd_append_param command -v "$log_level" + fi + if [ -n "$command_line_arguments" ]; then + procd_append_param command "$command_line_arguments" + fi + procd_set_param respawn + procd_set_param file "$stubby_config" + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param pidfile "$stubby_pid_file" + procd_set_param user stubby + procd_close_instance + fi +} + +service_triggers() +{ + local trigger + local delay + + trigger="$(uci_get stubby global trigger)" + delay="$(uci_get stubby global triggerdelay "2")" + + if [ "$trigger" != "none" ] && [ "$trigger" != "timed" ]; then + PROCD_RELOAD_DELAY=$((${delay:-2} * 1000)) + procd_add_interface_trigger "interface.*.up" "$trigger" "$stubby_init" start + fi + procd_add_reload_trigger "stubby" +} diff --git a/net/stubby/files/stubby.yml b/net/stubby/files/stubby.yml new file mode 100644 index 0000000..b935f31 --- /dev/null +++ b/net/stubby/files/stubby.yml @@ -0,0 +1,25 @@ +# Note: by default on OpenWRT stubby configuration is handled via +# the UCI system and the file /etc/config/stubby. If you want to +# use this file to configure stubby, then set "option manual '1'" +# in /etc/config/stubby. +resolution_type: GETDNS_RESOLUTION_STUB +round_robin_upstreams: 1 +appdata_dir: "/var/lib/stubby" +tls_authentication: GETDNS_AUTHENTICATION_REQUIRED +tls_query_padding_blocksize: 128 +edns_client_subnet_private: 1 +idle_timeout: 10000 +listen_addresses: + - 127.0.0.1@5453 + - 0::1@5453 +dns_transport_list: + - GETDNS_TRANSPORT_TLS +upstream_recursive_servers: + - address_data: 2606:4700:4700::1111 + tls_auth_name: "cloudflare-dns.com" + - address_data: 2606:4700:4700::1001 + tls_auth_name: "cloudflare-dns.com" + - address_data: 1.1.1.1 + tls_auth_name: "cloudflare-dns.com" + - address_data: 1.0.0.1 + tls_auth_name: "cloudflare-dns.com"