#!/usr/bin/env bash
# setup-onion.sh — Tor Hidden Service lab (ch.10)
# ---------------------------------------------------------------------------
# Publishes a hardened v3 .onion in front of a local Nginx, configured so the
# box does not leak: Nginx binds 127.0.0.1 ONLY, access logs off, no version
# string; Tor runs onion-only (no SOCKS, no relay) with scrubbed logging.
# Run as root:  ./setup-onion.sh [local_port]
# ---------------------------------------------------------------------------
set -uo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
print_header(){ echo -e "\n${GREEN}=== $1 ===${NC}"; }
die(){ echo -e "${RED}[x] $1${NC}"; exit 1; }
[[ ${EUID:-$(id -u)} -eq 0 ]] || die "Run as root."
export DEBIAN_FRONTEND=noninteractive
PORT="${1:-8080}"
HS_DIR="/var/lib/tor/lab_hs"

print_header "Installing Tor + Nginx"
apt-get update -qq
apt-get install -y tor nginx curl || die "package install failed"

print_header "Local site on 127.0.0.1:${PORT} (never the clearnet)"
install -d /var/www/onion
echo "<!doctype html><title>onion</title><h1>Served over Tor.</h1>" > /var/www/onion/index.html
cat > /etc/nginx/sites-available/onion <<EOF
server {
    listen 127.0.0.1:${PORT};       # loopback ONLY — never 0.0.0.0
    server_name _;
    root /var/www/onion;
    index index.html;
    server_tokens off;
    access_log off;                 # privacy: keep no visitor logs
    location ~ /\. { deny all; }
}
EOF
ln -sf /etc/nginx/sites-available/onion /etc/nginx/sites-enabled/onion
nginx -t || die "nginx config test failed"
systemctl reload nginx

print_header "Configuring the hardened v3 hidden service"
install -d -m 0700 -o debian-tor -g debian-tor "$HS_DIR"
if ! grep -q "$HS_DIR" /etc/tor/torrc; then
cat >> /etc/tor/torrc <<EOF

# --- lab hidden service (v3), hardened ---
HiddenServiceDir ${HS_DIR}
HiddenServicePort 80 127.0.0.1:${PORT}
SocksPort 0                 # client SOCKS off — onion service only
SafeLogging 1               # scrub IPs from Tor logs
EOF
fi

print_header "Leak check"
if ss -ltn 2>/dev/null | grep -qE "(0\.0\.0\.0|\[::\]|\*):${PORT}\b"; then
  echo -e "${RED}[!] ${PORT} is listening on a PUBLIC interface — fix before exposing.${NC}"
else
  echo -e "${GREEN}[+] ${PORT} is loopback-only.${NC}"
fi

print_header "Starting Tor"
systemctl restart tor
for _ in $(seq 1 15); do [ -s "${HS_DIR}/hostname" ] && break; sleep 1; done
[ -s "${HS_DIR}/hostname" ] || die "hidden service did not come up — check: journalctl -u tor"
ONION="$(cat "${HS_DIR}/hostname")"

print_header "Done"
echo -e "${GREEN}Your v3 onion:${NC}  ${ONION}"
echo    "Test it:  apt-get install -y torsocks && torsocks curl -s http://${ONION}/ | head"
echo -e "${YELLOW}Read next: Vanguards (guard-discovery defence), client authorization"
echo -e "(HiddenServiceAuthorizeClient), OnionBalance for scale. Never run a relay here.${NC}"
echo    "Keep ${HS_DIR} at 0700 owned by debian-tor; the private key there IS the onion."
