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
|
||||
echo "Registering tunnel for ${project} on ${edge_host}..."
|
||||
local response
|
||||
response=$(ssh -o StrictHostKeyChecking=no -o BatchMode=yes \
|
||||
response=$(ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes \
|
||||
"disinto-register@${edge_host}" \
|
||||
"register ${project} ${pubkey}" 2>&1) || {
|
||||
echo "Error: failed to register tunnel" >&2
|
||||
|
|
@ -1712,7 +1712,14 @@ disinto_edge() {
|
|||
exit 1
|
||||
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_PORT=${port}" >> "$env_file"
|
||||
echo "EDGE_TUNNEL_FQDN=${fqdn}" >> "$env_file"
|
||||
|
|
@ -1768,9 +1775,7 @@ disinto_edge() {
|
|||
if [ -f "$env_file" ]; then
|
||||
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
|
||||
grep -Ev "^EDGE_TUNNEL_(HOST|PORT|FQDN)=" "$env_file" > "$tmp_env" 2>/dev/null || true
|
||||
mv "$tmp_env" "$env_file"
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ GANDI_TOKEN=""
|
|||
INSTALL_DIR="/opt/disinto-edge"
|
||||
REGISTRY_DIR="/var/lib/disinto"
|
||||
CADDY_VERSION="2.8.4"
|
||||
DOMAIN_SUFFIX="disinto.ai"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
|
|
@ -52,6 +53,7 @@ Options:
|
|||
--install-dir <dir> Install directory (default: /opt/disinto-edge)
|
||||
--registry-dir <dir> Registry directory (default: /var/lib/disinto)
|
||||
--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
|
||||
|
||||
Example:
|
||||
|
|
@ -78,6 +80,10 @@ while [[ $# -gt 0 ]]; do
|
|||
CADDY_VERSION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--domain-suffix)
|
||||
DOMAIN_SUFFIX="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
|
|
@ -164,11 +170,12 @@ if ! command -v caddy &>/dev/null; then
|
|||
}
|
||||
fi
|
||||
|
||||
# Download Caddy binary directly (faster than building)
|
||||
CADDY_LINUX_AMD64="https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_linux_amd64"
|
||||
# Download Caddy with Gandi DNS plugin using Caddy's download API
|
||||
# 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..."
|
||||
curl -sL "$CADDY_LINUX_AMD64" -o /tmp/caddy
|
||||
log_info "Downloading Caddy with Gandi DNS plugin..."
|
||||
curl -sL "$CADDY_DOWNLOAD_API" -o /tmp/caddy
|
||||
chmod +x /tmp/caddy
|
||||
|
||||
# Verify it works
|
||||
|
|
@ -177,6 +184,11 @@ if ! /tmp/caddy version &>/dev/null; then
|
|||
exit 1
|
||||
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"
|
||||
log_info "Installed Caddy: $CADDY_BINARY"
|
||||
|
||||
|
|
@ -250,11 +262,11 @@ log_info "Installing control plane scripts to ${INSTALL_DIR}..."
|
|||
|
||||
mkdir -p "${INSTALL_DIR}/lib"
|
||||
|
||||
# Copy scripts
|
||||
cp -n "${BASH_SOURCE%/*}/register.sh" "${INSTALL_DIR}/"
|
||||
cp -n "${BASH_SOURCE%/*}/lib/ports.sh" "${INSTALL_DIR}/lib/"
|
||||
cp -n "${BASH_SOURCE%/*}/lib/authorized_keys.sh" "${INSTALL_DIR}/lib/"
|
||||
cp -n "${BASH_SOURCE%/*}/lib/caddy.sh" "${INSTALL_DIR}/lib/"
|
||||
# Copy scripts (overwrite existing to ensure idempotent updates)
|
||||
cp "${BASH_SOURCE%/*}/register.sh" "${INSTALL_DIR}/"
|
||||
cp "${BASH_SOURCE%/*}/lib/ports.sh" "${INSTALL_DIR}/lib/"
|
||||
cp "${BASH_SOURCE%/*}/lib/authorized_keys.sh" "${INSTALL_DIR}/lib/"
|
||||
cp "${BASH_SOURCE%/*}/lib/caddy.sh" "${INSTALL_DIR}/lib/"
|
||||
|
||||
chmod +x "${INSTALL_DIR}/register.sh"
|
||||
chmod +x "${INSTALL_DIR}/lib/"*.sh
|
||||
|
|
@ -330,10 +342,7 @@ fi
|
|||
# =============================================================================
|
||||
# Step 7: Final configuration
|
||||
# =============================================================================
|
||||
log_info "Setting environment variables..."
|
||||
|
||||
# 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"
|
||||
log_info "Configuring domain suffix: ${DOMAIN_SUFFIX}"
|
||||
|
||||
# Reload systemd if needed
|
||||
systemctl daemon-reload 2>/dev/null || true
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
# Source ports library
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# Source ports library (SCRIPT_DIR is this file's directory, so lib/ports.sh is adjacent)
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/ports.sh"
|
||||
|
||||
# Tunnel user home directory
|
||||
|
|
|
|||
|
|
@ -26,73 +26,50 @@ add_route() {
|
|||
local port="$2"
|
||||
local fqdn="${project}.${DOMAIN_SUFFIX}"
|
||||
|
||||
# Build Caddy site block configuration
|
||||
local config
|
||||
config=$(cat <<EOF
|
||||
# Build the route configuration (partial config)
|
||||
local route_config
|
||||
route_config=$(cat <<EOF
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"edge": {
|
||||
"listen": [":80", ":443"],
|
||||
"routes": [
|
||||
"match": [
|
||||
{
|
||||
"host": ["${fqdn}"]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"match": [
|
||||
"handler": "reverse_proxy",
|
||||
"upstreams": [
|
||||
{
|
||||
"host": ["${fqdn}"]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"handle": [
|
||||
{
|
||||
"handler": "reverse_proxy",
|
||||
"upstreams": [
|
||||
{
|
||||
"dial": "127.0.0.1:${port}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"dial": "127.0.0.1:${port}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Send POST to Caddy admin API to load config
|
||||
# Note: This appends to existing config rather than replacing
|
||||
# Append route using POST /config/apps/http/servers/edge/routes
|
||||
local response
|
||||
response=$(curl -s -X POST \
|
||||
"${CADDY_ADMIN_URL}/load" \
|
||||
"${CADDY_ADMIN_URL}/config/apps/http/servers/edge/routes" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$config" 2>&1) || {
|
||||
-d "$route_config" 2>&1) || {
|
||||
echo "Error: failed to add route for ${fqdn}" >&2
|
||||
echo "Response: ${response}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check response
|
||||
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
|
||||
echo "Added route: ${fqdn} → 127.0.0.1:${port}"
|
||||
}
|
||||
|
||||
# Remove a route for a project
|
||||
|
|
@ -101,11 +78,33 @@ remove_route() {
|
|||
local project="$1"
|
||||
local fqdn="${project}.${DOMAIN_SUFFIX}"
|
||||
|
||||
# Use Caddy admin API to delete the config for this host
|
||||
# We need to delete the specific host match from the config
|
||||
# First, get current routes
|
||||
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
|
||||
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) || {
|
||||
echo "Error: failed to remove route for ${fqdn}" >&2
|
||||
echo "Response: ${response}" >&2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue