Иногда провайдер/DPI распознаёт “первый” WireGuard handshake и начинает резать/душить соединение (часто выглядит как: handshake то появляется, то пропадает, либо “пакеты отправляются, но не приходят”).
Решение: перед включением туннеля отправить любой UDP-пакет на Endpoint с того же локального порта, который будет использовать WireGuard (ListenPort). Это “ломает” сигнатуру DPI на старте, и WireGuard обычно подключается стабильно.
- WireGuard конфиг (
DE-3_Tunel.conf) с фиксированнымListenPort - Скрипт pre-UDP (
wg-preudp-mac.sh), который читаетListenPortиEndpointпрямо из конфига и отправляет пакет":)"
Пример DE-3_Tunel.conf:
# ============ WireGuard Client ============
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = 10.8.0.3/32
# ВАЖНО: фиксируем локальный UDP порт (для обхода DPI и стабильности)
ListenPort = 57932
DNS = 1.1.1.1, 1.0.0.1
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <CLIENT_PSK>
Endpoint = <SERVER_PUBLIC_IP_OR_DOMAIN>:51820
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25Важно:
ListenPortдолжен быть постоянным (не “рандомным”), иначе pre-UDP не совпадёт с source-port WireGuard.Endpointдолжен бытьhost:port(или[ipv6]:port).
Скрипт:
- читает
ListenPortиEndpointиз.conf - отправляет любой UDP-пакет с source-port =
ListenPort - сначала пробует
nc(обычно есть на macOS), иначе используетpython3
#!/usr/bin/env bash
set -euo pipefail
CFG="${1:-./DE-3_Tunel.conf}"
[[ -f "$CFG" ]] || { echo "Config not found: $CFG" >&2; exit 1; }
# Берём ListenPort и Endpoint из конфига
listen_port="$(awk -F'=' '/^[[:space:]]*ListenPort[[:space:]]*=/ {
v=$2; sub(/#.*/,"",v); gsub(/[[:space:]]/,"",v); print v; exit
}' "$CFG")"
endpoint="$(awk -F'=' '/^[[:space:]]*Endpoint[[:space:]]*=/ {
v=$2; sub(/#.*/,"",v); gsub(/[[:space:]]/,"",v); print v; exit
}' "$CFG")"
[[ -n "${listen_port:-}" ]] || { echo "ListenPort not found in config" >&2; exit 1; }
[[ -n "${endpoint:-}" ]] || { echo "Endpoint not found in config" >&2; exit 1; }
# Endpoint может быть host:port или [ipv6]:port
host=""
port=""
if [[ "$endpoint" =~ ^\[(.+)\]:(\d+)$ ]]; then
host="${BASH_REMATCH[1]}"
port="${BASH_REMATCH[2]}"
else
host="${endpoint%:*}"
port="${endpoint##*:}"
fi
# Отправляем любой UDP пакет с того же source-port (ListenPort)
# Сначала пробуем nc (обычно есть на macOS), иначе python3.
if command -v nc >/dev/null 2>&1; then
# Важно: WireGuard должен быть отключён, чтобы порт был свободен.
printf ":)" | nc -u -w 1 -p "$listen_port" "$host" "$port" >/dev/null 2>&1 || true
echo "Sent pre-UDP via nc from :$listen_port to $host:$port"
else
HOST="$host" PORT="$port" LISTEN_PORT="$listen_port" python3 - <<'PY'
import os, socket
host = os.environ["HOST"]
port = int(os.environ["PORT"])
listen_port = int(os.environ["LISTEN_PORT"])
ip = socket.gethostbyname(host)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("0.0.0.0", listen_port))
s.sendto(b":)", (ip, port))
s.close()
print(f"Sent pre-UDP via python from :{listen_port} to {host}:{port} (resolved {ip})")
PY
fiСделать исполняемым:
chmod +x ./wg-preudp-mac.sh-
Отключи туннель в WireGuard.app (важно:
ListenPortдолжен быть свободен) -
Запусти pre-UDP:
./wg-preudp-mac.sh ./DE-3_Tunel.conf- Сразу после этого включи туннель в WireGuard.app (Activate)
- Если случайно включил WireGuard до запуска скрипта: выключи туннель, подожди 30–60 секунд и повтори:
pre-UDP → Activate. - Если провайдер режет UDP целиком (не только WireGuard), этот способ не поможет — тогда нужен WireGuard через TCP/443 (обёртка).
- Если скрипт пишет, что
ListenPortилиEndpointне найден — проверь, что они реально есть в.conf, и строки не закомментированы.
Никогда не публикуй PrivateKey / PresharedKey в публичных gist/repo.
Если ключи утекли — пересоздай конфиг и обнови peer на сервере.