generated from ztimson/template
149 lines
5.8 KiB
Bash
149 lines
5.8 KiB
Bash
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
SCRIPT_URL="https://git.zakscode.com/ztimson/fallback-ap/raw/branch/master/fallback-ap.sh"
|
|
INSTALL_PATH="/usr/local/bin/fallback-ap"
|
|
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "This installer needs to run as root, e.g.:"
|
|
echo " curl -sL https://git.zakscode.com/ztimson/fallback-ap/raw/branch/master/install.sh | sudo bash"
|
|
exit 1
|
|
fi
|
|
|
|
# Ask a question; Enter accepts the default.
|
|
prompt() {
|
|
local __var="$1" __question="$2" __default="$3" __answer=""
|
|
read -r -p "$__question [$__default]: " __answer < /dev/tty || __answer=""
|
|
printf -v "$__var" '%s' "${__answer:-$__default}"
|
|
}
|
|
|
|
# Like prompt, but "blank" is a legitimate value. Enter accepts the default;
|
|
# typing the clear word (e.g. "all" or "none") sets the value to empty.
|
|
prompt_blankable() {
|
|
local __var="$1" __question="$2" __default="$3" __clear="$4" __answer=""
|
|
read -r -p "$__question [${__default:-$__clear}]: " __answer < /dev/tty || __answer=""
|
|
|
|
case "$__answer" in
|
|
"") __answer="$__default" ;;
|
|
"$__clear") __answer="" ;;
|
|
esac
|
|
|
|
printf -v "$__var" '%s' "${__answer// /}"
|
|
}
|
|
|
|
# Ask until the answer is one of the allowed choices. Enter accepts the default.
|
|
prompt_choice() {
|
|
local __var="$1" __question="$2" __default="$3" __answer="" __opt
|
|
shift 3
|
|
|
|
while true; do
|
|
read -r -p "$__question [$__default]: " __answer < /dev/tty || __answer=""
|
|
__answer="${__answer:-$__default}"
|
|
|
|
for __opt in "$@"; do
|
|
if [ "$__answer" = "$__opt" ]; then
|
|
printf -v "$__var" '%s' "$__answer"
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
echo " Please enter one of: $*"
|
|
done
|
|
}
|
|
|
|
# Lists wireless interfaces (those with a /sys/class/net/<iface>/wireless dir).
|
|
detect_wireless() {
|
|
local dir
|
|
for dir in /sys/class/net/*; do
|
|
if [ -d "$dir/wireless" ]; then
|
|
basename "$dir"
|
|
fi
|
|
done
|
|
}
|
|
|
|
EXISTING_CONFIG="/etc/fallback-ap.conf"
|
|
|
|
if [ -f "$EXISTING_CONFIG" ]; then
|
|
# shellcheck disable=SC1090
|
|
source "$EXISTING_CONFIG"
|
|
fi
|
|
|
|
DETECTED_WIFI="$(detect_wireless | tr '\n' ' ')"
|
|
DETECTED_WIFI="${DETECTED_WIFI% }"
|
|
|
|
DEFAULT_SSID="${SAVED_SSID:-$(hostname)}"
|
|
DEFAULT_PASSWORD="${SAVED_PASSWORD:-abcd1234}"
|
|
DEFAULT_IFACE="${SAVED_IFACE:-${DETECTED_WIFI%% *}}"
|
|
DEFAULT_IFACE="${DEFAULT_IFACE:-wlan0}"
|
|
DEFAULT_CIDR="${SAVED_CIDR:-10.10.10.1/24}"
|
|
DEFAULT_DHCP_START_OCTET="${SAVED_DHCP_START_OCTET:-100}"
|
|
DEFAULT_DHCP_END_OCTET="${SAVED_DHCP_END_OCTET:-250}"
|
|
DEFAULT_MONITOR_IFACE="${SAVED_MONITOR_IFACE-}"
|
|
DEFAULT_IGNORE_IFACE="${SAVED_IGNORE_IFACE-}"
|
|
DEFAULT_CHECK_MODE="${SAVED_CHECK_MODE:-link}"
|
|
DEFAULT_CHECK_TARGETS="${SAVED_CHECK_TARGETS:-1.1.1.1 8.8.8.8}"
|
|
|
|
# --- Access point ----------------------------------------------------------------------------------------------------
|
|
|
|
[ -z "${FALLBACK_AP_SSID:-}" ] && prompt FALLBACK_AP_SSID "Access point SSID" "$DEFAULT_SSID"
|
|
[ -z "${FALLBACK_AP_PASSWORD:-}" ] && prompt FALLBACK_AP_PASSWORD "Access point passphrase" "$DEFAULT_PASSWORD"
|
|
|
|
if [ -z "${FALLBACK_AP_IFACE:-}" ]; then
|
|
if [ -n "$DETECTED_WIFI" ]; then
|
|
echo "Detected Wi-Fi interfaces: $DETECTED_WIFI"
|
|
fi
|
|
prompt FALLBACK_AP_IFACE "Interface to create the access point on" "$DEFAULT_IFACE"
|
|
fi
|
|
|
|
[ -z "${FALLBACK_AP_CIDR:-}" ] && prompt FALLBACK_AP_CIDR "Access point subnet (CIDR)" "$DEFAULT_CIDR"
|
|
[ -z "${FALLBACK_AP_DHCP_START_OCTET:-}" ] && prompt FALLBACK_AP_DHCP_START_OCTET "DHCP range start (last octet)" "$DEFAULT_DHCP_START_OCTET"
|
|
[ -z "${FALLBACK_AP_DHCP_END_OCTET:-}" ] && prompt FALLBACK_AP_DHCP_END_OCTET "DHCP range end (last octet)" "$DEFAULT_DHCP_END_OCTET"
|
|
|
|
# --- Connectivity monitoring -----------------------------------------------------------------------------------------
|
|
#
|
|
# The AP only starts when none of the monitored interfaces are online, and it
|
|
# is only ever created on the interface chosen above.
|
|
#
|
|
# These use "unset" (not "empty") to decide whether to ask, because an empty
|
|
# FALLBACK_AP_MONITOR_IFACE / FALLBACK_AP_IGNORE_IFACE is a valid answer
|
|
# meaning "all real interfaces" / "ignore nothing".
|
|
|
|
if [ -z "${FALLBACK_AP_MONITOR_IFACE+x}" ]; then
|
|
echo
|
|
echo "Which interfaces should count as 'online'? Enter a comma-separated list"
|
|
echo "(e.g. eth0,wlan0), or 'all' for every real interface. Virtual interfaces"
|
|
echo "(docker, veth, bridges, VPNs) are skipped automatically."
|
|
prompt_blankable FALLBACK_AP_MONITOR_IFACE "Interfaces to monitor" "$DEFAULT_MONITOR_IFACE" "all"
|
|
fi
|
|
|
|
if [ -z "$FALLBACK_AP_MONITOR_IFACE" ] && [ -z "${FALLBACK_AP_IGNORE_IFACE+x}" ]; then
|
|
echo
|
|
echo "Any physical interfaces to ignore (globs allowed, e.g. enx*,usb0)?"
|
|
prompt_blankable FALLBACK_AP_IGNORE_IFACE "Interfaces to ignore" "$DEFAULT_IGNORE_IFACE" "none"
|
|
fi
|
|
|
|
if [ -z "${FALLBACK_AP_CHECK_MODE:-}" ]; then
|
|
echo
|
|
echo "How should 'online' be determined?"
|
|
echo " link - the interface is connected (an upstream outage keeps the AP off)"
|
|
echo " internet - the interface is connected AND can ping out"
|
|
prompt_choice FALLBACK_AP_CHECK_MODE "Check mode" "$DEFAULT_CHECK_MODE" link internet
|
|
fi
|
|
|
|
if [ "$FALLBACK_AP_CHECK_MODE" = "internet" ] && [ -z "${FALLBACK_AP_CHECK_TARGETS:-}" ]; then
|
|
prompt FALLBACK_AP_CHECK_TARGETS "Hosts to ping (space-separated)" "$DEFAULT_CHECK_TARGETS"
|
|
fi
|
|
|
|
export FALLBACK_AP_SSID FALLBACK_AP_PASSWORD FALLBACK_AP_IFACE FALLBACK_AP_CIDR FALLBACK_AP_DHCP_START_OCTET FALLBACK_AP_DHCP_END_OCTET
|
|
export FALLBACK_AP_CHECK_MODE
|
|
[ -n "${FALLBACK_AP_MONITOR_IFACE+x}" ] && export FALLBACK_AP_MONITOR_IFACE
|
|
[ -n "${FALLBACK_AP_IGNORE_IFACE+x}" ] && export FALLBACK_AP_IGNORE_IFACE
|
|
[ -n "${FALLBACK_AP_CHECK_TARGETS+x}" ] && export FALLBACK_AP_CHECK_TARGETS
|
|
|
|
echo
|
|
echo "Downloading fallback-ap..."
|
|
curl -fsSL "$SCRIPT_URL" -o "$INSTALL_PATH"
|
|
chmod +x "$INSTALL_PATH"
|
|
echo "Running installer..."
|
|
"$INSTALL_PATH" install |