更新 setup-relay.sh
This commit is contained in:
+76
-29
@@ -56,7 +56,38 @@ ask_secret() {
|
||||
done
|
||||
}
|
||||
|
||||
generate_secret() {
|
||||
parse_existing_env() {
|
||||
# parse_existing_env <relay.env path>
|
||||
# Sets EX_* variables from an existing relay.env file.
|
||||
local envfile="$1"
|
||||
[[ -f "$envfile" ]] || return 1
|
||||
|
||||
_get() { grep -m1 "^${1}=" "$envfile" 2>/dev/null | cut -d= -f2- || true; }
|
||||
|
||||
EX_LOG_LEVEL="$(_get NB_LOG_LEVEL)"
|
||||
EX_AUTH_SECRET="$(_get NB_AUTH_SECRET)"
|
||||
EX_LE_EMAIL="$(_get NB_LETSENCRYPT_EMAIL)"
|
||||
EX_CERT_FILE="$(_get NB_TLS_CERT_FILE)"
|
||||
EX_KEY_FILE="$(_get NB_TLS_KEY_FILE)"
|
||||
EX_ENABLE_STUN="$(_get NB_ENABLE_STUN)"
|
||||
EX_STUN_PORTS="$(_get NB_STUN_PORTS)"
|
||||
|
||||
# Parse domain and port from NB_EXPOSED_ADDRESS=rels://domain:port
|
||||
local exposed; exposed="$(_get NB_EXPOSED_ADDRESS)"
|
||||
EX_DOMAIN="${exposed#rels://}"; EX_DOMAIN="${EX_DOMAIN%%:*}"
|
||||
EX_LISTEN_PORT="${exposed##*:}"
|
||||
|
||||
# Detect TLS mode
|
||||
local le_domains; le_domains="$(_get NB_LETSENCRYPT_DOMAINS)"
|
||||
if [[ -n "$le_domains" ]]; then
|
||||
EX_TLS_MODE="1"
|
||||
elif [[ -n "$EX_CERT_FILE" ]]; then
|
||||
EX_TLS_MODE="2" # could be self-signed, but treat as existing cert
|
||||
else
|
||||
EX_TLS_MODE="1" # fallback
|
||||
fi
|
||||
}
|
||||
|
||||
if command -v openssl &>/dev/null; then
|
||||
openssl rand -base64 32
|
||||
else
|
||||
@@ -104,7 +135,17 @@ header "Step 1 · Authentication Secret"
|
||||
echo "All relay servers AND your main NetBird server must share the same secret."
|
||||
echo ""
|
||||
|
||||
if ask_yn "Generate a new random secret automatically?" "y"; then
|
||||
# Try to pre-read an existing secret from /opt/netbird-relay/relay.env
|
||||
_PREREAD_SECRET=""
|
||||
if [[ -f "/opt/netbird-relay/relay.env" ]]; then
|
||||
_PREREAD_SECRET="$(grep -m1 '^NB_AUTH_SECRET=' /opt/netbird-relay/relay.env 2>/dev/null | cut -d= -f2- || true)"
|
||||
fi
|
||||
|
||||
if [[ -n "$_PREREAD_SECRET" ]]; then
|
||||
info "Found existing secret in /opt/netbird-relay/relay.env"
|
||||
ask AUTH_SECRET "Keep existing secret or enter a new one" "$_PREREAD_SECRET"
|
||||
success "Using secret."
|
||||
elif ask_yn "Generate a new random secret automatically?" "y"; then
|
||||
AUTH_SECRET="$(generate_secret)"
|
||||
success "Generated secret: ${BOLD}${AUTH_SECRET}${RESET}"
|
||||
warn "Save this — you'll need it for every relay and your main server config."
|
||||
@@ -136,23 +177,36 @@ for (( i=1; i<=RELAY_COUNT; i++ )); do
|
||||
|
||||
header "Step 3.$i · Relay Server #${i}"
|
||||
|
||||
# ── Output directory (ask first so we can read existing config) ───────────
|
||||
ask RELAY_DIR " Output directory for this relay's files" "/opt/netbird-relay"
|
||||
|
||||
# ── Load existing config as defaults if relay.env is present ─────────────
|
||||
EX_DOMAIN=""; EX_LISTEN_PORT="443"; EX_LOG_LEVEL="info"
|
||||
EX_AUTH_SECRET=""; EX_LE_EMAIL=""; EX_CERT_FILE=""; EX_KEY_FILE=""
|
||||
EX_ENABLE_STUN="true"; EX_STUN_PORTS="3478"; EX_TLS_MODE="1"
|
||||
_EXISTING_ENV="${RELAY_DIR}/relay.env"
|
||||
if parse_existing_env "$_EXISTING_ENV"; then
|
||||
info " Found existing config in ${_EXISTING_ENV} — using as defaults."
|
||||
fi
|
||||
|
||||
# ── Domain ────────────────────────────────────────────────────────────────
|
||||
while true; do
|
||||
ask DOMAIN " Domain name (e.g. relay-us.example.com)" ""
|
||||
ask DOMAIN " Domain name (e.g. relay-us.example.com)" "${EX_DOMAIN}"
|
||||
if validate_domain "$DOMAIN"; then break
|
||||
else warn " That doesn't look like a valid domain. Try again."; fi
|
||||
done
|
||||
RELAY_DOMAINS+=("$DOMAIN")
|
||||
|
||||
# ── Listen & exposed ports ────────────────────────────────────────────────
|
||||
ask LISTEN_PORT " HTTPS listen port" "443"
|
||||
ask LOG_LEVEL " Log level (debug/info/warn/error)" "info"
|
||||
ask LISTEN_PORT " HTTPS listen port" "${EX_LISTEN_PORT:-443}"
|
||||
ask LOG_LEVEL " Log level (debug/info/warn/error)" "${EX_LOG_LEVEL:-info}"
|
||||
|
||||
# ── STUN ──────────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
if ask_yn " Enable embedded STUN server?" "y"; then
|
||||
_STUN_DEFAULT="y"; [[ "${EX_ENABLE_STUN}" == "false" ]] && _STUN_DEFAULT="n"
|
||||
if ask_yn " Enable embedded STUN server?" "$_STUN_DEFAULT"; then
|
||||
ENABLE_STUN=true
|
||||
ask STUN_PORTS " STUN port(s) — comma-separated for multiple (e.g. 3478,3479)" "3478"
|
||||
ask STUN_PORTS " STUN port(s) — comma-separated for multiple (e.g. 3478,3479)" "${EX_STUN_PORTS:-3478}"
|
||||
else
|
||||
ENABLE_STUN=false
|
||||
STUN_PORTS=""
|
||||
@@ -164,22 +218,28 @@ for (( i=1; i<=RELAY_COUNT; i++ )); do
|
||||
echo " 1) Let's Encrypt (automatic — server needs port 80/tcp open)"
|
||||
echo " 2) Existing certificates (wildcard / own CA)"
|
||||
echo " 3) Self-signed certificate (generated by this script)"
|
||||
ask TLS_MODE " Choose [1/2/3]" "1"
|
||||
ask TLS_MODE " Choose [1/2/3]" "${EX_TLS_MODE:-1}"
|
||||
|
||||
if [[ "$TLS_MODE" == "1" ]]; then
|
||||
ask LE_EMAIL " Let's Encrypt email" ""
|
||||
ask LE_EMAIL " Let's Encrypt email" "${EX_LE_EMAIL}"
|
||||
LE_DATA_DIR="/data/letsencrypt"
|
||||
CERT_HOST_PATH=""; CERT_FILE=""; KEY_FILE=""; SELFSIGN_DAYS=""
|
||||
CERT_HOST_PATH=""; CERT_FILE=""; KEY_FILE=""
|
||||
elif [[ "$TLS_MODE" == "2" ]]; then
|
||||
ask CERT_HOST_PATH " Host path to certs directory" "/opt/1panel/www/sites/${DOMAIN}/ssl"
|
||||
ask CERT_FILE " Cert file path inside container" "/certs/fullchain.pem"
|
||||
ask KEY_FILE " Key file path inside container" "/certs/privkey.pem"
|
||||
LE_EMAIL=""; LE_DATA_DIR=""; SELFSIGN_DAYS=""
|
||||
# Derive existing host path from cert file path stored in env (best-effort)
|
||||
_EX_CERT_HOST=""
|
||||
[[ -n "$EX_CERT_FILE" ]] && _EX_CERT_HOST="$(
|
||||
grep -m1 'volumes:' -A5 "${RELAY_DIR}/docker-compose.yml" 2>/dev/null \
|
||||
| grep -m1 ':/certs:ro\|:/certs ' \
|
||||
| awk -F: '{print $1}' | sed 's/^ *- *//' || true
|
||||
)"
|
||||
ask CERT_HOST_PATH " Host path to certs directory" "${_EX_CERT_HOST:-/opt/1panel/www/sites/${DOMAIN}/ssl}"
|
||||
ask CERT_FILE " Cert file path inside container" "${EX_CERT_FILE:-/certs/fullchain.pem}"
|
||||
ask KEY_FILE " Key file path inside container" "${EX_KEY_FILE:-/certs/privkey.pem}"
|
||||
LE_EMAIL=""; LE_DATA_DIR=""
|
||||
else
|
||||
echo ""
|
||||
echo " ── Self-signed certificate details ──"
|
||||
|
||||
# Subject fields
|
||||
ask SS_CN " Common Name (CN)" "${DOMAIN}"
|
||||
ask SS_O " Organization (O)" ""
|
||||
ask SS_OU " Organizational Unit (OU)" ""
|
||||
@@ -187,7 +247,6 @@ for (( i=1; i<=RELAY_COUNT; i++ )); do
|
||||
ask SS_ST " State / Province (ST)" ""
|
||||
ask SS_L " Locality / City (L)" ""
|
||||
|
||||
# SANs — domain always included, allow adding more
|
||||
SS_SANS="DNS:${DOMAIN}"
|
||||
echo ""
|
||||
echo " Subject Alternative Names (SANs):"
|
||||
@@ -200,10 +259,8 @@ for (( i=1; i<=RELAY_COUNT; i++ )); do
|
||||
SS_SANS+=",${_san}"
|
||||
done
|
||||
|
||||
# Validity
|
||||
ask SS_DAYS " Certificate validity (days)" "3650"
|
||||
|
||||
# Key type
|
||||
echo ""
|
||||
echo " Key type:"
|
||||
echo " 1) RSA"
|
||||
@@ -229,7 +286,6 @@ for (( i=1; i<=RELAY_COUNT; i++ )); do
|
||||
esac
|
||||
fi
|
||||
|
||||
# Build subject string (only include non-empty fields)
|
||||
SS_SUBJ=""
|
||||
[[ -n "$SS_C" ]] && SS_SUBJ+="/C=${SS_C}"
|
||||
[[ -n "$SS_ST" ]] && SS_SUBJ+="/ST=${SS_ST}"
|
||||
@@ -238,20 +294,11 @@ for (( i=1; i<=RELAY_COUNT; i++ )); do
|
||||
[[ -n "$SS_OU" ]] && SS_SUBJ+="/OU=${SS_OU}"
|
||||
SS_SUBJ+="/CN=${SS_CN}"
|
||||
|
||||
CERT_HOST_PATH="" # filled in after RELAY_DIR is known
|
||||
CERT_HOST_PATH=""
|
||||
CERT_FILE="/certs/fullchain.pem"
|
||||
KEY_FILE="/certs/privkey.pem"
|
||||
LE_EMAIL=""; LE_DATA_DIR=""
|
||||
fi
|
||||
|
||||
# ── Output directory ──────────────────────────────────────────────────────
|
||||
_DEFAULT_RELAY_DIR="/opt/netbird-relay"
|
||||
# If the default dir already has relay files, surface it as the default so
|
||||
# the user can confirm with Enter rather than retyping the path.
|
||||
if [[ -f "${_DEFAULT_RELAY_DIR}/relay.env" || -f "${_DEFAULT_RELAY_DIR}/docker-compose.yml" ]]; then
|
||||
warn " ${_DEFAULT_RELAY_DIR} already contains relay files (will be overwritten if confirmed)."
|
||||
fi
|
||||
ask RELAY_DIR " Output directory for this relay's files" "${_DEFAULT_RELAY_DIR}"
|
||||
# For self-signed mode, certs live inside the relay dir
|
||||
[[ "$TLS_MODE" == "3" ]] && CERT_HOST_PATH="${RELAY_DIR}/certs"
|
||||
RELAY_DIRS+=("$RELAY_DIR")
|
||||
|
||||
Reference in New Issue
Block a user