WireGuard вместо SSH-reverse: как я выкинул костыль на три сервиса

Обложка

🔧 Исходные данные

Роутер и сервер у меня в разных сетях: сервер живёт за чужим NAT без белого IP, а у роутера на даче белый IP есть. Все домашние сервисы наружу торчали через SSH reverse-туннель — sshd на роутере, keepalive каждые 30 секунд, dstnat 443→8443 и 8080→8080. Работало, но жило своей жизнью: одно длинное TCP-соединение, которое надо держать живым, ключ от роутера лежит на сервере, а TCP-поверх-TCP на потере пакетов ведёт себя так себе.

Как и что делали

Завёл WireGuard — и упёрся в три грабли.

Грабли 1: интерфейс «есть», а трафика нет. Поднял wg0, handshake 0, пакеты не идут. Оказалось, интерфейс висел без приватного ключа — туннель формально создался, но обменяться ключами не мог.

Грабли 2: wg-quick в LXC падает в segfault. Непривилегированный контейнер без /dev/net/tun. Поднимаю руками через wg setconf + свой systemd-юнит:

wg setconf wg0 /etc/wireguard/wg0.conf
ip link set wg0 up
ip addr add 10.100.0.2/30 dev wg0

Грабли 3: wg setconf не создаёт маршрут до LAN. Туннель поднялся, но до локальной сети за роутером пакеты не доезжали. Добавил маршрут руками:

ip route add 10.0.0.0/24 dev wg0

Отдельный сюрприз — реальные IP клиентов. Снял masquerade на роутере, чтобы видеть, кто стучится, — и всё легло. WG резал входящие пакеты, чей source не в AllowedIPs. Лечение — расширить AllowedIPs до 0.0.0.0/0 и добавить policy-routing, чтобы ответы Caddy уходили обратно в туннель:

ip rule add from 10.100.0.2 lookup 200
ip route add default via 10.100.0.1 dev wg0 table 200

На роутере — peer и dstnat прямо в туннель:

/interface wireguard peers add interface=wg-lab allowed-address=10.100.0.2/32
/ip firewall nat add chain=dstnat protocol=tcp dst-port=443 action=dst-nat to-addresses=10.100.0.2

Что получили

Мораль

WireGuard — это просто, пока не начнёшь. Но когда выкидываешь костыль из трёх сервисов и получаешь один файл конфига — оно того стоит.

А у тебя туннели до сих пор на SSH-reverse, или уже переехал на WireGuard?

#network #selfhosting #openclaw