110 lines
3.4 KiB
Shell
110 lines
3.4 KiB
Shell
|
|
#!/usr/bin/env bash
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
if [[ "$(id -u)" -ne 0 ]]; then
|
||
|
|
echo "INSTALL_REQUIRES_ROOT" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
SOURCE_DIR="${1:-}"
|
||
|
|
TUNNEL_PUBLIC_KEY_FILE="${2:-}"
|
||
|
|
if [[ -z "$SOURCE_DIR" || ! -f "$SOURCE_DIR/deploy/guanghulab-zhulan.nginx.conf" ]]; then
|
||
|
|
echo "SOURCE_DIR_INVALID" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
if [[ -z "$TUNNEL_PUBLIC_KEY_FILE" || ! -f "$TUNNEL_PUBLIC_KEY_FILE" ]]; then
|
||
|
|
echo "TUNNEL_PUBLIC_KEY_FILE_INVALID" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
EXPECTED_HOST="${ZHULAN_EXPECTED_HOST:-VM-0-16-ubuntu}"
|
||
|
|
EXPECTED_DMI="${ZHULAN_EXPECTED_DMI:-b2ecf109-1999-4643-b223-e67e24d7667d}"
|
||
|
|
ACTUAL_HOST="$(hostname)"
|
||
|
|
ACTUAL_DMI="$(tr '[:upper:]' '[:lower:]' </sys/class/dmi/id/product_uuid)"
|
||
|
|
if [[ "$ACTUAL_HOST" != "$EXPECTED_HOST" || "$ACTUAL_DMI" != "$EXPECTED_DMI" ]]; then
|
||
|
|
echo "TARGET_IDENTITY_MISMATCH" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
SITE_FILE="/etc/nginx/sites-enabled/guanghulab"
|
||
|
|
SNIPPET_FILE="/etc/nginx/snippets/guanghu-zhulan.conf"
|
||
|
|
SSHD_DROPIN="/etc/ssh/sshd_config.d/80-zhulan-proxy.conf"
|
||
|
|
PROXY_HOME="/var/lib/guanghu/zhulan-proxy"
|
||
|
|
AUTH_KEYS="$PROXY_HOME/.ssh/authorized_keys"
|
||
|
|
BACKUP_ROOT="/var/backups/guanghu/zhulan-front"
|
||
|
|
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
|
||
|
|
|
||
|
|
if [[ ! -f "$SITE_FILE" ]]; then
|
||
|
|
echo "GUANGHULAB_SITE_NOT_FOUND" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
if ! grep -q 'include /etc/nginx/snippets/guanghu-ai-discovery.conf;' "$SITE_FILE"; then
|
||
|
|
echo "GUANGHULAB_INCLUDE_ANCHOR_NOT_FOUND" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
getent passwd zhulan-proxy >/dev/null || {
|
||
|
|
echo "PROXY_USER_MUST_BE_PRECREATED" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
PUBLIC_KEY="$(tr -d '\r\n' <"$TUNNEL_PUBLIC_KEY_FILE")"
|
||
|
|
if [[ "$PUBLIC_KEY" != ssh-ed25519\ * ]]; then
|
||
|
|
echo "TUNNEL_PUBLIC_KEY_NOT_ED25519" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
install -d -o root -g root -m 0700 "$BACKUP_ROOT"
|
||
|
|
install -m 0644 "$SITE_FILE" "$BACKUP_ROOT/guanghulab-$STAMP"
|
||
|
|
[[ ! -f "$SNIPPET_FILE" ]] || install -m 0644 "$SNIPPET_FILE" "$BACKUP_ROOT/snippet-$STAMP"
|
||
|
|
[[ ! -f "$SSHD_DROPIN" ]] || install -m 0600 "$SSHD_DROPIN" "$BACKUP_ROOT/sshd-$STAMP"
|
||
|
|
|
||
|
|
install -d -o zhulan-proxy -g zhulan-proxy -m 0700 "$PROXY_HOME" "$PROXY_HOME/.ssh"
|
||
|
|
{
|
||
|
|
printf '%s %s\n' \
|
||
|
|
'restrict,port-forwarding,permitlisten="127.0.0.1:17631"' \
|
||
|
|
"$PUBLIC_KEY"
|
||
|
|
} >"$AUTH_KEYS.tmp"
|
||
|
|
chown zhulan-proxy:zhulan-proxy "$AUTH_KEYS.tmp"
|
||
|
|
chmod 0600 "$AUTH_KEYS.tmp"
|
||
|
|
mv "$AUTH_KEYS.tmp" "$AUTH_KEYS"
|
||
|
|
|
||
|
|
cat >"$SSHD_DROPIN.tmp" <<'EOF'
|
||
|
|
Match User zhulan-proxy
|
||
|
|
AuthenticationMethods publickey
|
||
|
|
PasswordAuthentication no
|
||
|
|
KbdInteractiveAuthentication no
|
||
|
|
AllowAgentForwarding no
|
||
|
|
AllowTcpForwarding remote
|
||
|
|
GatewayPorts no
|
||
|
|
PermitListen 127.0.0.1:17631
|
||
|
|
PermitOpen none
|
||
|
|
PermitTTY no
|
||
|
|
X11Forwarding no
|
||
|
|
PermitTunnel no
|
||
|
|
PermitUserRC no
|
||
|
|
MaxSessions 0
|
||
|
|
EOF
|
||
|
|
chown root:root "$SSHD_DROPIN.tmp"
|
||
|
|
chmod 0600 "$SSHD_DROPIN.tmp"
|
||
|
|
mv "$SSHD_DROPIN.tmp" "$SSHD_DROPIN"
|
||
|
|
sshd -t
|
||
|
|
|
||
|
|
install -o root -g root -m 0644 \
|
||
|
|
"$SOURCE_DIR/deploy/guanghulab-zhulan.nginx.conf" "$SNIPPET_FILE"
|
||
|
|
if ! grep -q 'include /etc/nginx/snippets/guanghu-zhulan.conf;' "$SITE_FILE"; then
|
||
|
|
sed -i \
|
||
|
|
'/include \/etc\/nginx\/snippets\/guanghu-ai-discovery.conf;/a\ include /etc/nginx/snippets/guanghu-zhulan.conf;' \
|
||
|
|
"$SITE_FILE"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if ! nginx -t; then
|
||
|
|
install -m 0644 "$BACKUP_ROOT/guanghulab-$STAMP" "$SITE_FILE"
|
||
|
|
nginx -t
|
||
|
|
echo "NGINX_VALIDATION_FAILED_ROLLED_BACK" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
systemctl reload ssh
|
||
|
|
systemctl reload nginx
|
||
|
|
printf '{"schema":"guanghu.zhulan-front-install-receipt/v1","development_id":"DEV-20260813-005","front_node":"BS-GZ-006","role":"DOMAIN_TLS_REVERSE_PROXY_ONLY","listener":"127.0.0.1:17631","installed_at":"%s"}\n' "$STAMP"
|