From 5c73330be6107fbd2354fd414289cfadf400dbb4 Mon Sep 17 00:00:00 2001 From: anonpenguin23 Date: Thu, 12 Feb 2026 07:40:43 +0200 Subject: [PATCH] created patch and fixed authentication issue for ipfs bug and cross node communication --- pkg/environments/production/wireguard.go | 1 + pkg/environments/production/wireguard_test.go | 3 + pkg/gateway/middleware.go | 18 ++- scripts/patches/fix-wg-mtu.sh | 106 ++++++++++++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100755 scripts/patches/fix-wg-mtu.sh diff --git a/pkg/environments/production/wireguard.go b/pkg/environments/production/wireguard.go index c1901a5..5097066 100644 --- a/pkg/environments/production/wireguard.go +++ b/pkg/environments/production/wireguard.go @@ -113,6 +113,7 @@ func (wp *WireGuardProvisioner) GenerateConfig() string { sb.WriteString(fmt.Sprintf("PrivateKey = %s\n", wp.config.PrivateKey)) sb.WriteString(fmt.Sprintf("Address = %s/24\n", wp.config.PrivateIP)) sb.WriteString(fmt.Sprintf("ListenPort = %d\n", wp.config.ListenPort)) + sb.WriteString("MTU = 1420\n") // Accept all WireGuard subnet traffic before UFW's conntrack "invalid" drop. // Without this, packets reordered by the tunnel get silently dropped. diff --git a/pkg/environments/production/wireguard_test.go b/pkg/environments/production/wireguard_test.go index 42d0adc..e24f54c 100644 --- a/pkg/environments/production/wireguard_test.go +++ b/pkg/environments/production/wireguard_test.go @@ -89,6 +89,9 @@ func TestWireGuardProvisioner_GenerateConfig_NoPeers(t *testing.T) { if !strings.Contains(config, "ListenPort = 51820") { t.Error("config should contain ListenPort") } + if !strings.Contains(config, "MTU = 1420") { + t.Error("config should contain MTU = 1420") + } if !strings.Contains(config, "PrivateKey = dGVzdHByaXZhdGVrZXl0ZXN0cHJpdmF0ZWtleXM=") { t.Error("config should contain PrivateKey") } diff --git a/pkg/gateway/middleware.go b/pkg/gateway/middleware.go index 6bf8a24..83fafc8 100644 --- a/pkg/gateway/middleware.go +++ b/pkg/gateway/middleware.go @@ -259,8 +259,10 @@ func (g *Gateway) authMiddleware(next http.Handler) http.Handler { // 0) Trust internal auth headers from internal IPs (WireGuard network or localhost) // This allows the main gateway to pre-authenticate requests before proxying to namespace gateways + // IMPORTANT: Use r.RemoteAddr (actual TCP peer), NOT getClientIP() which reads + // X-Forwarded-For and would return the original client IP instead of the proxy's IP. if r.Header.Get(HeaderInternalAuthValidated) == "true" { - clientIP := getClientIP(r) + clientIP := remoteAddrIP(r) if isInternalIP(clientIP) { ns := strings.TrimSpace(r.Header.Get(HeaderInternalAuthNamespace)) if ns != "" { @@ -489,7 +491,7 @@ func (g *Gateway) authorizationMiddleware(next http.Handler) http.Handler { // before proxying, so re-checking ownership against the namespace RQLite is // redundant and adds ~300ms of unnecessary latency (3 DB round-trips). if r.Header.Get(HeaderInternalAuthValidated) == "true" { - clientIP := getClientIP(r) + clientIP := remoteAddrIP(r) if isInternalIP(clientIP) { next.ServeHTTP(w, r) return @@ -716,6 +718,18 @@ func (g *Gateway) persistRequestLog(r *http.Request, srw *statusResponseWriter, } } +// remoteAddrIP extracts the actual TCP peer IP from r.RemoteAddr, ignoring +// X-Forwarded-For and other proxy headers. Use this for security-sensitive +// checks like internal auth validation where we need to verify the direct +// connection source (e.g. WireGuard proxy IP), not the original client. +func remoteAddrIP(r *http.Request) string { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return r.RemoteAddr + } + return host +} + // getClientIP extracts the client IP from headers or RemoteAddr func getClientIP(r *http.Request) string { // X-Forwarded-For may contain a list of IPs, take the first diff --git a/scripts/patches/fix-wg-mtu.sh b/scripts/patches/fix-wg-mtu.sh new file mode 100755 index 0000000..49fe689 --- /dev/null +++ b/scripts/patches/fix-wg-mtu.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# +# Patch: Persist MTU = 1420 in /etc/wireguard/wg0.conf on all nodes. +# +# The WireGuard provisioner now generates configs with MTU = 1420, but +# existing nodes were provisioned without it. Some nodes default to +# MTU 65456, causing packet fragmentation and TCP retransmissions. +# +# This script adds "MTU = 1420" to wg0.conf if it's missing. +# It does NOT restart WireGuard — the live MTU is already correct. +# +# Usage: +# scripts/patches/fix-wg-mtu.sh --devnet +# scripts/patches/fix-wg-mtu.sh --testnet +# +set -euo pipefail + +ENV="" +for arg in "$@"; do + case "$arg" in + --devnet) ENV="devnet" ;; + --testnet) ENV="testnet" ;; + -h|--help) + echo "Usage: scripts/patches/fix-wg-mtu.sh --devnet|--testnet" + exit 0 + ;; + *) echo "Unknown flag: $arg" >&2; exit 1 ;; + esac +done + +if [[ -z "$ENV" ]]; then + echo "ERROR: specify --devnet or --testnet" >&2 + exit 1 +fi + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +CONF="$ROOT_DIR/scripts/remote-nodes.conf" +[[ -f "$CONF" ]] || { echo "ERROR: Missing $CONF" >&2; exit 1; } + +SSH_OPTS=(-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=10) + +fix_node() { + local user_host="$1" + local password="$2" + local ssh_key="$3" + + local cmd=' + CONF=/etc/wireguard/wg0.conf + if ! sudo test -f "$CONF"; then + echo "SKIP_NO_CONF" + exit 0 + fi + if sudo grep -q "^MTU" "$CONF" 2>/dev/null; then + echo "SKIP_ALREADY" + exit 0 + fi + sudo sed -i "/^ListenPort/a MTU = 1420" "$CONF" + if sudo grep -q "^MTU = 1420" "$CONF" 2>/dev/null; then + echo "PATCH_OK" + else + echo "PATCH_FAIL" + fi + ' + + local result + if [[ -n "$ssh_key" ]]; then + expanded_key="${ssh_key/#\~/$HOME}" + result=$(ssh -n "${SSH_OPTS[@]}" -i "$expanded_key" "$user_host" "$cmd" 2>&1) + else + result=$(sshpass -p "$password" ssh -n "${SSH_OPTS[@]}" -o PreferredAuthentications=password -o PubkeyAuthentication=no "$user_host" "$cmd" 2>&1) + fi + + if echo "$result" | grep -q "PATCH_OK"; then + echo " PATCHED $user_host" + elif echo "$result" | grep -q "SKIP_ALREADY"; then + echo " OK $user_host (MTU already set)" + elif echo "$result" | grep -q "SKIP_NO_CONF"; then + echo " SKIP $user_host (no wg0.conf)" + else + echo " ERR $user_host: $result" + fi +} + +# Parse all nodes from conf (both nameservers and regular nodes) +HOSTS=() +PASSES=() +KEYS=() + +while IFS='|' read -r env host pass role key; do + [[ -z "$env" || "$env" == \#* ]] && continue + env="${env%%#*}" + env="$(echo "$env" | xargs)" + [[ "$env" != "$ENV" ]] && continue + HOSTS+=("$host") + PASSES+=("$pass") + KEYS+=("${key:-}") +done < "$CONF" + +echo "== fix-wg-mtu ($ENV) — ${#HOSTS[@]} nodes ==" + +for i in "${!HOSTS[@]}"; do + fix_node "${HOSTS[$i]}" "${PASSES[$i]}" "${KEYS[$i]}" & +done + +wait +echo "Done."