wren-linux / bin / onion-site
#!/bin/bash
# onion-site [start|stop|status|shell|upload|update|address|rebuild]
# written by Wren Linux extras/onion-site.sh
# Your onion site, which runs in its own VM with no network: only Tor on this
# computer reaches it, so nothing the site does can give away your address.
# onion-site start start the site's VM (the site is up while it runs)
# onion-site stop stop it (the site is down)
# onion-site status is it running?
# onion-site address the site's .onion address
# onion-site upload static FOLDER FOLDER becomes the site's files (/srv/site/static)
# onion-site upload app FOLDER FOLDER becomes the app (/srv/site/app; Python: app.py)
# onion-site shell a shell in the VM, as the site's user
# onion-site update the VM's security updates, through Tor
# onion-site rebuild throw the VM away and build a fresh one
# (the .onion address stays; the site's files don't)
set -euo pipefail
AGENT=onion-site
SESSION=/usr/local/libexec/onion-site-session
ADDRESS=${XDG_STATE_HOME:-$HOME/.local/state}/wren/onion-site-address
die() { printf 'onion-site: %s\n' "$*" >&2; exit 1; }
[ "$(id -u)" -ne 0 ] || die "run it as your normal user, not root."
cmd=${1:-}
case "$cmd" in
start | stop | status | shell | update | rebuild) ;;
upload)
case ${2:-} in static | app) ;; *) die "upload what? onion-site upload static FOLDER, or upload app FOLDER" ;; esac
[ -d "${3:-}" ] || die "no folder '${3:-}'. onion-site upload ${2} FOLDER"
;;
address)
[ -s "$ADDRESS" ] || die "no address saved here. Run: wrenctl install onion-site"
cat "$ADDRESS"
exit 0 ;;
-h | --help | "")
sed -n '2,16p' "$0" | sed 's/^# \{0,1\}//'
[ -n "$cmd" ] || exit 2
exit 0 ;;
*) die "unknown command '$cmd'. Try: onion-site --help" ;;
esac
sudo -n -u "$AGENT" -l "$SESSION" >/dev/null 2>&1 ||
die "the onion site isn't set up. Run: wrenctl install onion-site"
# The site needs both its VM and this computer's tor service; say so when tor
# isn't running, which is the usual reason the address can't be reached
if [ "$cmd" = start ] || [ "$cmd" = status ]; then
if ! systemctl is-active --quiet tor@default.service 2>/dev/null; then
printf 'onion-site: Tor is not running on this computer, so the site cannot be reached.\n' >&2
printf ' Start it (and at every boot): sudo systemctl enable --now tor.service tor@default.service\n' >&2
fi
fi
if [ "$cmd" = upload ]; then
# No shared folder: the files go to the VM as one stream (owner and
# permissions of yours aren't carried over, nor when you edited a file,
# which the site would show visitors; .git isn't sent: it names its authors)
tar -C "$3" --owner=0 --group=0 --exclude=.git --mtime='2000-01-01 00:00:00 UTC' -cf - . | sudo -n -u "$AGENT" "$SESSION" upload "$2"
exit
fi
exec sudo -n -u "$AGENT" "$SESSION" "$cmd"