Материал предназначен для сотрудников, которые занимаются криминалистикой, то есть исключительно для легального использования. Автор не несет ответственности за неправомерное использование.
Свой каскад решает несколько проблем одновременно. Во-первых, ты контролируешь оба узла — никто не знает, где они находятся, кроме тебя. Во-вторых, можно развести юрисдикции: первый узел в одной стране, второй в другой. Во-третьих, полный контроль над маршрутизацией и DNS — это важно для некоторых кейсов.
Клиент подключается к первому узлу, тот шифрует трафик второй раз и отправляет на второй узел. Второй узел делает NAT и выпускает трафик в интернет. Если скомпрометирован первый узел — второй не знает, кто был клиентом. Если второй — первый знает только внутренний IP.
Важный момент - оба узла должны быть в разных ASN и желательно в разных странах. Иначе смысл теряется, провайдер может связать их по трафику.
Типичная схема - два VPS, оба на Ubuntu. Первый в Нью-Джерси, второй в Рейкьявике. Провайдеры разные /ASN разные.
Это важно проверить заранее, иначе можно купить два сервера у одного хостинга в разных дата-центрах и толку будет мало.
Первое, что делаю после получения доступа — меняю SSH-порт и отключаю root-логин. UFW настраиваю сразу иначе через пару часов уже будут попытки брутфорса.
На обоих серверах
Меняю SSH порт
Настраиваем fail2ban — без него через день уже будут забаненные IP. Но это не панацея, просто снижает шум в логах.
Первый узел должен принимать клиентов и маршрутизировать их трафик на второй узел. Второй узел принимает только от первого.
На втором узле (exit node) создаем интерфейс:
На первом узле (middle) конфиг сложнее — нужно два пира: один для клиентов а второй для выхода:
После настройки проверяем цепочку:
# На клиенте
curl ifconfig.me
Должен показать IP второго узла
# Проверяю маршрут
mtr --report --report-cycles 10 8.8.8.8
Первый хоп должен быть 10.60.10.1
Если видите свой реальный IP или IP первого узла — что-то не так с маршрутизацией. Обычно проблема в iptables или в конфиге WireGuard.
По умолчанию клиент будет использовать DNS своего провайдера, что создает утечку. Решение — настроить приватный DNS на втором узле или использовать DoH/DoT
На втором узле ставим unbound:
Конфиг для приватности:
В клиентском конфиге WireGuard добавляем:
Проверьте утечки через tcpdump — не должно быть запросов к публичным DNS на порту 53.
Многие сервисы блокируют IP-диапазоны дата-центров, но пропускают резидентные.
Дома стоит MikroTik hEX, в дата-центре — еще один MikroTik в стойке. Между ними WireGuard, на домашнем — L2TP/IPsec для клиентов.
На домашнем MikroTik настраиваем L2TP-сервер:
Вложение 5129 недоступно
Потом WireGuard до дата-центрового роутера:
Важный момент: нужно правильно настроить routing table, иначе трафик пойдет не туда. RouterOS 7.x позволяет создавать отдельные таблицы маршрутизации.
Проверяем через traceroute с клиента — должен видеть оба узла в цепочке.
Если VPS скомпрометирован или провайдер передает логи, вся схема рушится.
Разные провайдеры, разные ASN, разные юрисдикции. Проверяем ASN перед покупкой:
Если оба сервера в одном ASN — смысл теряется. Провайдер может связать их по трафику.
Делайте выборочно:
Удаляем телеметрию
Отключаем cloud-init
Минимизируем логирование
SSH настраиваем строго. только ключи, ED25519, сильные алгоритмы но не блокируем по IP — если потеряете доступ к VPN, с которым подключались – останетесь без доступа к серверу.
UFW удобен, но для серьезной защиты лучше юзать iptables напрямую. Настраиваем whitelist-подход:
Важно сохранить правила, иначе после перезагрузки все сбросится.
Самая частая проблема — утечки DNS. Клиент может использовать DNS провайдера вместо туннеля. Решение - настраиваем unbound на выходном узле и указываем его в клиентском конфиге.
IPv6 тоже может создать утечку. Если не нужен — отключаем полностью:
Если нужен IPv6 — туннелирую через WireGuard, добавляя IPv6-адреса в конфиг.
Перед запуском проверяю все векторы утечки:
# DNS
Должен вернуть IP выходного узла, не клиента
# IPv6
Должно быть пусто или только туннельные адреса
# IP
Должен быть IP выходного узла
# Timezone (может светить локацию)
Если что-то светится — исправляйте перед использованием.
Раз в месяц ротирую ключи WireGuard. Не автоматически — сначала генерирую новые, тестирую на тестовом клиенте, потом обновляю все конфиги. Старые ключи удаляю только после подтверждения, что все работает.
Важные нюансы:
Проверка на компрометацию:
# Подозрительные процессы
# Сетевая активность
# Изменения в критических файлах
За все время эксплуатации этой тактики столкнулся с несколькими проблемами
При двойном туннелировании MTU становится критичным. Если не настроить правильно, пакеты будут фрагментироваться, что снижает производительность и может создавать проблемы с некоторыми протоколами.
Решение – уменьшать MTU на интерфейсах WireGuard:
# В конфиге WireGuard
Или настраиваем MSS clamping в iptables:
Если между узлами нестабильное соединение, туннель может падать. WireGuard по умолчанию не отправляет keepalive если нет трафика.
Решение – настраиваем
Некоторые приложения игнорируют системные DNS и используют свои. Например, браузеры могут использовать DoH напрямую, обходя туннель.
Решение – блокируем прямой доступ к публичным DNS на уровне firewall и перенаправляю все DNS-запросы через туннель:
Даже если отключил IPv6 на сервере, клиент может использовать IPv6 напрямую, обходя туннель.
Решение - на клиенте либо отключаем IPv6 полностью, либо настраиваем маршрутизацию IPv6 через туннель.
Зачем нужен Приватный Double VPN
Свой каскад решает несколько проблем одновременно. Во-первых, ты контролируешь оба узла — никто не знает, где они находятся, кроме тебя. Во-вторых, можно развести юрисдикции: первый узел в одной стране, второй в другой. Во-третьих, полный контроль над маршрутизацией и DNS — это важно для некоторых кейсов.
Как это работает на практике
Клиент подключается к первому узлу, тот шифрует трафик второй раз и отправляет на второй узел. Второй узел делает NAT и выпускает трафик в интернет. Если скомпрометирован первый узел — второй не знает, кто был клиентом. Если второй — первый знает только внутренний IP.
Не удалось прогрузить медиа
Важный момент - оба узла должны быть в разных ASN и желательно в разных странах. Иначе смысл теряется, провайдер может связать их по трафику.
Поднимаем между VPS
Типичная схема - два VPS, оба на Ubuntu. Первый в Нью-Джерси, второй в Рейкьявике. Провайдеры разные /ASN разные.
Это важно проверить заранее, иначе можно купить два сервера у одного хостинга в разных дата-центрах и толку будет мало.
Подготовка серверов
Первое, что делаю после получения доступа — меняю SSH-порт и отключаю root-логин. UFW настраиваю сразу иначе через пару часов уже будут попытки брутфорса.
На обоих серверах
Code:
adduser ops
usermod -aG sudo ops
ufw default deny incoming
ufw default allow outgoing
ufw allow 51820/udp # WireGuard порт
ufw enable
Меняю SSH порт
Code:
sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config
systemctl restart sshd
Настраиваем fail2ban — без него через день уже будут забаненные IP. Но это не панацея, просто снижает шум в логах.
Настройка WireGuard
Первый узел должен принимать клиентов и маршрутизировать их трафик на второй узел. Второй узел принимает только от первого.
На втором узле (exit node) создаем интерфейс:
Code:
wg genkey | tee /etc/wireguard/wg-exit.key | wg pubkey > /etc/wireguard/wg-exit.pub
cat > /etc/wireguard/wg-exit.conf <<EOF
[Interface]
Address = 10.80.20.1/30
ListenPort = 51822
PrivateKey = $(cat /etc/wireguard/wg-exit.key)
PostUp = iptables -t nat -A POSTROUTING -s 10.60.10.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.60.10.0/24 -o eth0 -j MASQUERADE
[Peer]
PublicKey = <публичный ключ первого узла>
AllowedIPs = 10.60.10.0/24,10.80.20.2/32
PersistentKeepalive = 25
EOF
Code:
systemctl enable --now wg-quick@wg-exit
На первом узле (middle) конфиг сложнее — нужно два пира: один для клиентов а второй для выхода:
Code:
wg genkey | tee /etc/wireguard/wg-mid.key | wg pubkey > /etc/wireguard/wg-mid.pub
cat > /etc/wireguard/wg-mid.conf <<EOF
[Interface]
Address = 10.60.10.1/24, 10.80.20.2/30
ListenPort = 51820
PrivateKey = $(cat /etc/wireguard/wg-mid.key)
PostUp = iptables -t nat -A POSTROUTING -s 10.60.10.0/24 -o wg-exit -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.60.10.0/24 -o wg-exit -j MASQUERADE
[Peer]
# Клиенты
PublicKey = <публичный ключ клиента>
AllowedIPs = 10.60.10.0/24
[Peer]
# Выходной узел
PublicKey = <публичный ключ второго узла>
Endpoint = <IP второго узла>:51822
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
Code:
systemctl enable --now wg-quick@wg-mid
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Проблема, с которой столкнулся если не указать AllowedIPs = 0.0.0.0/0 для второго пира, трафик не пойдет дальше первого узла. WireGuard по умолчанию не маршрутизирует весь трафик, нужно точно указать.
Проверка работы
После настройки проверяем цепочку:
# На клиенте
curl ifconfig.me
Должен показать IP второго узла
# Проверяю маршрут
mtr --report --report-cycles 10 8.8.8.8
Первый хоп должен быть 10.60.10.1
Не удалось прогрузить медиа
Если видите свой реальный IP или IP первого узла — что-то не так с маршрутизацией. Обычно проблема в iptables или в конфиге WireGuard.
DNS и утечки
По умолчанию клиент будет использовать DNS своего провайдера, что создает утечку. Решение — настроить приватный DNS на втором узле или использовать DoH/DoT
На втором узле ставим unbound:
Code:
apt install -y unbound
Конфиг для приватности:
server:
interface: 127.0.0.1
interface: 10.80.20.1
access-control: 10.60.10.0/24 allow
do-ip6: no
hide-identity: yes
hide-version: yes
qname-minimisation: yes
Code:
systemctl restart unbound
В клиентском конфиге WireGuard добавляем:
DNS = 10.80.20.1Не удалось прогрузить медиа
Проверьте утечки через tcpdump — не должно быть запросов к публичным DNS на порту 53.
Второй вариант: MikroTik
Многие сервисы блокируют IP-диапазоны дата-центров, но пропускают резидентные.
Дома стоит MikroTik hEX, в дата-центре — еще один MikroTik в стойке. Между ними WireGuard, на домашнем — L2TP/IPsec для клиентов.
Домашний роутер
На домашнем MikroTik настраиваем L2TP-сервер:
Code:
/ip pool add name=doublevpn ranges=10.55.55.10-10.55.55.60
/ppp profile add name=doublevpn local-address=10.55.55.1 remote-address=doublevpn
/ppp secret add name=user1 password=xxx service=l2tp profile=doublevpn
/interface l2tp-server server set enabled=yes default-profile=doublevpn use-ipsec=yes ipsec-secret=xxx
Вложение 5129 недоступно
Потом WireGuard до дата-центрового роутера:
Code:
/interface wireguard add name=wg-exit listen-port=51830 private-key="xxx"
/interface wireguard peers add interface=wg-exit public-key="yyy" endpoint-address=203.0.113.42 endpoint-port=51830 allowed-address=0.0.0.0/0
/ip address add interface=wg-exit address=10.90.90.1/30
/ip firewall nat add chain=srcnat src-address=10.55.55.0/24 out-interface=wg-exit action=masquerade
/ip route add dst-address=0.0.0.0/0 gateway=10.90.90.2 routing-table=main
Не удалось прогрузить медиа
Важный момент: нужно правильно настроить routing table, иначе трафик пойдет не туда. RouterOS 7.x позволяет создавать отдельные таблицы маршрутизации.
Дата-центровый роутер
На втором MikroTik настраиваем прием WireGuard и NAT:
Code:
/interface wireguard add name=wg-exit listen-port=51830 private-key="xxx"
/interface wireguard peers add interface=wg-exit public-key="yyy" allowed-address=10.55.55.0/24,10.90.90.1/32
/ip address add interface=wg-exit address=10.90.90.2/30
/ip firewall nat add chain=srcnat src-address=10.55.55.0/24 out-interface=ether1 action=masquerade
Проверяем через traceroute с клиента — должен видеть оба узла в цепочке.
Не удалось прогрузить медиа
Защита VPS
Если VPS скомпрометирован или провайдер передает логи, вся схема рушится.
Выбор провайдера
Разные провайдеры, разные ASN, разные юрисдикции. Проверяем ASN перед покупкой:
Code:
whois -h whois.radb.net $(dig +short provider.com) | grep -i origin
Если оба сервера в одном ASN — смысл теряется. Провайдер может связать их по трафику.
Оплата — только криптой, желательно Monero. Регистрация через Tor, временный email. Никаких реальных данных. Для критических сетапов используйте resellers, которые не требуют верификацию.
Hardening
Делайте выборочно:
Удаляем телеметрию
Code:
apt remove --purge ubuntu-report popularity-contest apport whoopsie 2>/dev/null || true
Отключаем cloud-init
Code:
touch /etc/cloud/cloud-init.disabled
systemctl disable cloud-init
Минимизируем логирование
Code:
mkdir -p /etc/systemd/journald.conf.d/
cat > /etc/systemd/journald.conf.d/no-logs.conf <<EOF
Storage=none
ForwardToSyslog=no
MaxRetentionSec=0
EOF
Code:
systemctl restart systemd-journald
SSH настраиваем строго. только ключи, ED25519, сильные алгоритмы но не блокируем по IP — если потеряете доступ к VPN, с которым подключались – останетесь без доступа к серверу.
Firewall: не только UFW
UFW удобен, но для серьезной защиты лучше юзать iptables напрямую. Настраиваем whitelist-подход:
Code:
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT # SSH
iptables -A INPUT -p udp --dport 51820 -j ACCEPT # WireGuard
iptables -A INPUT -p udp --dport 51822 -j ACCEPT # WireGuard exit
apt install -y iptables-persistent
netfilter-persistent save
Не удалось прогрузить медиа
Важно сохранить правила, иначе после перезагрузки все сбросится.
DNS и IPv6: где теряется анонимность
Самая частая проблема — утечки DNS. Клиент может использовать DNS провайдера вместо туннеля. Решение - настраиваем unbound на выходном узле и указываем его в клиентском конфиге.
IPv6 тоже может создать утечку. Если не нужен — отключаем полностью:
Code:
cat >> /etc/sysctl.conf <<EOF
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
EOF
sysctl -p
Если нужен IPv6 — туннелирую через WireGuard, добавляя IPv6-адреса в конфиг.
Мониторинг без компрометации
Code:
# fail2ban
apt install -y fail2ban
cat > /etc/fail2ban/jail.local <<EOF
[DEFAULT]
bantime = 86400
maxretry = 3
[sshd]
enabled = true
port = 2222
EOF
systemctl enable --now fail2ban
Проверка на утечки
Перед запуском проверяю все векторы утечки:
# DNS
Code:
dig +short @8.8.8.8 whoami.akamai.net
# IPv6
Code:
ip -6 addr show
# IP
Code:
curl -s ifconfig.me
# Timezone (может светить локацию)
Code:
timedatectl
Не удалось прогрузить медиа
Если что-то светится — исправляйте перед использованием.
Раз в месяц ротирую ключи WireGuard. Не автоматически — сначала генерирую новые, тестирую на тестовом клиенте, потом обновляю все конфиги. Старые ключи удаляю только после подтверждения, что все работает.
Важные нюансы:
- Никогда не подключайтесь к VPS с реального IP. Всегда через другой VPN или Tor.
- Отдельный SSH-ключ для каждого VPS. Если один накрыли — остальные в безопасности.
- Конфиги WireGuard не храню на VPS. Только локально на зашифрованном диске.
Проверка на компрометацию:
# Подозрительные процессы
Code:
ps aux | awk '{print $11}' | sort | uniq -c | sort -rn | head -20
# Сетевая активность
Code:
iftop -i eth0
# Изменения в критических файлах
Code:
find /etc -type f -mtime -7 -ls
Реальные проблемы и их решения
За все время эксплуатации этой тактики столкнулся с несколькими проблемами
Проблема 1: MTU и фрагментация
При двойном туннелировании MTU становится критичным. Если не настроить правильно, пакеты будут фрагментироваться, что снижает производительность и может создавать проблемы с некоторыми протоколами.
Решение – уменьшать MTU на интерфейсах WireGuard:
# В конфиге WireGuard
MTU = 1280Или настраиваем MSS clamping в iptables:
Code:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1200
Проблема 2: Таймауты и keepalive
Если между узлами нестабильное соединение, туннель может падать. WireGuard по умолчанию не отправляет keepalive если нет трафика.
Решение – настраиваем
PersistentKeepalive = 25 для всех пиров. Это отправляет пакет каждые 25 секунд, поддерживая соединение.Проблема 3: DNS через туннель
Некоторые приложения игнорируют системные DNS и используют свои. Например, браузеры могут использовать DoH напрямую, обходя туннель.
Решение – блокируем прямой доступ к публичным DNS на уровне firewall и перенаправляю все DNS-запросы через туннель:
Code:
iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 10.80.20.1:53
iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to-destination 10.80.20.1:53
Проблема 4: IPv6 утечки
Даже если отключил IPv6 на сервере, клиент может использовать IPv6 напрямую, обходя туннель.
Решение - на клиенте либо отключаем IPv6 полностью, либо настраиваем маршрутизацию IPv6 через туннель.
👍17
❤️2
😮2
👏2
LIMB