aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <hello@cleberg.net>2023-12-03 22:43:44 -0600
committerChristian Cleberg <hello@cleberg.net>2023-12-03 22:43:44 -0600
commit18e372d06257e62a1003c563fb26fb4c491f50a9 (patch)
tree0e5dc96e8e85fc3a418efde72bd7caae0e5d40c0
parent5c78e03ec05ed90d2ef93a6bf9bc0c4043d9a85f (diff)
downloadcleberg.net-18e372d06257e62a1003c563fb26fb4c491f50a9.tar.gz
cleberg.net-18e372d06257e62a1003c563fb26fb4c491f50a9.tar.bz2
cleberg.net-18e372d06257e62a1003c563fb26fb4c491f50a9.zip
feat: add nextdns pot
-rw-r--r--blog/2023-11-12-consolefonts.org5
-rw-r--r--blog/2023-12-03-unifi-nextdns.org1275
-rw-r--r--blog/index.org25
-rw-r--r--blog/rss.org2
4 files changed, 1301 insertions, 6 deletions
diff --git a/blog/2023-11-12-consolefonts.org b/blog/2023-11-12-consolefonts.org
deleted file mode 100644
index 47ac456..0000000
--- a/blog/2023-11-12-consolefonts.org
+++ /dev/null
@@ -1,5 +0,0 @@
-+++
-date = 2023-11-12T02:03:25.924298748+00:00
-title = "How to Configure Console Fonts on Alpine Linux"
-description = ""
-+++
diff --git a/blog/2023-12-03-unifi-nextdns.org b/blog/2023-12-03-unifi-nextdns.org
new file mode 100644
index 0000000..e6eb4b0
--- /dev/null
+++ b/blog/2023-12-03-unifi-nextdns.org
@@ -0,0 +1,1275 @@
+#+title: How to Install NextDNS on the Unifi Dream Machine
+#+date: 2023-12-03
+
+* Overview
+:PROPERTIES:
+:ID: 711309AE-955D-4B2D-B716-CFD700079157
+:PUBDATE: 2023-12-03 Sun 22:32
+:END:
+
+I recently installed NextDNS on my Unifi Dream Machine router using the
+[[https://github.com/nextdns/nextdns/wiki/UnifiOS][UnifiOS]] wiki page on
+NextDNS's GitHub repository.
+
+As a result of this, I wanted to write down the process in case the wiki or
+installer ever gets lost.
+
+* Wiki
+:PROPERTIES:
+:ID: 8457B7A9-AE62-448D-B092-C04759F8D468
+:PUBDATE: 2023-12-03 Sun 22:32
+:END:
+
+The following is copied from the wiki page linked above, with one difference in
+the =ssh= command.
+
+Install instructions for Unifi Dream Machine (UDM) standard and pro routers.
+
+** Install
+:PROPERTIES:
+:ID: 907F595C-6D53-409D-AB97-2B830D09B62E
+:END:
+
+Enable SSH:
+
+- Go to your unifi admin interface and select your device (not the controller
+ settings, but the Dream Machine settings)
+- Click on "Settings" at the bottom of the page
+- Go to the "Advanced" section on the left pan
+- Enable SSH
+- Set a SSH password
+
+Connect to your router using =ssh root@xxx.xxx.xxx.xxx= with the password you
+configured.
+
+Run the following command and follow the instructions:
+
+#+begin_src sh
+sh -c 'sh -c "$(curl -sL https://nextdns.io/install)"'
+#+end_src
+
+Note: Queries from the UDM itself won’t be routed to NextDNS nor encrypted due
+to current system limitation. All traffic from other devices on then network
+will.
+
+** Upgrade
+:PROPERTIES:
+:ID: 3836C070-2C7C-456D-AB3B-15DDE60D2F99
+:END:
+
+To upgrade to the last version, simply re-run the installer above. If a new
+version is available, the upgrade action will added to the list of possible
+actions.
+
+** Uninstall
+:PROPERTIES:
+:ID: DFD1BA2F-EC4E-4B5C-9CEA-098DFF0AD62F
+:END:
+
+To uninstall, re-run the installer above and select "Remove" in the menu.
+
+** Troubleshooting
+:PROPERTIES:
+:ID: 0B0F4E70-FACC-4C7C-8EB9-55398AA8476F
+:END:
+
+If the installation fail, please the installer in debug mode and contact us at
+team@nextdns.io with the transcript of the installation:
+
+#+begin_src sh
+sh -c 'DEBUG=1 sh -c "$(curl -sL https://nextdns.io/install)"'
+#+end_Ssrc
+
+*** Content Filtering Conflict
+:PROPERTIES:
+:ID: BCDD3267-4C04-45AC-BAAD-9D15F414ED4D
+:END:
+
+NextDNS CLI and the UDM Content Filtering or the Ad Blocking features are
+incompatible. If you want to use NextDNS CLI, please make sure they are
+disabled.
+
+To disable Content Filtering, go to Settings > Network, then for each network,
+set the Content Filtering feature to None
+
+To disable Ad Blocking, go to Settings > Application Firewall. In the General
+tab, uncheck the Ad Blocking checkbox.
+
+*** APT Error
+:PROPERTIES:
+:ID: 83244A13-7154-475A-8193-064A1B81D3AE
+:END:
+
+If you get an apt error as follow:
+
+#+begin_src sh
+E: Failed to fetch http://security.debian.org/dists/stretch/updates/main/binary-arm64/Packages 404 Not Found [IP: 151.101.70.132 80]
+#+end_src
+
+You may try to following:
+
+#+begin_src sh
+sed -i -e 's/deb.debian.org/archive.debian.org/g' \
+ -e 's|security.debian.org|archive.debian.org/|g' \
+ -e '/stretch-updates/d' /etc/apt/sources.list
+#+end_src
+
+* install.sh
+:PROPERTIES:
+:ID: 91DE0DD0-8177-4594-B067-373ABF99C343
+:PUBDATE: 2023-12-03 Sun 22:34
+:END:
+
+Here are the contents of the =install.sh= file used above, as of 2023-12-03:
+
+#+begin_src sh
+#!/bin/sh
+
+main() {
+ OS=$(detect_os)
+ GOARCH=$(detect_goarch)
+ GOOS=$(detect_goos)
+ NEXTDNS_BIN=$(bin_location)
+ INSTALL_RELEASE=$(get_release)
+
+ export NEXTDNS_INSTALLER=1
+
+ log_info "OS: $OS"
+ log_info "GOARCH: $GOARCH"
+ log_info "GOOS: $GOOS"
+ log_info "NEXTDNS_BIN: $NEXTDNS_BIN"
+ log_info "INSTALL_RELEASE: $INSTALL_RELEASE"
+
+ if [ -z "$OS" ] || [ -z "$GOARCH" ] || [ -z "$GOOS" ] || [ -z "$NEXTDNS_BIN" ] || [ -z "$INSTALL_RELEASE" ]; then
+ log_error "Cannot detect running environment."
+ exit 1
+ fi
+
+ case "$RUN_COMMAND" in
+ install|upgrade|uninstall|configure) "$RUN_COMMAND"; exit ;;
+ esac
+
+ while true; do
+ CURRENT_RELEASE=$(get_current_release)
+ log_debug "Start install loop with CURRENT_RELEASE=$CURRENT_RELEASE"
+
+ if [ "$CURRENT_RELEASE" ]; then
+ if ! is_version_current; then
+ log_debug "NextDNS is out of date ($CURRENT_RELEASE != $INSTALL_RELEASE)"
+ menu \
+ u "Upgrade NextDNS from $CURRENT_RELEASE to $INSTALL_RELEASE" upgrade \
+ c "Configure NextDNS" configure \
+ r "Remove NextDNS" uninstall \
+ e "Exit" exit
+ else
+ log_debug "NextDNS is up to date ($CURRENT_RELEASE)"
+ menu \
+ c "Configure NextDNS" configure \
+ r "Remove NextDNS" uninstall \
+ e "Exit" exit
+ fi
+ else
+ log_debug "NextDNS is not installed"
+ menu \
+ i "Install NextDNS" install \
+ e "Exit" exit
+ fi
+ done
+}
+
+install() {
+ if [ "$(get_current_release)" ]; then
+ log_info "Already installed"
+ return
+ fi
+ if type=$(install_type); then
+ log_info "Installing NextDNS..."
+ log_debug "Using $type install type"
+ if "install_$type"; then
+ if [ ! -x "$NEXTDNS_BIN" ]; then
+ log_error "Installation failed: binary not installed in $NEXTDNS_BIN"
+ return 1
+ fi
+ configure
+ post_install
+ exit 0
+ fi
+ else
+ return $?
+ fi
+}
+
+upgrade() {
+ if [ "$(get_current_release)" = "$INSTALL_RELEASE" ]; then
+ log_info "Already on the latest version"
+ return
+ fi
+ if type=$(install_type); then
+ log_info "Upgrading NextDNS..."
+ log_debug "Using $type install type"
+ "upgrade_$type"
+ else
+ return $?
+ fi
+}
+
+uninstall() {
+ if type=$(install_type); then
+ log_info "Uninstalling NextDNS..."
+ log_debug "Using $type uninstall type"
+ "uninstall_$type"
+ else
+ return $?
+ fi
+}
+
+precheck() {
+ if [ -e "/data/unifi" ] && [ -f "/run/dnsfilter/dnsfilter" ]; then
+ log_warn "UDM Content Filtering and/or Ad Blocking feature is enabled."
+ log_warn "Please disable it to use NextDNS."
+ log_warn ""
+ log_warn " To disable Content Filtering, go to Settings > Network."
+ log_warn " For each network, set the Content Filtering feature to None."
+ log_warn ""
+ log_warn " To disable Ad Blocking, go to Settings > Application Firewall"
+ log_warn " In the General tab, uncheck the Ad Blocking checkbox."
+ log_warn ""
+ while [ -f "/run/dnsfilter/dnsfilter" ]; do
+ sleep 1
+ done
+ log_info "Content Filtering feature successfuly disabled."
+ fi
+}
+
+configure() {
+ log_debug "Start configure"
+ precheck
+ args=""
+ add_arg() {
+ for value in $2; do
+ log_debug "Add arg -$1=$value"
+ args="$args -$1=$value"
+ done
+ }
+ add_arg_bool_ask() {
+ arg=$1
+ msg=$2
+ default=$3
+ if [ -z "$default" ]; then
+ default=$(get_config_bool "$arg")
+ fi
+ # shellcheck disable=SC2046
+ add_arg "$arg" $(ask_bool "$msg" "$default")
+ }
+ # Use profile from now on
+ add_arg profile "$(get_profile_id)"
+
+ doc "Sending your devices name lets you filter analytics and logs by device."
+ add_arg_bool_ask report-client-info 'Report device name?' true
+
+ case $(guess_host_type) in
+ router)
+ add_arg setup-router true
+ ;;
+ unsure)
+ doc "Accept DNS request from other network hosts."
+ if [ "$(get_config_bool setup-router)" = "true" ]; then
+ router_default=true
+ fi
+ if [ "$(ask_bool 'Setup as a router?' $router_default)" = "true" ]; then
+ add_arg setup-router true
+ fi
+ ;;
+ esac
+
+ doc "Make NextDNS CLI cache responses. This improves latency and reduces the amount"
+ doc "of queries sent to NextDNS."
+ if [ "$(guess_host_type)" = "router" ]; then
+ doc "Note that enabling this feature will disable dnsmasq for DNS to avoid double"
+ doc "caching."
+ fi
+ if [ "$(get_config cache-size)" != "0" ]; then
+ cache_default=true
+ fi
+ if [ "$(ask_bool 'Enable caching?' $cache_default)" = "true" ]; then
+ add_arg cache-size "10MB"
+
+ doc "Instant refresh will force low TTL on responses sent to clients so they rely"
+ doc "on CLI DNS cache. This will allow changes on your NextDNS config to be applied"
+ doc "on your LAN hosts without having to wait for their cache to expire."
+ if [ "$(get_config max-ttl)" = "5s" ]; then
+ instant_refresh_default=true
+ fi
+ if [ "$(ask_bool 'Enable instant refresh?' $instant_refresh_default)" = "true" ]; then
+ add_arg max-ttl "5s"
+ fi
+ fi
+
+ if [ "$(guess_host_type)" != "router" ]; then
+ doc "Changes DNS settings of the host automatically when NextDNS is started."
+ doc "If you say no here, you will have to manually configure DNS to 127.0.0.1."
+ add_arg_bool_ask auto-activate 'Automatically setup local host DNS?' true
+ fi
+ # shellcheck disable=SC2086
+ asroot "$NEXTDNS_BIN" install $args
+}
+
+post_install() {
+ println
+ println "Congratulations! NextDNS is now installed."
+ println
+ println "To upgrade/uninstall, run this command again and select the appropriate option."
+ println
+ println "You can use the NextDNS command to control the daemon."
+ println "Here are a few important commands to know:"
+ println
+ println "# Start, stop, restart the daemon:"
+ println "nextdns start"
+ println "nextdns stop"
+ println "nextdns restart"
+ println
+ println "# Configure the local host to point to NextDNS or not:"
+ println "nextdns activate"
+ println "nextdns deactivate"
+ println
+ println "# Explore daemon logs:"
+ println "nextdns log"
+ println
+ println "# For more commands, use:"
+ println "nextdns help"
+ println
+}
+
+install_bin() {
+ bin_path=$NEXTDNS_BIN
+ if [ "$1" ]; then
+ bin_path=$1
+ fi
+ log_debug "Installing $INSTALL_RELEASE binary for $GOOS/$GOARCH to $bin_path"
+ case "$INSTALL_RELEASE" in
+ */*)
+ # Snapshot
+ branch=${INSTALL_RELEASE%/*}
+ hash=${INSTALL_RELEASE#*/}
+ url="https://snapshot.nextdns.io/${branch}/nextdns-${hash}_${GOOS}_${GOARCH}.tar.gz"
+ ;;
+ *)
+ url="https://github.com/nextdns/nextdns/releases/download/v${INSTALL_RELEASE}/nextdns_${INSTALL_RELEASE}_${GOOS}_${GOARCH}.tar.gz"
+ ;;
+ esac
+ log_debug "Downloading $url"
+ asroot mkdir -p "$(dirname "$bin_path")" &&
+ curl -sL "$url" | asroot sh -c "tar Ozxf - nextdns > \"$bin_path\"" &&
+ asroot chmod 755 "$bin_path"
+}
+
+upgrade_bin() {
+ tmp=$NEXTDNS_BIN.tmp
+ if install_bin "$tmp"; then
+ asroot "$NEXTDNS_BIN" uninstall
+ asroot mv "$tmp" "$NEXTDNS_BIN"
+ asroot "$NEXTDNS_BIN" install
+ fi
+ log_debug "Removing spurious temporary install file"
+ asroot rm -rf "$tmp"
+}
+
+uninstall_bin() {
+ asroot "$NEXTDNS_BIN" uninstall
+ asroot rm -f "$NEXTDNS_BIN"
+}
+
+install_rpm() {
+ asroot curl -Ls https://repo.nextdns.io/nextdns.repo -o /etc/yum.repos.d/nextdns.repo &&
+ asroot yum install -y nextdns
+}
+
+upgrade_rpm() {
+ asroot yum update -y nextdns
+}
+
+uninstall_rpm() {
+ asroot yum remove -y nextdns
+}
+
+install_zypper() {
+ if asroot zypper repos | grep -q nextdns >/dev/null; then
+ echo "Repository nextdns already exists. Skipping adding repository..."
+ else
+ asroot zypper ar -f -r https://repo.nextdns.io/nextdns.repo nextdns
+ fi
+ asroot zypper refresh && asroot zypper in -y nextdns
+}
+
+upgrade_zypper() {
+ asroot zypper up nextdns
+}
+
+uninstall_zypper() {
+ asroot zypper remove -y nextdns
+ case $(ask_bool 'Do you want to remove the repository from the repositories list?' true) in
+ true)
+ asroot zypper removerepo nextdns
+ ;;
+ esac
+}
+
+install_deb() {
+ if [ -f /etc/default/ubnt-dpkg-cache ]; then
+ # On UnifiOS 2, make sure the package is persisted over upgrades
+ sed -e '/^DPKG_CACHE_UBNT_PKGS+=" nextdns"/{:a;n;ba;q}' \
+ -e '$aDPKG_CACHE_UBNT_PKGS+=" nextdns"' \
+ -i /etc/default/ubnt-dpkg-cache
+ fi
+
+ install_deb_keyring &&
+ asroot sh -c 'echo "deb [signed-by=/etc/apt/keyrings/nextdns.gpg] https://repo.nextdns.io/deb stable main" > /etc/apt/sources.list.d/nextdns.list' &&
+ (dpkg --compare-versions $(dpkg-query --showformat='${Version}' --show apt) ge 1.1 ||
+ asroot ln -s /etc/apt/keyrings/nextdns.gpg /etc/apt/trusted.gpg.d/.) &&
+ (test "$OS" = "debian" && asroot apt-get -y install apt-transport-https || true) &&
+ asroot apt-get update &&
+ asroot apt-get install -y nextdns
+}
+
+install_deb_keyring() {
+ # Fallback on curl, some debian based distrib don't have wget while debian
+ # doesn't have curl by default.
+ asroot mkdir -p /etc/apt/keyrings
+ ( asroot wget -qO /etc/apt/keyrings/nextdns.gpg https://repo.nextdns.io/nextdns.gpg ||
+ asroot curl -sfL https://repo.nextdns.io/nextdns.gpg -o /etc/apt/keyrings/nextdns.gpg ) &&
+ asroot chmod 0644 /etc/apt/keyrings/nextdns.gpg
+}
+
+upgrade_deb() {
+ install_deb_keyring &&
+ asroot apt-get update &&
+ asroot apt-get install -y nextdns
+}
+
+uninstall_deb() {
+ asroot apt-get remove -y nextdns
+}
+
+install_apk() {
+ repo=https://repo.nextdns.io/apk
+ asroot wget -O /etc/apk/keys/nextdns.pub https://repo.nextdns.io/nextdns.pub &&
+ (grep -v $repo /etc/apk/repositories; echo $repo) | asroot tee /etc/apk/repositories >/dev/null &&
+ asroot apk update &&
+ asroot apk add nextdns
+}
+
+upgrade_apk() {
+ asroot apk update && asroot apk upgrade nextdns
+}
+
+uninstall_apk() {
+ asroot apk del nextdns
+}
+
+install_arch() {
+ asroot pacman -Sy yay &&
+ yay -Sy nextdns
+}
+
+upgrade_arch() {
+ yay -Suy nextdns
+}
+
+uninstall_arch() {
+ asroot pacman -R nextdns
+}
+
+install_merlin_path() {
+ # Add next to Merlin's path
+ mkdir -p /tmp/opt/sbin
+ ln -sf "$NEXTDNS_BIN" /tmp/opt/sbin/nextdns
+}
+
+install_merlin() {
+ if install_bin; then
+ install_merlin_path
+ fi
+}
+
+uninstall_merlin() {
+ uninstall_bin
+ rm -f /tmp/opt/sbin/nextdns
+}
+
+upgrade_merlin() {
+ if upgrade_bin; then
+ install_merlin_path
+ fi
+}
+
+install_openwrt() {
+ opkg update &&
+ opkg install nextdns
+ rt=$?
+ if [ $rt -eq 0 ]; then
+ case $(ask_bool 'Install the GUI?' true) in
+ true)
+ opkg install luci-app-nextdns
+ rt=$?
+ ;;
+ esac
+ fi
+ return $rt
+}
+
+upgrade_openwrt() {
+ opkg update &&
+ opkg upgrade nextdns
+}
+
+uninstall_openwrt() {
+ opkg remove nextdns
+}
+
+install_ddwrt() {
+ if [ "$(nvram get enable_jffs2)" = "0" ]; then
+ log_error "JFFS support not enabled"
+ log_info "To enabled JFFS:"
+ log_info " 1. On the router web page click on Administration."
+ log_info " 2. Scroll down until you see JFFS2 Support section."
+ log_info " 3. Click Enable JFFS."
+ log_info " 4. Click Save."
+ log_info " 5. Wait couple seconds, then click Apply."
+ log_info " 6. Wait again. Go back to the Enable JFFS section, and enable Clean JFFS."
+ log_info " 7. Do not click Save. Click Apply instead."
+ log_info " 8. Wait till you get the web-GUI back, then disable Clean JFFS again."
+ log_info " 9. Click Save."
+ log_info "10. Relaunch this installer."
+ exit 1
+ fi
+ mkdir -p /jffs/nextdns &&
+ openssl_get https://curl.haxx.se/ca/cacert.pem | http_body > /jffs/nextdns/ca.pem &&
+ install_bin
+}
+
+upgrade_ddwrt() {
+ upgrade_bin
+}
+
+uninstall_ddwrt() {
+ uninstall_bin
+ rm -rf /jffs/nextdns
+}
+
+install_brew() {
+ silent_exec brew install nextdns/tap/nextdns
+}
+
+upgrade_brew() {
+ silent_exec brew upgrade nextdns/tap/nextdns
+ asroot "$NEXTDNS_BIN" install
+}
+
+uninstall_brew() {
+ silent_exec brew uninstall nextdns/tap/nextdns
+}
+
+install_freebsd() {
+ # TODO: port install
+ install_bin
+}
+
+upgrade_freebsd() {
+ # TODO: port upgrade
+ upgrade_bin
+}
+
+uninstall_freebsd() {
+ # TODO: port uninstall
+ uninstall_bin
+}
+
+install_pfsense() {
+ # TODO: port install + UI
+ install_bin
+}
+
+upgrade_pfsense() {
+ # TODO: port upgrade
+ upgrade_bin
+}
+
+uninstall_pfsense() {
+ # TODO: port uninstall
+ uninstall_bin
+}
+
+install_opnsense() {
+ # TODO: port install + UI
+ install_bin
+}
+
+upgrade_opnsense() {
+ # TODO: port upgrade
+ upgrade_bin
+}
+
+uninstall_opnsense() {
+ # TODO: port uninstall
+ uninstall_bin
+}
+
+ubios_install_source() {
+ echo "deb [signed-by=/etc/apt/keyrings/nextdns.gpg] https://repo.nextdns.io/deb stable main" > /data/nextdns.list
+ podman exec unifi-os mv /data/nextdns.list /etc/apt/sources.list.d/nextdns.list
+ rm -f /tmp/nextdns.list
+ podman exec unifi-os apt-get install -y gnupg1 curl
+ podman exec unifi-os mkdir -p /etc/apt/keyrings/
+ podman exec unifi-os curl -sfL https://repo.nextdns.io/nextdns.gpg -o /etc/apt/keyrings/nextdns.gpg
+ podman exec unifi-os apt-get update -o Dir::Etc::sourcelist="sources.list.d/nextdns.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0"
+}
+
+install_ubios() {
+ ubios_install_source
+ podman exec unifi-os apt-get install -y nextdns
+}
+
+upgrade_ubios() {
+ ubios_install_source
+ podman exec unifi-os apt-get install --only-upgrade -y nextdns
+}
+
+uninstall_ubios() {
+ podman exec unifi-os apt-get remove -y nextdns
+}
+
+install_ubios_snapshot() {
+ branch=${INSTALL_RELEASE%/*}
+ hash=${INSTALL_RELEASE#*/}
+ url="https://snapshot.nextdns.io/${branch}/nextdns-${hash}_${GOOS}_${GOARCH}.tar.gz"
+ podman exec unifi-os sh -c "curl -o- $url | tar Ozxf - nextdns > /usr/bin/nextdns; /usr/bin/nextdns install"
+}
+
+upgrade_ubios_snapshot() {
+ /data/nextdns uninstall
+ install_ubios_snapshot
+}
+
+install_type() {
+ if [ "$FORCE_INSTALL_TYPE" ]; then
+ echo "$FORCE_INSTALL_TYPE"; return 0
+ fi
+ case "$INSTALL_RELEASE" in
+ */*)
+ case $OS in
+ ubios)
+ echo "ubios_snapshot"; return 0
+ ;;
+ *)
+ # Snapshot mode always use binary install
+ echo "bin"; return 0
+ ;;
+ esac
+ esac
+ case $OS in
+ centos|fedora|rhel)
+ echo "rpm"
+ ;;
+ opensuse-tumbleweed|opensuse-leap|opensuse)
+ echo "zypper"
+ ;;
+ debian|ubuntu|elementary|raspbian|linuxmint|pop|neon|sparky|vyos|Deepin)
+ echo "deb"
+ ;;
+ alpine)
+ echo "apk"
+ ;;
+ arch|manjaro|steamos)
+ #echo "arch" # TODO: fix AUR install
+ echo "bin"
+ ;;
+ openwrt)
+ # shellcheck disable=SC1091
+ . /etc/os-release
+ major=$(echo "$VERSION_ID" | cut -d. -f1)
+ case $major in
+ *[!0-9]*)
+ if [ "$VERSION_ID" = "19.07.0-rc1" ]; then
+ # No opkg support before 19.07.0-rc2
+ echo "bin"
+ else
+ # Likely 'snapshot' build in this case, but still > major version 19
+ echo "openwrt"
+ fi
+ ;;
+ *)
+ if [ "$major" -lt 19 ]; then
+ # No opkg support before 19.07.0-rc2
+ echo "bin"
+ else
+ echo "openwrt"
+ fi
+ ;;
+ esac
+ ;;
+ asuswrt-merlin)
+ echo "merlin"
+ ;;
+ edgeos|synology|clear-linux-os|solus|openbsd|netbsd|overthebox)
+ echo "bin"
+ ;;
+ ddwrt)
+ echo "ddwrt"
+ ;;
+ darwin)
+ if [ -x /usr/local/bin/brew ] || [ -x /opt/homebrew/bin/brew ]; then
+ echo "brew"
+ else
+ log_debug "Homebrew not installed, fallback on binary install"
+ echo "bin"
+ fi
+ ;;
+ freebsd)
+ echo "freebsd"
+ ;;
+ pfsense)
+ echo "pfsense"
+ ;;
+ opnsense)
+ echo "opnsense"
+ ;;
+ ubios)
+ echo "ubios"
+ ;;
+ gentoo)
+ echo "bin"
+ ;;
+ void)
+ # TODO: pkg for xbps
+ echo "bin"
+ ;;
+ *)
+ log_error "Unsupported installation for $(detect_os)"
+ return 1
+ ;;
+ esac
+}
+
+get_config() {
+ "$NEXTDNS_BIN" config | grep -E "^$1 " | cut -d' ' -f 2
+}
+
+get_config_bool() {
+ val=$(get_config "$1")
+ case $val in
+ true|false)
+ echo "$val"
+ ;;
+ esac
+ echo "$2"
+}
+
+get_profile_id() {
+ log_debug "Get profile ID"
+ if [ "$CONFIG_ID" ]; then
+ # backward compat
+ PROFILE_ID="$CONFIG_ID"
+ fi
+ while [ -z "$PROFILE_ID" ]; do
+ default=
+ prev_id=$(get_config profile)
+ if [ -z "$prev_id" ]; then
+ # backward compat
+ prev_id=$(get_config config)
+ fi
+ if [ "$prev_id" ]; then
+ log_debug "Previous profile ID: $prev_id"
+ default=" (default=$prev_id)"
+ fi
+ print "NextDNS Profile ID%s: " "$default"
+ read -r id
+ if [ -z "$id" ]; then
+ id=$prev_id
+ fi
+ if echo "$id" | grep -qE '^[0-9a-f]{6}$'; then
+ PROFILE_ID=$id
+ break
+ else
+ log_error "Invalid profile ID."
+ println
+ println "ID format is 6 alphanumerical lowercase characters (example: 123abc)."
+ println "Your ID can be found on the Setup tab of https://my.nextdns.io."
+ println
+ fi
+ done
+ echo "$PROFILE_ID"
+}
+
+log_debug() {
+ if [ "$DEBUG" = "1" ]; then
+ printf "\033[30;1mDEBUG: %s\033[0m\n" "$*" >&2
+ fi
+}
+
+log_info() {
+ printf "INFO: %s\n" "$*" >&2
+}
+
+log_warn() {
+ printf "\033[33mWARN: %s\033[0m\n" "$*" >&2
+}
+
+log_error() {
+ printf "\033[31mERROR: %s\033[0m\n" "$*" >&2
+}
+
+print() {
+ format=$1
+ if [ $# -gt 0 ]; then
+ shift
+ fi
+ # shellcheck disable=SC2059
+ printf "$format" "$@" >&2
+}
+
+println() {
+ format=$1
+ if [ $# -gt 0 ]; then
+ shift
+ fi
+ # shellcheck disable=SC2059
+ printf "$format\n" "$@" >&2
+}
+
+doc() {
+ # shellcheck disable=SC2059
+ printf "\033[30;1m%s\033[0m\n" "$*" >&2
+}
+
+menu() {
+ while true; do
+ n=0
+ default=
+ for item in "$@"; do
+ case $((n%3)) in
+ 0)
+ key=$item
+ if [ -z "$default" ]; then
+ default=$key
+ fi
+ ;;
+ 1)
+ echo "$key) $item"
+ ;;
+ esac
+ n=$((n+1))
+ done
+ print "Choice (default=%s): " "$default"
+ read -r choice
+ if [ -z "$choice" ]; then
+ choice=$default
+ fi
+ n=0
+ for item in "$@"; do
+ case $((n%3)) in
+ 0)
+ key=$item
+ ;;
+ 2)
+ if [ "$key" = "$choice" ]; then
+ if ! "$item"; then
+ log_error "$item: exit $?"
+ fi
+ break 2
+ fi
+ ;;
+ esac
+ n=$((n+1))
+ done
+ echo "Invalid choice"
+ done
+}
+
+ask_bool() {
+ msg=$1
+ default=$2
+ case $default in
+ true)
+ msg="$msg [Y|n]: "
+ ;;
+ false)
+ msg="$msg [y|N]: "
+ ;;
+ *)
+ msg="$msg (y/n): "
+ esac
+ while true; do
+ print "%s" "$msg"
+ read -r answer
+ if [ -z "$answer" ]; then
+ answer=$default
+ fi
+ case $answer in
+ y|Y|yes|YES|true)
+ echo "true"
+ return 0
+ ;;
+ n|N|no|NO|false)
+ echo "false"
+ return 0
+ ;;
+ *)
+ echo "Invalid input, use yes or no"
+ ;;
+ esac
+ done
+}
+
+detect_endiannes() {
+ if ! hexdump /dev/null 2>/dev/null; then
+ # Some firmwares do not contain hexdump, for those, try to detect endianness
+ # differently.
+ case $(cat /proc/cpuinfo) in
+ *BCM5300*)
+ # RT-AC66U does not support Merlin version over 380.70 which
+ # lacks hexdump command.
+ echo "le"
+ ;;
+ *)
+ log_error "Cannot determine endianness"
+ return 1
+ ;;
+ esac
+ return 0
+ fi
+ case $(hexdump -s 5 -n 1 -e '"%x"' /bin/sh | head -c1) in
+ 1)
+ echo "le"
+ ;;
+ 2)
+ echo ""
+ ;;
+ esac
+}
+
+detect_goarch() {
+ if [ "$FORCE_GOARCH" ]; then
+ echo "$FORCE_GOARCH"; return 0
+ fi
+ case $(uname -m) in
+ x86_64|amd64)
+ echo "amd64"
+ ;;
+ i386|i686)
+ echo "386"
+ ;;
+ arm)
+ # FreeBSD does not include arm version
+ case "$(sysctl -b hw.model 2>/dev/null)" in
+ *A9*)
+ echo "armv7"
+ ;;
+ *)
+ # Unknown version, fallback to the lowest
+ echo "armv5"
+ ;;
+ esac
+ ;;
+ armv5*)
+ echo "armv5"
+ ;;
+ armv6*|armv7*)
+ if grep -q vfp /proc/cpuinfo 2>/dev/null; then
+ echo "armv$(uname -m | sed -e 's/[[:alpha:]]//g')"
+ else
+ # Soft floating point
+ echo "armv5"
+ fi
+ ;;
+ aarch64)
+ case "$(uname -o 2>/dev/null)" in
+ ASUSWRT-Merlin*)
+ # XXX when using arm64 build on ASUS AC66U and ACG86U, we get Go error:
+ # "out of memory allocating heap arena metadata".
+ echo "armv7"
+ ;;
+ *)
+ echo "arm64"
+ ;;
+ esac
+ ;;
+ armv8*|arm64)
+ echo "arm64"
+ ;;
+ mips*)
+ # TODO: detect hardfloat
+ echo "$(uname -m)$(detect_endiannes)_softfloat"
+ ;;
+ *)
+ log_error "Unsupported GOARCH: $(uname -m)"
+ return 1
+ ;;
+ esac
+}
+
+detect_goos() {
+ if [ "$FORCE_GOOS" ]; then
+ echo "$FORCE_GOOS"; return 0
+ fi
+ case $(uname -s) in
+ Linux)
+ echo "linux"
+ ;;
+ Darwin)
+ echo "darwin"
+ ;;
+ FreeBSD)
+ echo "freebsd"
+ ;;
+ NetBSD)
+ echo "netbsd"
+ ;;
+ OpenBSD)
+ echo "openbsd"
+ ;;
+ *)
+ log_error "Unsupported GOOS: $(uname -s)"
+ return 1
+ esac
+}
+
+detect_os() {
+ if [ "$FORCE_OS" ]; then
+ echo "$FORCE_OS"; return 0
+ fi
+ case $(uname -s) in
+ Linux)
+ case $(uname -o) in
+ GNU/Linux|Linux)
+ if grep -q -e '^EdgeRouter' -e '^UniFiSecurityGateway' /etc/version 2> /dev/null; then
+ echo "edgeos"; return 0
+ fi
+ if uname -u 2>/dev/null | grep -q '^synology'; then
+ echo "synology"; return 0
+ fi
+ # shellcheck disable=SC1091
+ dist=$(. /etc/os-release; echo "$ID")
+ case $dist in
+ ubios)
+ if [ -z "$(command -v podman)" ]; then
+ log_error "This version of UnifiOS is not supported. Make sure you run version 1.7.0 or above."
+ return 1
+ fi
+ echo "$dist"; return 0
+ ;;
+ debian|ubuntu|elementary|raspbian|centos|fedora|rhel|arch|manjaro|openwrt|clear-linux-os|linuxmint|opensuse-tumbleweed|opensuse-leap|opensuse|solus|pop|neon|overthebox|sparky|vyos|void|alpine|Deepin|gentoo|steamos)
+ echo "$dist"; return 0
+ ;;
+ esac
+ # shellcheck disable=SC1091
+ for dist in $(. /etc/os-release; echo "$ID_LIKE"); do
+ case $dist in
+ debian|ubuntu|rhel|fedora|openwrt)
+ log_debug "Using ID_LIKE"
+ echo "$dist"; return 0
+ ;;
+ esac
+ done
+ ;;
+ ASUSWRT-Merlin*)
+ echo "asuswrt-merlin"; return 0
+ ;;
+ DD-WRT)
+ echo "ddwrt"; return 0
+ esac
+ ;;
+ Darwin)
+ echo "darwin"; return 0
+ ;;
+ FreeBSD)
+ if [ -f /etc/platform ]; then
+ case $(cat /etc/platform) in
+ pfSense)
+ echo "pfsense"; return 0
+ ;;
+ esac
+ fi
+ if [ -x /usr/local/sbin/opnsense-version ]; then
+ case $(/usr/local/sbin/opnsense-version -N) in
+ OPNsense)
+ echo "opnsense"; return 0
+ ;;
+ esac
+ fi
+ echo "freebsd"; return 0
+ ;;
+ NetBSD)
+ echo "netbsd"; return 0
+ ;;
+ OpenBSD)
+ echo "openbsd"; return 0
+ ;;
+ *)
+ esac
+ log_error "Unsupported OS: $(uname -o) $(grep ID "/etc/os-release" 2>/dev/null | xargs)"
+ return 1
+}
+
+guess_host_type() {
+ if [ -d /data/unifi ]; then
+ # Special case when installer is run from inside the ubios podman
+ echo "router"; return 0
+ fi
+
+ case $OS in
+ pfsense|opnsense|openwrt|asuswrt-merlin|edgeos|ddwrt|synology|overthebox|ubios)
+ echo "router"
+ ;;
+ darwin|steamos)
+ echo "workstation"
+ ;;
+ *)
+ echo "unsure"
+ ;;
+ esac
+}
+
+asroot() {
+ # Some platform (Merlin) do not have the "id" command and $USER report a non root username with uid 0.
+ if [ "$(grep '^Uid:' /proc/$$/status 2>/dev/null|cut -f2)" = "0" ] || [ "$USER" = "root" ] || [ "$(id -u 2>/dev/null)" = "0" ]; then
+ "$@"
+ elif [ "$(command -v sudo 2>/dev/null)" ]; then
+ sudo "$@"
+ else
+ echo "Root required"
+ su -m root -c "$*"
+ fi
+}
+
+silent_exec() {
+ if [ "$DEBUG" = 1 ]; then
+ "$@"
+ else
+ if ! out=$("$@" 2>&1); then
+ rt=$?
+ println "\033[30;1m%s\033[0m" "$out"
+ return $rt
+ fi
+ fi
+}
+
+bin_location() {
+ case $OS in
+ centos|fedora|rhel|debian|ubuntu|elementary|raspbian|arch|manjaro|clear-linux-os|linuxmint|opensuse-tumbleweed|opensuse-leap|opensuse|solus|pop|neon|sparky|vyos|void|alpine|Deepin|gentoo)
+ echo "/usr/bin/nextdns"
+ ;;
+ openwrt|overthebox)
+ echo "/usr/sbin/nextdns"
+ ;;
+ synology)
+ echo "/usr/local/bin/nextdns"
+ ;;
+ darwin)
+ echo "$(brew --prefix 2>/dev/null || echo /usr/local)/bin/nextdns"
+ ;;
+ asuswrt-merlin|ddwrt)
+ echo "/jffs/nextdns/nextdns"
+ ;;
+ freebsd|pfsense|opnsense|netbsd|openbsd)
+ echo "/usr/local/sbin/nextdns"
+ ;;
+ edgeos)
+ echo "/config/nextdns/nextdns"
+ ;;
+ ubios)
+ echo "/data/nextdns"
+ ;;
+ steamos)
+ echo "$HOME/.local/bin/nextdns"
+ ;;
+ *)
+ log_error "Unknown bin location for $OS"
+ ;;
+ esac
+}
+
+is_version_current() {
+ case "$INSTALL_RELEASE" in
+ */*)
+ # Snapshot
+ hash=${INSTALL_RELEASE#*/}
+ test "0.0.0-$hash" = "$CURRENT_RELEASE"
+ ;;
+ *)
+ test "$INSTALL_RELEASE" = "$CURRENT_RELEASE"
+ ;;
+ esac
+}
+
+get_current_release() {
+ if [ -x "$NEXTDNS_BIN" ]; then
+ $NEXTDNS_BIN version|cut -d' ' -f 3
+ fi
+}
+
+get_release() {
+ if [ "$NEXTDNS_VERSION" ]; then
+ echo "$NEXTDNS_VERSION"
+ else
+ for cmd in curl wget openssl true; do
+ # command is the "right" way but may be compiled out of busybox shell
+ ! command -v $cmd > /dev/null 2>&1 || break
+ ! which $cmd > /dev/null 2>&1 || break
+ done
+ case "$cmd" in
+ curl) cmd="curl -A curl -s" ;;
+ wget) cmd="wget -qO- -U curl" ;;
+ openssl) cmd="openssl_get" ;;
+ *)
+ log_error "Cannot retrieve latest version"
+ return
+ ;;
+ esac
+ v=$($cmd "https://api.github.com/repos/nextdns/nextdns/releases/latest" | \
+ grep '"tag_name":' | esed 's/.*"([^"]+)".*/\1/' | sed -e 's/^v//')
+ if [ -z "$v" ]; then
+ log_error "Cannot get latest version: $out"
+ fi
+ echo "$v"
+ fi
+}
+
+esed() {
+ if (echo | sed -E '' >/dev/null 2>&1); then
+ sed -E "$@"
+ else
+ sed -r "$@"
+ fi
+}
+
+http_redirect() {
+ while read -r header; do
+ case $header in
+ Location:*)
+ echo "${header#Location: }"
+ return
+ ;;
+ esac
+ if [ "$header" = "" ]; then
+ break
+ fi
+ done
+ cat > /dev/null
+ return 1
+}
+
+http_body() {
+ sed -n '/^\r/,$p' | sed 1d
+}
+
+openssl_get() {
+ host=${1#https://*} # https://dom.com/path -> dom.com/path
+ path=/${host#*/} # dom.com/path -> /path
+ host=${host%$path} # dom.com/path -> dom.com
+ printf "GET %s HTTP/1.0\nHost: %s\nUser-Agent: curl\n\n" "$path" "$host" |
+ openssl s_client -quiet -connect "$host:443" 2>/dev/null
+}
+
+umask 0022
+main
+#+end_src
diff --git a/blog/index.org b/blog/index.org
index 3c80bbb..a2c4420 100644
--- a/blog/index.org
+++ b/blog/index.org
@@ -4,7 +4,12 @@
Use =C-f= to search blog post titles for keywords.
* 2023
+:PROPERTIES:
+:ID: 21779F03-E65E-4A80-A958-3D08723EB8AD
+:PUBDATE: 2023-12-03 Sun 22:35
+:END:
+- 2023-12-03 [[./2023-12-03-unifi-nextdns.org][Installing NextDNS on the Unifi Dream Machine]]
- 2023-11-08 [[./2023-11-08-scli.org][Installing scli on Alpine Linux (musl)]]
- 2023-10-17 [[./2023-10-17-self-hosting-anonymousoverflow.org][Self-Hosting AnonymousOverflow]]
- 2023-10-15 [[./2023-10-15-alpine-ssh-hardening.org][SSH Hardening for Alpine Linux]]
@@ -33,6 +38,10 @@ Use =C-f= to search blog post titles for keywords.
- 2023-01-03 [[./2023-01-03-recent-website-changes.org][Recent Website Changes]]
* 2022
+:PROPERTIES:
+:ID: 3B281087-A3B6-46B7-8A29-77F74DAD5F15
+:PUBDATE: 2023-12-03 Sun 22:35
+:END:
- 2022-12-23 [[./2022-12-23-alpine-desktop.org][Alpine Linux as a Desktop OS]]
- 2022-12-17 [[./2022-12-17-st.org][Simple Terminal]]
@@ -76,6 +85,10 @@ Use =C-f= to search blog post titles for keywords.
- 2022-02-10 [[./2022-02-10-leaving-the-office.org][Leaving Office-Based Work In the Past]]
* 2021
+:PROPERTIES:
+:ID: 7603D51F-513F-4407-9CDC-F55C555D35D4
+:PUBDATE: 2023-12-03 Sun 22:35
+:END:
- 2021-12-04 [[./2021-12-04-cisa.org][I Passed the CISA!]]
- 2021-10-09 [[./2021-10-09-apache-redirect.org][Apache Redirect HTML Files to a Directory]]
@@ -95,6 +108,10 @@ Use =C-f= to search blog post titles for keywords.
- 2021-01-01 [[./2021-01-01-seum.org][SEUM: Speedrunners from Hell]]
* 2020
+:PROPERTIES:
+:ID: 8442803D-FB00-498D-9936-51029E80B367
+:PUBDATE: 2023-12-03 Sun 22:35
+:END:
- 2020-12-29 [[./2020-12-29-zork.org][Zork: Let's Explore a Classic]]
- 2020-12-28 [[./2020-12-28-neon-drive.org][Neon Drive: A Nostalgic 80s Arcade Racing Game]]
@@ -115,6 +132,10 @@ Use =C-f= to search blog post titles for keywords.
- 2020-01-25 [[./2020-01-25-linux-software.org][Linux Software]]
* 2019
+:PROPERTIES:
+:ID: CC0E4E85-6094-48AD-B78A-68DE97E56A17
+:PUBDATE: 2023-12-03 Sun 22:35
+:END:
- 2019-12-16 [[./2019-12-16-password-security.org][Password Security]]
- 2019-12-03 [[./2019-12-03-the-ansoff-matrix.org][The Ansoff Matrix]]
@@ -122,6 +143,10 @@ Use =C-f= to search blog post titles for keywords.
- 2019-01-07 [[./2019-01-07-useful-css.org][Useful CSS Snippets]]
* 2018
+:PROPERTIES:
+:ID: 4FE32AD6-AC36-43DD-ACEF-B2D98450FB2D
+:PUBDATE: 2023-12-03 Sun 22:35
+:END:
- 2018-12-08 [[./2018-12-08-aes-encryption.org][AES Encryption]]
- 2018-11-28 [[./2018-11-28-cpp-compiler.org][The C++ Compiler]]
diff --git a/blog/rss.org b/blog/rss.org
index fdddc88..79d96f6 100644
--- a/blog/rss.org
+++ b/blog/rss.org
@@ -1,5 +1,6 @@
#+TITLE: cleberg.net
+- [[file:2023-12-03-unifi-nextdns.org][How to Install NextDNS on the Unifi Dream Machine]]
- [[file:2021-03-28-vaporwave-vs-outrun.org][2021-03-28-vaporwave-vs-outrun]]
- [[file:2023-06-23-self-hosting-convos-irc.org][2023-06-23-self-hosting-convos-irc]]
- [[file:2020-07-26-business-analysis.org][Algorithmically Analyzing Local Businesses]]
@@ -66,7 +67,6 @@
- [[file:2022-02-20-nginx-caching.org][2022-02-20-nginx-caching]]
- [[file:2022-08-31-privacy.com-changes.org][2022-08-31-privacy.com-changes]]
- [[file:2022-03-02-note-taking.org][2022-03-02-note-taking]]
-- [[file:2023-11-12-consolefonts.org][2023-11-12-consolefonts]]
- [[file:2021-04-28-photography.org][2021-04-28-photography]]
- [[file:2020-09-22-internal-audit.org][What is Internal Audit?]]
- [[file:2022-07-25-curseradio.org][2022-07-25-curseradio]]