141 lines
4.3 KiB
Bash
Executable File
141 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Install a mkp224o-generated v3 key directory into the CyberLux HiddenServiceDir and restart Tor.
|
||
# Run with sudo after vanity-onion-mine.sh has produced a folder named *.onion under the output path.
|
||
#
|
||
# sudo bash scripts/install-vanity-onion-key.sh /path/to/var/vanity-mine
|
||
# sudo bash scripts/install-vanity-onion-key.sh /path/to/specificXXXX.onion
|
||
#
|
||
# If the path is a parent with several *.onion children, one is chosen automatically
|
||
# (default: first in lexicographic order). Override with:
|
||
# CYBERLUX_VANITY_PICK=latest — use the directory with the newest mtime
|
||
# CYBERLUX_VANITY_PICK=first — same as default (first sorted A–Z)
|
||
# Or pass a direct path to a single ... .onion folder.
|
||
#
|
||
set -euo pipefail
|
||
[[ "${EUID}" -eq 0 ]] || { echo "Run as root (sudo)."; exit 1; }
|
||
|
||
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
||
TOR_DIRS_FILE="${REPO}/scripts/generated/tor-dirs.txt"
|
||
ARG="${1:-}"
|
||
|
||
if [[ -z "${ARG}" ]]; then
|
||
echo "Usage: sudo bash $0 <vanity_out_dir|path_to_name.onion_dir>"
|
||
exit 1
|
||
fi
|
||
|
||
# If ARG is relative, prefer REPO/ARG (so `var/vanity-mine` works from any cwd when using this repo).
|
||
if [[ "${ARG}" != /* && -d "${REPO}/${ARG}" ]]; then
|
||
ARG="${REPO}/${ARG}"
|
||
fi
|
||
|
||
if [[ ! -f "${TOR_DIRS_FILE}" ]]; then
|
||
echo "Missing ${TOR_DIRS_FILE}. Run: cd ${REPO} && node scripts/generate-onion-config.cjs"
|
||
exit 1
|
||
fi
|
||
|
||
# Resolve single torDir (CyberLux uses "cyberlux" in onion-nodes.json)
|
||
TOR_DIR_NAME="$(head -1 "${TOR_DIRS_FILE}" | tr -d '\r\n')"
|
||
if [[ -z "${TOR_DIR_NAME}" ]]; then
|
||
echo "Empty ${TOR_DIRS_FILE}"
|
||
exit 1
|
||
fi
|
||
|
||
HS_ROOT="/var/lib/tor/${TOR_DIR_NAME}"
|
||
KEY_SRC=""
|
||
|
||
if [[ -d "${ARG}" ]]; then
|
||
if [[ -f "${ARG}/hs_ed25519_secret_key" ]]; then
|
||
KEY_SRC="${ARG}"
|
||
else
|
||
# Pick a *.onion child (one or many)
|
||
mapfile -t kids < <(find "${ARG}" -maxdepth 1 -type d -name '*.onion' 2>/dev/null | sort)
|
||
if [[ "${#kids[@]}" -eq 1 ]]; then
|
||
KEY_SRC="${kids[0]}"
|
||
elif [[ "${#kids[@]}" -eq 0 ]]; then
|
||
echo "No subdirectory matching *.onion under ${ARG} and no key at top level."
|
||
exit 1
|
||
else
|
||
pick="${CYBERLUX_VANITY_PICK:-first}"
|
||
case "${pick}" in
|
||
first)
|
||
KEY_SRC="${kids[0]}"
|
||
echo "[*] ${#kids[@]} *.onion key dirs; using first (lexicographic): ${KEY_SRC}"
|
||
;;
|
||
latest|newest)
|
||
latest=""
|
||
latest_m=0
|
||
for d in "${kids[@]}"; do
|
||
m="$(stat -c %Y "${d}" 2>/dev/null || echo 0)"
|
||
if (( m >= latest_m )); then
|
||
latest_m="${m}"
|
||
latest="${d}"
|
||
fi
|
||
done
|
||
KEY_SRC="${latest}"
|
||
echo "[*] ${#kids[@]} *.onion key dirs; using latest mtime: ${KEY_SRC}"
|
||
;;
|
||
*)
|
||
echo "Unknown CYBERLUX_VANITY_PICK=${pick} (use first or latest)."
|
||
exit 1
|
||
;;
|
||
esac
|
||
fi
|
||
fi
|
||
else
|
||
echo "Not a directory: ${ARG}"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ ! -f "${KEY_SRC}/hs_ed25519_secret_key" ]]; then
|
||
echo "No hs_ed25519_secret_key in ${KEY_SRC}"
|
||
exit 1
|
||
fi
|
||
|
||
TOR_USER=""
|
||
for u in debian-tor tor _tor; do
|
||
if id -u "${u}" &>/dev/null; then
|
||
TOR_USER="${u}"
|
||
break
|
||
fi
|
||
done
|
||
if [[ -z "${TOR_USER}" ]]; then
|
||
echo "No Tor system user (tried debian-tor, tor, _tor). Install Tor."
|
||
exit 1
|
||
fi
|
||
|
||
TS="$(date +%s)"
|
||
if [[ -d "${HS_ROOT}" ]]; then
|
||
echo "[*] Preserving current service dir as ${HS_ROOT}.stale.${TS}"
|
||
mv "${HS_ROOT}" "${HS_ROOT}.stale.${TS}"
|
||
fi
|
||
|
||
mkdir -p "${HS_ROOT}"
|
||
shopt -s dotglob nullglob
|
||
for item in "${KEY_SRC}"/*; do
|
||
base="$(basename "${item}")"
|
||
[[ "${base}" == "." || "${base}" == ".." ]] && continue
|
||
cp -a "${item}" "${HS_ROOT}/"
|
||
done
|
||
shopt -u dotglob nullglob
|
||
|
||
chown -R "${TOR_USER}:${TOR_USER}" "${HS_ROOT}"
|
||
chmod -R u+rwX,og-rwx "${HS_ROOT}"
|
||
chmod 0700 "${HS_ROOT}"
|
||
|
||
restart_tor() {
|
||
systemctl restart tor@default.service 2>/dev/null || systemctl restart tor
|
||
}
|
||
|
||
echo "[*] Installed key material into ${HS_ROOT} (onion: $(tr -d '\n' < "${HS_ROOT}/hostname" 2>/dev/null || echo '?'))"
|
||
restart_tor
|
||
|
||
if [[ -f "${REPO}/scripts/export-onion-urls.sh" ]]; then
|
||
bash "${REPO}/scripts/export-onion-urls.sh" || true
|
||
fi
|
||
if [[ -f "${REPO}/scripts/backup-onion-keys.sh" ]]; then
|
||
bash "${REPO}/scripts/backup-onion-keys.sh" || true
|
||
fi
|
||
|
||
echo "[*] Done. Open: http://$(tr -d '\n' < "${HS_ROOT}/hostname") (in Tor Browser)"
|
||
echo "[*] Old keys (if any): ${HS_ROOT}.stale.${TS}"
|