Created
June 2, 2020 22:49
-
-
Save sheatsb/5f079a1d460833933f342911bfb6be70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| main() { | |
| OS=$(detect_os) | |
| GOARCH=$(detect_goarch) | |
| GOOS=$(detect_goos) | |
| NEXTDNS_BIN=$(bin_location) | |
| LATEST_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 "LATEST_RELEASE: $LATEST_RELEASE" | |
| if [ -z "$OS" ] || [ -z "$GOARCH" ] || [ -z "$GOOS" ] || [ -z "$NEXTDNS_BIN" ] || [ -z "$LATEST_RELEASE" ]; then | |
| log_error "Cannot detect running environment." | |
| exit 1 | |
| fi | |
| while true; do | |
| CURRENT_RELEASE=$(get_current_release) | |
| log_debug "Start install loop with CURRENT_RELEASE=$CURRENT_RELEASE" | |
| if [ "$CURRENT_RELEASE" ]; then | |
| if [ "$CURRENT_RELEASE" != "$LATEST_RELEASE" ]; then | |
| log_debug "NextDNS is out of date ($CURRENT_RELEASE != $LATEST_RELEASE)" | |
| menu \ | |
| u "Upgrade NextDNS from $CURRENT_RELEASE to $LATEST_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 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 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 | |
| } | |
| configure() { | |
| log_debug "Start configure" | |
| 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") | |
| } | |
| add_arg config "$(get_config_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 | |
| doc "Only use DNS servers located in jurisdictions with strong privacy laws." | |
| doc "This may increase latency." | |
| add_arg_bool_ask hardened-privacy 'Enable hardened privacy mode (may increase latency)?' | |
| 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 you 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 | |
| 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 | |
| # 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 approriate option." | |
| println | |
| println "You can use the nextdns command to control the daemon." | |
| println "Here is 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 $LATEST_RELEASE binary for $GOOS/$GOARCH to $bin_path" | |
| url="https://github.com/nextdns/nextdns/releases/download/v${LATEST_RELEASE}/nextdns_${LATEST_RELEASE}_${GOOS}_${GOARCH}.tar.gz" | |
| log_debug "Downloading $url" | |
| 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 -s https://nextdns.io/yum.repo -o /etc/yum.repos.d/nextdns.repo && | |
| asroot yum install -y nextdns | |
| } | |
| upgrade_rpm() { | |
| asroot yum update -y nextdns | |
| } | |
| uninstall_rpm() { | |
| asroot yum uninstall -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 https://dl.bintray.com/nextdns/rpm/ 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() { | |
| # Fallback on curl, some debian based distrib don't have wget while debian | |
| # doesn't have curl by default. | |
| ( wget -qO - https://nextdns.io/repo.gpg || curl -sfL https://nextdns.io/repo.gpg ) | asroot apt-key add - && | |
| asroot sh -c 'echo "deb https://nextdns.io/repo/deb stable main" > /etc/apt/sources.list.d/nextdns.list' && | |
| (test "$OS" = "debian" && asroot apt-get install apt-transport-https || true) && | |
| asroot apt-get update && | |
| asroot apt-get install -y nextdns | |
| } | |
| upgrade_deb() { | |
| asroot apt-get update && | |
| asroot apt-get upgrade -y nextdns | |
| } | |
| uninstall_deb() { | |
| log_debug "Uninstalling NextDNS" | |
| asroot apt-get remove -y 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 | |
| } | |
| install_type() { | |
| if [ "$FORCE_INSTALL_TYPE" ]; then | |
| echo "$FORCE_INSTALL_TYPE"; return 0 | |
| fi | |
| case $OS in | |
| centos|fedora|rhel) | |
| echo "rpm" | |
| ;; | |
| opensuse-tumbleweed|opensuse) | |
| echo "zypper" | |
| ;; | |
| debian|ubuntu|elementary|raspbian|linuxmint|pop|neon) | |
| echo "deb" | |
| ;; | |
| arch|manjaro) | |
| #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' bulid 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 ]; 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" | |
| ;; | |
| *) | |
| 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_config_id() { | |
| log_debug "Get configuration ID" | |
| while [ -z "$CONFIG_ID" ]; do | |
| default= | |
| prev_id=$(get_config config) | |
| if [ "$prev_id" ]; then | |
| log_debug "Previous config ID: $prev_id" | |
| default=" (default=$prev_id)" | |
| fi | |
| print "NextDNS Configuration ID%s: " "$default" | |
| read -r id | |
| if [ -z "$id" ]; then | |
| id=$prev_id | |
| fi | |
| if echo "$id" | grep -qE '^[0-9a-f]{6}$'; then | |
| CONFIG_ID=$id | |
| break | |
| else | |
| log_error "Invalid configuration 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 "$CONFIG_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_error() { | |
| printf "\033[31mERROR: %s\033[0m\n" "$*" >&2 | |
| } | |
| print() { | |
| format=$1; shift | |
| # shellcheck disable=SC2059 | |
| printf "$format" "$@" >&2 | |
| } | |
| println() { | |
| format=$1; shift | |
| # 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 firmware do not contain hexdump, for those, try to detect endiannes | |
| # differently | |
| case $(cat /proc/cpuinfo) in | |
| *BCM5300*) | |
| # RT-AC66U does not support merlin version over 380.70 which | |
| # lack hexdump command. | |
| echo "le" | |
| ;; | |
| *) | |
| log_error "Cannot determine endiannes" | |
| 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) | |
| 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 | |
| debian|ubuntu|elementary|raspbian|centos|fedora|rhel|arch|manjaro|openwrt|clear-linux-os|linuxmint|opensuse-tumbleweed|opensuse|solus|pop|neon|overthebox) | |
| echo "$dist"; return 0 | |
| ;; | |
| esac | |
| ;; | |
| 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 -s)" | |
| return 1 | |
| } | |
| guess_host_type() { | |
| case $OS in | |
| pfsense|opnsense|openwrt|asuswrt-merlin|edgeos|ddwrt|synology|overthebox) | |
| echo "router" | |
| ;; | |
| darwin) | |
| 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|solus|pop|neon) | |
| echo "/usr/bin/nextdns" | |
| ;; | |
| openwrt|overthebox) | |
| echo "/usr/sbin/nextdns" | |
| ;; | |
| darwin|synology) | |
| 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" | |
| ;; | |
| *) | |
| log_error "Unknown bin location for $OS" | |
| ;; | |
| 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 | |
| curl="curl -s" | |
| if [ -z "$(command -v curl 2>/dev/null)" ]; then | |
| curl="openssl_get" | |
| fi | |
| $curl "https://api.github.com/repos/nextdns/nextdns/releases/latest" | | |
| grep '"tag_name":' | | |
| esed 's/.*"([^"]+)".*/\1/' | | |
| sed -e 's/^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 | |
| } | |
| main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment