Files
dark-lord/scripts/install-tor-onion.sh
2026-04-26 22:28:40 -07:00

140 lines
4.5 KiB
Bash
Executable File

#!/bin/bash
# Run with sudo: sudo bash scripts/install-tor-onion.sh
# Regenerates Tor + nginx from scripts/onion-nodes.json, installs configs only when
# they changed, restores backed-up onion keys if any service dirs are missing, and
# starts/restarts nginx + Tor only when required.
set -euo pipefail
[[ "${EUID}" -eq 0 ]] || { echo "Run as root (sudo)."; exit 1; }
REPO="$(cd "$(dirname "$0")/.." && pwd)"
TORRC="/etc/tor/torrc"
TOR_INCLUDE="/etc/tor/cyberlux-nodes.conf"
if ! command -v node >/dev/null 2>&1; then
echo "node is required to run scripts/generate-onion-config.cjs"
exit 1
fi
install_if_changed() {
local src="$1" dest="$2" mode="$3"
if [[ -f "${dest}" ]] && cmp -s "${src}" "${dest}"; then
return 1
fi
install -m "${mode}" "${src}" "${dest}"
return 0
}
tor_is_active() {
systemctl is-active --quiet tor@default.service 2>/dev/null || systemctl is-active --quiet tor 2>/dev/null
}
nginx_is_active() {
systemctl is-active --quiet nginx 2>/dev/null
}
restart_tor() {
systemctl restart tor@default.service 2>/dev/null || systemctl restart tor
}
start_tor() {
systemctl start tor@default.service 2>/dev/null || systemctl start tor
}
node "${REPO}/scripts/generate-onion-config.cjs"
mkdir -p /etc/tor /etc/nginx/conf.d /etc/nginx/sites-available /etc/nginx/sites-enabled
touch "${TORRC}"
tor_changed=0
nginx_changed=0
if install_if_changed "${REPO}/tor/cyberlux-nodes.conf" "${TOR_INCLUDE}" 0644; then
tor_changed=1
fi
if grep -qF '%include /etc/tor/cyberlux-onion.conf' "${TORRC}"; then
sed -i '\|%include /etc/tor/cyberlux-onion.conf|d' "${TORRC}"
tor_changed=1
fi
if ! grep -qF "${TOR_INCLUDE}" "${TORRC}"; then
printf '\n%%include %s\n' "${TOR_INCLUDE}" >> "${TORRC}"
tor_changed=1
fi
if install_if_changed "${REPO}/nginx/cyberlux-ddos-zones.conf" /etc/nginx/conf.d/cyberlux-ddos-zones.conf 0644; then
nginx_changed=1
fi
if install_if_changed "${REPO}/nginx/cyberlux-server-common.inc" /etc/nginx/cyberlux-server-common.inc 0644; then
nginx_changed=1
fi
if install_if_changed "${REPO}/nginx.example.conf" /etc/nginx/sites-available/cyberlux-onion 0644; then
nginx_changed=1
fi
ln -sf /etc/nginx/sites-available/cyberlux-onion /etc/nginx/sites-enabled/cyberlux-onion
if [[ -x "${REPO}/scripts/restore-onion-keys.sh" ]]; then
bash "${REPO}/scripts/restore-onion-keys.sh"
fi
nginx -t
if command -v tor >/dev/null 2>&1; then
tor --verify-config -f "${TORRC}" >/dev/null
fi
if (( nginx_changed )); then
systemctl reload nginx 2>/dev/null || systemctl restart nginx
elif ! nginx_is_active; then
systemctl start nginx
fi
if (( tor_changed )); then
restart_tor
elif ! tor_is_active; then
start_tor
fi
# Hidden services proxy to nginx → Next on 127.0.0.1:3000. If Next is down, every .onion returns 502.
if command -v curl >/dev/null 2>&1; then
up="$(curl -g -sS -o /dev/null -w "%{http_code}" --connect-timeout 2 --max-time 5 "http://127.0.0.1:3000/" 2>/dev/null)" || up="000"
if [[ ! "${up}" =~ ^(200|301|302|304)$ ]]; then
echo "[!] Next.js is not serving on 127.0.0.1:3000 (HTTP ${up}) — onion URLs will fail until it is running." >&2
echo " Start: cd ${REPO} && npm run start:onion or: sudo systemctl start cyberlux.service" >&2
echo " Install service: sudo CYBERLUX_USER=\${SUDO_USER:-\$USER} bash ${REPO}/scripts/install-systemd.sh" >&2
fi
fi
# Refresh repo-root onion-urls.txt while we have root (hostname dirs are 0700 debian-tor).
if [[ -f "${REPO}/scripts/export-onion-urls.sh" ]]; then
bash "${REPO}/scripts/export-onion-urls.sh" || true
fi
if [[ "${CYBERLUX_INSTALL_QUIET:-}" == "1" ]]; then
exit 0
fi
echo ""
echo "CyberLux Tor nodes (see hostname files):"
while IFS= read -r dir || [[ -n "${dir}" ]]; do
[[ -z "${dir}" ]] && continue
f="/var/lib/tor/${dir}/hostname"
if [[ -f "$f" ]]; then
echo " ${dir}: http://$(tr -d '\n' < "$f")"
else
echo " ${dir}: (generating…) sudo cat $f"
fi
done < "${REPO}/scripts/generated/tor-dirs.txt"
echo ""
echo "Config status:"
echo " • Tor: $([[ ${tor_changed} -eq 1 ]] && echo changed || echo unchanged)"
echo " • nginx: $([[ ${nginx_changed} -eq 1 ]] && echo changed || echo unchanged)"
echo ""
echo "Host hardening:"
echo " • Next: npm run start:onion (127.0.0.1:3000)"
echo " • Do not expose 3000 or nginx loopback ports to the public internet."
echo " • Onion key backup set: /var/backups/cyberlux-onion-keys/current"
echo " • Optional: sudo bash ${REPO}/scripts/classroom-ufw.sh"
echo ""
echo "Start app: cd ${REPO} && ./start.sh or npm run build && npm run start:onion"