diff options
Diffstat (limited to 'blog/2023-12-03-unifi-nextdns.org')
-rw-r--r-- | blog/2023-12-03-unifi-nextdns.org | 1275 |
1 files changed, 0 insertions, 1275 deletions
diff --git a/blog/2023-12-03-unifi-nextdns.org b/blog/2023-12-03-unifi-nextdns.org deleted file mode 100644 index 4d790f9..0000000 --- a/blog/2023-12-03-unifi-nextdns.org +++ /dev/null @@ -1,1275 +0,0 @@ -#+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_src - -*** 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 |