wren-linux / bin / secure-dns
#!/bin/bash
# secure-dns [status|on|off|toggle|login-check]: written by Wren Linux parts/secure-dns.sh
# Encrypted DNS (Unbound, DNSSEC, DNS over TLS) on or off. Off is for Wi-Fi
# with a sign-in page (cafés, hotels, trains): sign in, then switch it on
# again. While it is off, Wren Linux's Firefox encrypts its own lookups. The
# Wren menu's Secure DNS line does the same.
# login-check (at login, from sway and from ~/.bashrc on a text console): if
# the Wi-Fi sign-in window switched it off and it is still off (you logged
# out while that window was open, say), it says so. Switched off by you, it
# says nothing.
set -euo pipefail
SWITCH=/usr/local/libexec/wren-secure-dns
RESOLV=${WREN_RESOLV_CONF:-/etc/resolv.conf}
# Left by bin/wifi-signin while it has secure DNS off; gone once it is on again
LEFT_OFF=${XDG_STATE_HOME:-$HOME/.local/state}/wren/secure-dns-left-off
die() { printf 'secure-dns: %s\n' "$*" >&2; exit 1; }
state() { if grep -qsE '^# Written by Wren Linux (parts|extras)/secure-dns\.sh' "$RESOLV"; then echo on; else echo off; fi; }
cmd=${1:-status}
[ "$cmd" != toggle ] || { if [ "$(state)" = on ]; then cmd=off; else cmd=on; fi; }
case $cmd in
status) state ;;
on | off)
[ -x "$SWITCH" ] || die "it isn't set up. Run: wrenctl part secure-dns"
rc=0
err=$(mktemp)
# Without a password where the sudo rule allows that. Only trying tells:
# sudo -l also lists what you may run with a password (in the sudo group,
# everything). LC_ALL: sudo's refusal, in the words looked for below
LC_ALL=C sudo -n "$SWITCH" "$cmd" 2>"$err" || rc=$?
if [ "$rc" != 0 ] && grep -q 'password is required' "$err"; then
rm -f "$err"
# parts/secure-dns.sh: you chose that off asks for your password
[ -t 0 ] || die "switching it $cmd asks for your password (you chose that): run secure-dns $cmd in a terminal."
rc=0
sudo "$SWITCH" "$cmd" || rc=$?
else
cat "$err" >&2
rm -f "$err"
fi
if [ "$cmd" = on ] && [ "$rc" = 0 ]; then rm -f "$LEFT_OFF"; fi
exit "$rc" ;;
login-check)
[ -e "$LEFT_OFF" ] || exit 0
if [ "$(state)" = on ]; then
rm -f "$LEFT_OFF"
exit 0
fi
# A power cut in the sign-in, say: back on by itself. The switch puts it off again if names
# don't resolve (no network yet, so a few tries in the desktop, or a network that wants a
# sign-in). Only this: if you switched it off yourself, there is no such mark.
tries=1
if [ -n "${WAYLAND_DISPLAY:-}" ]; then tries=3; fi
while [ "$tries" -gt 0 ]; do
if sudo -n "$SWITCH" on >/dev/null 2>&1; then
rm -f "$LEFT_OFF"
exit 0
fi
tries=$((tries - 1))
if [ "$tries" -gt 0 ]; then sleep "${WREN_SECDNS_RETRY:-15}"; fi
done
msg="Secure DNS is still off: the Wi-Fi sign-in window switched it off and didn't get to switch it on again, and it couldn't come back by itself. Switch it on: the Wren menu's Secure DNS line, or secure-dns on."
if [ -n "${WAYLAND_DISPLAY:-}" ] && command -v notify-send >/dev/null; then
notify-send -a wren -u critical "Secure DNS is off" "$msg" 2>/dev/null || printf '%s\n' "$msg" >&2
else
printf '\n%s\n\n' "$msg" >&2
fi ;;
-h | --help) sed -n '2,10p' "$0" | sed 's/^# \{0,1\}//' ;;
*) die "usage: secure-dns [status|on|off|toggle|login-check]" ;;
esac