#!/usr/bin/env bash set -euo pipefail if [[ "$(id -u)" -ne 0 ]]; then echo "INSTALL_REQUIRES_ROOT" >&2 exit 1 fi FRONT_HOST="${1:-}" KNOWN_HOSTS_SOURCE="${2:-}" if [[ ! "$FRONT_HOST" =~ ^[0-9A-Fa-f:.]+$ ]]; then echo "FRONT_HOST_MUST_BE_LITERAL_IP" >&2 exit 1 fi if [[ -z "$KNOWN_HOSTS_SOURCE" || ! -f "$KNOWN_HOSTS_SOURCE" ]]; then echo "KNOWN_HOSTS_SOURCE_INVALID" >&2 exit 1 fi EXPECTED_HOST="${ZHULAN_EXPECTED_HOST:-VM-12-12-ubuntu}" EXPECTED_DMI="${ZHULAN_EXPECTED_DMI:-7a500f2d-9aed-4b93-b3b8-59c87c65d031}" ACTUAL_HOST="$(hostname)" ACTUAL_DMI="$(tr '[:upper:]' '[:lower:]' &2 exit 1 fi CONFIG_ROOT="/etc/guanghu/zhulan-front-tunnel" KEY_FILE="$CONFIG_ROOT/id_ed25519" KNOWN_HOSTS="$CONFIG_ROOT/known_hosts" SSH_CONFIG="$CONFIG_ROOT/ssh_config" SERVICE_FILE="/etc/systemd/system/zhulan-front-tunnel.service" if [[ ! -f "$KEY_FILE" || ! -f "$KEY_FILE.pub" ]]; then echo "TUNNEL_IDENTITY_NOT_PREPARED" >&2 exit 1 fi if ! getent passwd zhulan-tunnel >/dev/null; then echo "TUNNEL_USER_NOT_PREPARED" >&2 exit 1 fi install -o root -g zhulan-tunnel -m 0640 "$KNOWN_HOSTS_SOURCE" "$KNOWN_HOSTS" if ! ssh-keygen -F "$FRONT_HOST" -f "$KNOWN_HOSTS" >/dev/null; then echo "PINNED_FRONT_HOST_KEY_MISSING" >&2 exit 1 fi EXPECTED_FRONT_HOST_KEY="${ZHULAN_EXPECTED_FRONT_HOST_KEY:-SHA256:P2EtuYFg8hptha4s0auP4yzp+Wg+H27bw4mdqzk1Cvk}" ACTUAL_FRONT_HOST_KEY="$(ssh-keygen -F "$FRONT_HOST" -f "$KNOWN_HOSTS" | awk 'NF && $1 !~ /^#/ {print $2, $3}' | ssh-keygen -lf - 2>/dev/null | awk '{print $2}' | head -1)" if [[ "$ACTUAL_FRONT_HOST_KEY" != "$EXPECTED_FRONT_HOST_KEY" ]]; then echo "PINNED_FRONT_HOST_KEY_MISMATCH" >&2 exit 1 fi cat >"$SSH_CONFIG.tmp" <"$SERVICE_FILE.tmp" <<'EOF' [Unit] Description=Zhulan SG003 to GZ006 loopback-only reverse proxy tunnel After=network-online.target zhulan-remote-cell.service Wants=network-online.target Requires=zhulan-remote-cell.service [Service] Type=simple User=zhulan-tunnel Group=zhulan-tunnel ExecStart=/usr/bin/ssh -F /etc/guanghu/zhulan-front-tunnel/ssh_config -NT guanghu-zhulan-front Restart=always RestartSec=5 UMask=0077 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true RestrictSUIDSGID=true LockPersonality=true MemoryDenyWriteExecute=true RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 ReadOnlyPaths=/etc/guanghu/zhulan-front-tunnel StateDirectory=guanghu/zhulan-front-tunnel [Install] WantedBy=multi-user.target EOF chown root:root "$SERVICE_FILE.tmp" chmod 0644 "$SERVICE_FILE.tmp" mv "$SERVICE_FILE.tmp" "$SERVICE_FILE" systemctl daemon-reload systemctl enable --now zhulan-front-tunnel.service for _ in $(seq 1 20); do if systemctl is-active --quiet zhulan-front-tunnel.service; then systemctl show zhulan-front-tunnel.service -p ActiveState -p SubState -p MainPID exit 0 fi sleep 1 done systemctl status zhulan-front-tunnel.service --no-pager >&2 || true exit 1