PKG_NAME:=https-dns-proxy
PKG_VERSION:=2026.03.18
-PKG_RELEASE:=3
+PKG_RELEASE:=4
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy/
define Package/https-dns-proxy/description
Light-weight DNS-over-HTTPS, non-caching translation proxy for the RFC 8484 DoH standard.
It receives regular, unencrypted (UDP) DNS requests and resolves them via DoH resolver.
-Please see https://docs.openwrt.melmac.ca/https-dns-proxy/ for more information.
+Please see https://docs.mossdef.org/https-dns-proxy/ for more information.
endef
define Package/https-dns-proxy/conffiles
$(INSTALL_CONF) ./files/etc/config/https-dns-proxy $(1)/etc/config/https-dns-proxy
$(INSTALL_DIR) $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/50-https-dns-proxy-migrate-options.sh $(1)/etc/uci-defaults/50-https-dns-proxy-migrate-options.sh
+ $(INSTALL_DIR) $(1)/usr/share/nftables.d/ruleset-post
+ $(INSTALL_DATA) ./files/usr/share/nftables.d/ruleset-post/.placeholder $(1)/usr/share/nftables.d/ruleset-post/.placeholder
endef
$(eval $(call BuildPackage,https-dns-proxy))
# https-dns-proxy
[](https://openwrt.org)
-[](https://docs.openwrt.melmac.ca/https-dns-proxy/)
-[](https://docs.openwrt.melmac.ca/https-dns-proxy/)
+[](https://docs.mossdef.org/https-dns-proxy/)
+[](https://docs.mossdef.org/https-dns-proxy/)
[](https://github.com/stangri/https-dns-proxy)
[](https://github.com/stangri/https-dns-proxy/blob/master/LICENSE)
**Full documentation:**
-[https://docs.openwrt.melmac.ca/https-dns-proxy/](https://docs.openwrt.melmac.ca/https-dns-proxy/)
+[https://docs.mossdef.org/https-dns-proxy/](https://docs.mossdef.org/https-dns-proxy/)
Based on [@aarond10](https://github.com/aarond10)'s excellent [https_dns_proxy](https://github.com/aarond10/https_dns_proxy)
# list force_dns_port '8443'
list force_dns_src_interface 'lan'
option procd_trigger_wan6 '0'
- option heartbeat_domain 'heartbeat.melmac.ca'
+ option heartbeat_domain 'heartbeat.mossdef.org'
option heartbeat_sleep_timeout '10'
option heartbeat_wait_timeout '10'
option user 'nobody'
is_resolver_working() {
local heartbeat_domain heartbeat_sleep_timeout heartbeat_wait_timeout
config_load "$packageName"
- config_get heartbeat_domain 'config' 'heartbeat_domain' 'heartbeat.melmac.ca'
+ config_get heartbeat_domain 'config' 'heartbeat_domain' 'heartbeat.mossdef.org'
config_get heartbeat_sleep_timeout 'config' 'heartbeat_sleep_timeout' '10'
config_get heartbeat_wait_timeout 'config' 'heartbeat_wait_timeout' '30'
[ "$heartbeat_domain" = '-' ] && return 0
[ -n "$(/sbin/uci ${UCI_CONFIG_DIR:+-c ${UCI_CONFIG_DIR}} changes "$PACKAGE${CONFIG:+.${CONFIG}}${OPTION:+.${OPTION}}")" ]
}
notrack_nft() {
+ command -v nft >/dev/null 2>&1 || return 0
case "$1" in
update)
local port_set="$2"
)"
existing_content="$(cat "$NOTRACK_NFT_FILE" 2>/dev/null)"
if [ "$new_content" != "$existing_content" ]; then
- mkdir -p "${NOTRACK_NFT_FILE%/*}"
- echo "$new_content" > "$NOTRACK_NFT_FILE"
+ if ! mkdir -p "${NOTRACK_NFT_FILE%/*}"; then
+ logger -t "$packageName" "Failed to create ${NOTRACK_NFT_FILE%/*}; skipping notrack rules"
+ return 1
+ fi
+ if ! echo "$new_content" > "$NOTRACK_NFT_FILE"; then
+ logger -t "$packageName" "Failed to write $NOTRACK_NFT_FILE; skipping notrack rules"
+ return 1
+ fi
fi
[ -s "$NOTRACK_NFT_FILE" ] && nft -c -f "$NOTRACK_NFT_FILE"
;;
# Tests helper functions, validation logic, dnsmasq integration,
# and UCI migration by mocking OpenWrt's rc.common framework.
#
-# Usage: cd source.openwrt.melmac.ca/https-dns-proxy && bash tests/run_tests.sh
+# Usage: cd source.mossdef.org/https-dns-proxy && bash tests/run_tests.sh
set -o pipefail
assert_rc "notrack_nft remove succeeds when file and table both absent" 0 $?
__nft_rc=0
+# ── nft binary absent: notrack_nft is a no-op ──
+# Without firewall4/nftables installed, the package should not error;
+# `command -v nft` returns non-zero and notrack_nft returns 0 immediately.
+rm -rf "$TESTDIR/usr/share"
+__saved_nft_def="$(typeset -f nft 2>/dev/null || declare -f nft)"
+unset -f nft
+mkdir -p "$TESTDIR/empty-path"
+__saved_path="$PATH"
+PATH="$TESTDIR/empty-path"
+
+notrack_nft update "53"
+assert_rc "notrack_nft update is a no-op when nft binary is absent" 0 $?
+
+[ ! -f "$NOTRACK_TEST_FILE" ]
+assert_rc "notrack_nft did not write snippet when nft is absent" 0 $?
+
+PATH="$__saved_path"
+eval "$__saved_nft_def"
+
+# ── mkdir failure path returns non-zero ──
+# Place a regular file at the would-be parent dir so mkdir -p must fail.
+# Defensive logic should return 1 instead of falling through to a broken
+# redirection.
+rm -rf "$TESTDIR/usr/share"
+mkdir -p "$(dirname "$(dirname "$NOTRACK_TEST_FILE")")"
+: > "$(dirname "$NOTRACK_TEST_FILE")"
+
+notrack_nft update "53" 2>/dev/null
+assert_rc "notrack_nft update returns 1 when parent dir cannot be created" 1 $?
+
+[ ! -f "$NOTRACK_TEST_FILE" ]
+assert_rc "notrack_nft did not write snippet on mkdir failure" 0 $?
+
+rm -f "$(dirname "$NOTRACK_TEST_FILE")"
+
###############################################################################
# SHELL SCRIPT SYNTAX #
###############################################################################