fix: SSH accept-new and DOMAIN_SUFFIX configuration for edge control
- Changed SSH StrictHostKeyChecking from 'no' to 'accept-new' for better security - Fixed .env write logic with proper deduplication before appending - Fixed deregister .env cleanup to use single grep pattern - Added --domain-suffix option to install.sh - Removed no-op DOMAIN_SUFFIX sed from install.sh - Changed cp -n to cp for idempotent script updates - Fixed authorized_keys.sh SCRIPT_DIR to point to lib/ - Fixed Caddy route management to use POST /routes instead of /load - Fixed Caddy remove_route to find route by host match, not hardcoded index
This commit is contained in:
parent
637ea66a5a
commit
cf3c63bf68
4 changed files with 82 additions and 69 deletions
15
bin/disinto
15
bin/disinto
|
|
@ -1693,7 +1693,7 @@ disinto_edge() {
|
||||||
# SSH to edge host and register
|
# SSH to edge host and register
|
||||||
echo "Registering tunnel for ${project} on ${edge_host}..."
|
echo "Registering tunnel for ${project} on ${edge_host}..."
|
||||||
local response
|
local response
|
||||||
response=$(ssh -o StrictHostKeyChecking=no -o BatchMode=yes \
|
response=$(ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes \
|
||||||
"disinto-register@${edge_host}" \
|
"disinto-register@${edge_host}" \
|
||||||
"register ${project} ${pubkey}" 2>&1) || {
|
"register ${project} ${pubkey}" 2>&1) || {
|
||||||
echo "Error: failed to register tunnel" >&2
|
echo "Error: failed to register tunnel" >&2
|
||||||
|
|
@ -1712,7 +1712,14 @@ disinto_edge() {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Write to .env
|
# Write to .env (replace existing entries to avoid duplicates)
|
||||||
|
local tmp_env
|
||||||
|
tmp_env=$(mktemp)
|
||||||
|
grep -v "^EDGE_TUNNEL_HOST=" "$env_file" > "$tmp_env" 2>/dev/null || true
|
||||||
|
grep -v "^EDGE_TUNNEL_PORT=" "$env_file" >> "$tmp_env" 2>/dev/null || true
|
||||||
|
grep -v "^EDGE_TUNNEL_FQDN=" "$env_file" >> "$tmp_env" 2>/dev/null || true
|
||||||
|
cat "$tmp_env" > "$env_file"
|
||||||
|
rm -f "$tmp_env"
|
||||||
echo "EDGE_TUNNEL_HOST=${edge_host}" >> "$env_file"
|
echo "EDGE_TUNNEL_HOST=${edge_host}" >> "$env_file"
|
||||||
echo "EDGE_TUNNEL_PORT=${port}" >> "$env_file"
|
echo "EDGE_TUNNEL_PORT=${port}" >> "$env_file"
|
||||||
echo "EDGE_TUNNEL_FQDN=${fqdn}" >> "$env_file"
|
echo "EDGE_TUNNEL_FQDN=${fqdn}" >> "$env_file"
|
||||||
|
|
@ -1768,9 +1775,7 @@ disinto_edge() {
|
||||||
if [ -f "$env_file" ]; then
|
if [ -f "$env_file" ]; then
|
||||||
local tmp_env
|
local tmp_env
|
||||||
tmp_env=$(mktemp)
|
tmp_env=$(mktemp)
|
||||||
grep -v "^EDGE_TUNNEL_HOST=" "$env_file" > "$tmp_env" 2>/dev/null || true
|
grep -Ev "^EDGE_TUNNEL_(HOST|PORT|FQDN)=" "$env_file" > "$tmp_env" 2>/dev/null || true
|
||||||
grep -v "^EDGE_TUNNEL_PORT=" "$env_file" >> "$tmp_env" 2>/dev/null || true
|
|
||||||
grep -v "^EDGE_TUNNEL_FQDN=" "$env_file" >> "$tmp_env" 2>/dev/null || true
|
|
||||||
mv "$tmp_env" "$env_file"
|
mv "$tmp_env" "$env_file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ GANDI_TOKEN=""
|
||||||
INSTALL_DIR="/opt/disinto-edge"
|
INSTALL_DIR="/opt/disinto-edge"
|
||||||
REGISTRY_DIR="/var/lib/disinto"
|
REGISTRY_DIR="/var/lib/disinto"
|
||||||
CADDY_VERSION="2.8.4"
|
CADDY_VERSION="2.8.4"
|
||||||
|
DOMAIN_SUFFIX="disinto.ai"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
@ -52,6 +53,7 @@ Options:
|
||||||
--install-dir <dir> Install directory (default: /opt/disinto-edge)
|
--install-dir <dir> Install directory (default: /opt/disinto-edge)
|
||||||
--registry-dir <dir> Registry directory (default: /var/lib/disinto)
|
--registry-dir <dir> Registry directory (default: /var/lib/disinto)
|
||||||
--caddy-version <ver> Caddy version to install (default: ${CADDY_VERSION})
|
--caddy-version <ver> Caddy version to install (default: ${CADDY_VERSION})
|
||||||
|
--domain-suffix <suffix> Domain suffix for tunnels (default: disinto.ai)
|
||||||
-h, --help Show this help
|
-h, --help Show this help
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
@ -78,6 +80,10 @@ while [[ $# -gt 0 ]]; do
|
||||||
CADDY_VERSION="$2"
|
CADDY_VERSION="$2"
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
--domain-suffix)
|
||||||
|
DOMAIN_SUFFIX="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
usage
|
usage
|
||||||
;;
|
;;
|
||||||
|
|
@ -164,11 +170,12 @@ if ! command -v caddy &>/dev/null; then
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download Caddy binary directly (faster than building)
|
# Download Caddy with Gandi DNS plugin using Caddy's download API
|
||||||
CADDY_LINUX_AMD64="https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_linux_amd64"
|
# The API returns a binary with specified plugins baked in
|
||||||
|
CADDY_DOWNLOAD_API="https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com/caddy-dns/gandi"
|
||||||
|
|
||||||
log_info "Downloading Caddy..."
|
log_info "Downloading Caddy with Gandi DNS plugin..."
|
||||||
curl -sL "$CADDY_LINUX_AMD64" -o /tmp/caddy
|
curl -sL "$CADDY_DOWNLOAD_API" -o /tmp/caddy
|
||||||
chmod +x /tmp/caddy
|
chmod +x /tmp/caddy
|
||||||
|
|
||||||
# Verify it works
|
# Verify it works
|
||||||
|
|
@ -177,6 +184,11 @@ if ! /tmp/caddy version &>/dev/null; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check for Gandi plugin
|
||||||
|
if ! /tmp/caddy version 2>&1 | grep -qi gandi; then
|
||||||
|
log_warn "Gandi plugin not found in Caddy binary - DNS-01 challenge will fail"
|
||||||
|
fi
|
||||||
|
|
||||||
mv /tmp/caddy "$CADDY_BINARY"
|
mv /tmp/caddy "$CADDY_BINARY"
|
||||||
log_info "Installed Caddy: $CADDY_BINARY"
|
log_info "Installed Caddy: $CADDY_BINARY"
|
||||||
|
|
||||||
|
|
@ -250,11 +262,11 @@ log_info "Installing control plane scripts to ${INSTALL_DIR}..."
|
||||||
|
|
||||||
mkdir -p "${INSTALL_DIR}/lib"
|
mkdir -p "${INSTALL_DIR}/lib"
|
||||||
|
|
||||||
# Copy scripts
|
# Copy scripts (overwrite existing to ensure idempotent updates)
|
||||||
cp -n "${BASH_SOURCE%/*}/register.sh" "${INSTALL_DIR}/"
|
cp "${BASH_SOURCE%/*}/register.sh" "${INSTALL_DIR}/"
|
||||||
cp -n "${BASH_SOURCE%/*}/lib/ports.sh" "${INSTALL_DIR}/lib/"
|
cp "${BASH_SOURCE%/*}/lib/ports.sh" "${INSTALL_DIR}/lib/"
|
||||||
cp -n "${BASH_SOURCE%/*}/lib/authorized_keys.sh" "${INSTALL_DIR}/lib/"
|
cp "${BASH_SOURCE%/*}/lib/authorized_keys.sh" "${INSTALL_DIR}/lib/"
|
||||||
cp -n "${BASH_SOURCE%/*}/lib/caddy.sh" "${INSTALL_DIR}/lib/"
|
cp "${BASH_SOURCE%/*}/lib/caddy.sh" "${INSTALL_DIR}/lib/"
|
||||||
|
|
||||||
chmod +x "${INSTALL_DIR}/register.sh"
|
chmod +x "${INSTALL_DIR}/register.sh"
|
||||||
chmod +x "${INSTALL_DIR}/lib/"*.sh
|
chmod +x "${INSTALL_DIR}/lib/"*.sh
|
||||||
|
|
@ -330,10 +342,7 @@ fi
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Step 7: Final configuration
|
# Step 7: Final configuration
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
log_info "Setting environment variables..."
|
log_info "Configuring domain suffix: ${DOMAIN_SUFFIX}"
|
||||||
|
|
||||||
# Set DOMAIN_SUFFIX in register.sh
|
|
||||||
sed -i "s/DOMAIN_SUFFIX=\"${DOMAIN_SUFFIX:-disinto.ai}\"/DOMAIN_SUFFIX=\"${DOMAIN_SUFFIX:-disinto.ai}\"/" "${INSTALL_DIR}/register.sh"
|
|
||||||
|
|
||||||
# Reload systemd if needed
|
# Reload systemd if needed
|
||||||
systemctl daemon-reload 2>/dev/null || true
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Source ports library
|
# Source ports library (SCRIPT_DIR is this file's directory, so lib/ports.sh is adjacent)
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
source "${SCRIPT_DIR}/ports.sh"
|
source "${SCRIPT_DIR}/ports.sh"
|
||||||
|
|
||||||
# Tunnel user home directory
|
# Tunnel user home directory
|
||||||
|
|
|
||||||
|
|
@ -26,73 +26,50 @@ add_route() {
|
||||||
local port="$2"
|
local port="$2"
|
||||||
local fqdn="${project}.${DOMAIN_SUFFIX}"
|
local fqdn="${project}.${DOMAIN_SUFFIX}"
|
||||||
|
|
||||||
# Build Caddy site block configuration
|
# Build the route configuration (partial config)
|
||||||
local config
|
local route_config
|
||||||
config=$(cat <<EOF
|
route_config=$(cat <<EOF
|
||||||
{
|
{
|
||||||
"apps": {
|
"match": [
|
||||||
"http": {
|
{
|
||||||
"servers": {
|
"host": ["${fqdn}"]
|
||||||
"edge": {
|
}
|
||||||
"listen": [":80", ":443"],
|
],
|
||||||
"routes": [
|
"handle": [
|
||||||
|
{
|
||||||
|
"handler": "subroute",
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"handle": [
|
||||||
{
|
{
|
||||||
"match": [
|
"handler": "reverse_proxy",
|
||||||
|
"upstreams": [
|
||||||
{
|
{
|
||||||
"host": ["${fqdn}"]
|
"dial": "127.0.0.1:${port}"
|
||||||
}
|
|
||||||
],
|
|
||||||
"handle": [
|
|
||||||
{
|
|
||||||
"handler": "subroute",
|
|
||||||
"routes": [
|
|
||||||
{
|
|
||||||
"handle": [
|
|
||||||
{
|
|
||||||
"handler": "reverse_proxy",
|
|
||||||
"upstreams": [
|
|
||||||
{
|
|
||||||
"dial": "127.0.0.1:${port}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
# Send POST to Caddy admin API to load config
|
# Append route using POST /config/apps/http/servers/edge/routes
|
||||||
# Note: This appends to existing config rather than replacing
|
|
||||||
local response
|
local response
|
||||||
response=$(curl -s -X POST \
|
response=$(curl -s -X POST \
|
||||||
"${CADDY_ADMIN_URL}/load" \
|
"${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$config" 2>&1) || {
|
-d "$route_config" 2>&1) || {
|
||||||
echo "Error: failed to add route for ${fqdn}" >&2
|
echo "Error: failed to add route for ${fqdn}" >&2
|
||||||
echo "Response: ${response}" >&2
|
echo "Response: ${response}" >&2
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check response
|
echo "Added route: ${fqdn} → 127.0.0.1:${port}"
|
||||||
local loaded
|
|
||||||
loaded=$(echo "$response" | jq -r '.loaded // empty' 2>/dev/null) || loaded=""
|
|
||||||
|
|
||||||
if [ "$loaded" = "true" ]; then
|
|
||||||
echo "Added route: ${fqdn} → 127.0.0.1:${port}"
|
|
||||||
else
|
|
||||||
echo "Warning: Caddy admin response: ${response}" >&2
|
|
||||||
# Don't fail hard - config might have been merged successfully
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove a route for a project
|
# Remove a route for a project
|
||||||
|
|
@ -101,11 +78,33 @@ remove_route() {
|
||||||
local project="$1"
|
local project="$1"
|
||||||
local fqdn="${project}.${DOMAIN_SUFFIX}"
|
local fqdn="${project}.${DOMAIN_SUFFIX}"
|
||||||
|
|
||||||
# Use Caddy admin API to delete the config for this host
|
# First, get current routes
|
||||||
# We need to delete the specific host match from the config
|
local routes_json
|
||||||
|
routes_json=$(curl -s "${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes" 2>&1) || {
|
||||||
|
echo "Error: failed to get current routes" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find the route index that matches our fqdn
|
||||||
|
local route_index=-1
|
||||||
|
local idx=0
|
||||||
|
while IFS= read -r host; do
|
||||||
|
if [ "$host" = "$fqdn" ]; then
|
||||||
|
route_index=$idx
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
idx=$((idx + 1))
|
||||||
|
done < <(echo "$routes_json" | jq -r '.[].match[].host[]' 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$route_index" -lt 0 ]; then
|
||||||
|
echo "Warning: route for ${fqdn} not found" >&2
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Delete the route at the found index
|
||||||
local response
|
local response
|
||||||
response=$(curl -s -X DELETE \
|
response=$(curl -s -X DELETE \
|
||||||
"${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes/0" \
|
"${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes/${route_index}" \
|
||||||
-H "Content-Type: application/json" 2>&1) || {
|
-H "Content-Type: application/json" 2>&1) || {
|
||||||
echo "Error: failed to remove route for ${fqdn}" >&2
|
echo "Error: failed to remove route for ${fqdn}" >&2
|
||||||
echo "Response: ${response}" >&2
|
echo "Response: ${response}" >&2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue