mirror of
https://github.com/vvzvlad/trickster-vpn.git
synced 2024-12-26 02:41:00 +03:00
update article
This commit is contained in:
parent
6ee6c82a48
commit
4fb6444e43
@ -36,6 +36,8 @@ IMG_1589.PNG
|
|||||||
Особенно для одинокого пользователя-хакера приятна работа с шифрованием: нет ни необходимости в сертификатах и удостоверяющих центрах, ни в логинах-паролях, все, что нужно — это с тем пиром, с которым хотите установить соедиение, передать друг другу публичные ключи вашего интерфейса WG. Для больших компаний, это, конечно, будет скорее минусом, как и то, что WG — это только базовая часть полноценной большой инфраструктуры VPN.
|
Особенно для одинокого пользователя-хакера приятна работа с шифрованием: нет ни необходимости в сертификатах и удостоверяющих центрах, ни в логинах-паролях, все, что нужно — это с тем пиром, с которым хотите установить соедиение, передать друг другу публичные ключи вашего интерфейса WG. Для больших компаний, это, конечно, будет скорее минусом, как и то, что WG — это только базовая часть полноценной большой инфраструктуры VPN.
|
||||||
Но, например, именно WireGuard использовали в Cloudflare для своего WARP (https://blog.cloudflare.com/announcing-warp-plus/, https://blog.cloudflare.com/warp-technical-challenges/), правда, написав его собственную реализацию — boringtun.
|
Но, например, именно WireGuard использовали в Cloudflare для своего WARP (https://blog.cloudflare.com/announcing-warp-plus/, https://blog.cloudflare.com/warp-technical-challenges/), правда, написав его собственную реализацию — boringtun.
|
||||||
|
|
||||||
|
Еще одним минусом WG является то, что трафик не обфусцирован — DPI может обнаружить трафик WireGuard, так что его можно довольно легко заблокировать (не говоря уж о блокировке UDP совсем, что почти не мешает вебу, но гарантированно ломает работу WireGuard). Для скрытия трафика рекомендуется использовать специализированное ПО — Cloak, Obfsproxy, Shadowsocks, Stunnel, SoftEther, SSTP, в конце-концов, SSH.
|
||||||
|
|
||||||
|
|
||||||
Если очень упрощать, ключи работают следующим образом: у нас есть закрытый (приватный) ключ, из которого можно сгенерировать открытый, или публичный. Наоборот — нельзя, из открытого ключа мы получить закрытый никак не можем. После чего, мы можем зашифровать с помощью закрытого ключая какую-то строку, а при помощи открытого — расшифровать ее и тем самым убедиться, что у собеседника точно есть закрытый ключ, а значит, он тот, за кого себя выдает. Таким образом, мы можем без проблем публиковать открытый ключ — он всего лишь позволяет проверить подлинность автора, но не притвориться им. Это как в SSH — публичный ключ лежит на сервере, где его потеря небольшая беда: все что сможет сделать с ним злоумышленник это положить его на свой сервер, чтобы вы к нему могли подключиться с помощью закрытого ключа.
|
Если очень упрощать, ключи работают следующим образом: у нас есть закрытый (приватный) ключ, из которого можно сгенерировать открытый, или публичный. Наоборот — нельзя, из открытого ключа мы получить закрытый никак не можем. После чего, мы можем зашифровать с помощью закрытого ключая какую-то строку, а при помощи открытого — расшифровать ее и тем самым убедиться, что у собеседника точно есть закрытый ключ, а значит, он тот, за кого себя выдает. Таким образом, мы можем без проблем публиковать открытый ключ — он всего лишь позволяет проверить подлинность автора, но не притвориться им. Это как в SSH — публичный ключ лежит на сервере, где его потеря небольшая беда: все что сможет сделать с ним злоумышленник это положить его на свой сервер, чтобы вы к нему могли подключиться с помощью закрытого ключа.
|
||||||
Так вот, в WG первый этап подключения заключается в том, что каждая сторона с помощью зашифрованного приватным ключом сообщения доказывает собеседнику, что она именно она: это проверяется публичным ключом.
|
Так вот, в WG первый этап подключения заключается в том, что каждая сторона с помощью зашифрованного приватным ключом сообщения доказывает собеседнику, что она именно она: это проверяется публичным ключом.
|
||||||
@ -56,8 +58,8 @@ echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
|
|||||||
echo "net.ipv4.conf.all.forwarding=1" >> /etc/sysctl.conf
|
echo "net.ipv4.conf.all.forwarding=1" >> /etc/sysctl.conf
|
||||||
sysctl -p /etc/sysctl.conf
|
sysctl -p /etc/sysctl.conf
|
||||||
Опционально (но очень удобно) сразу поменять hostname обоих серверов, чтобы не запутаться, где какая консоль:
|
Опционально (но очень удобно) сразу поменять hostname обоих серверов, чтобы не запутаться, где какая консоль:
|
||||||
hostnamectl set-hostname internal.trickster
|
hostnamectl set-hostname trickster-internal
|
||||||
hostnamectl set-hostname external.trickster
|
hostnamectl set-hostname trickster-external
|
||||||
|
|
||||||
#Шаг второй: настраиваем WireGuard для связи двух серверов:
|
#Шаг второй: настраиваем WireGuard для связи двух серверов:
|
||||||
Для начала генерируем ключи. Запускаем два раза wg genkey и получаем два приватных ключа:
|
Для начала генерируем ключи. Запускаем два раза wg genkey и получаем два приватных ключа:
|
||||||
@ -66,7 +68,7 @@ kOd3FVBggwpjD3AlZKXUxNTzJT0+f3MJdUdR8n6ZBn8=
|
|||||||
root@trikster-internal:~# wg genkey
|
root@trikster-internal:~# wg genkey
|
||||||
6CCRP42JiTObyf64Vo0BcqsX6vptsqOU+MKUslUun28=
|
6CCRP42JiTObyf64Vo0BcqsX6vptsqOU+MKUslUun28=
|
||||||
|
|
||||||
Утилита wg genkey не делает никакой магии, это просто аналог чего-то типа "echo $RANDOM | md5sum | head -c 32 | base64", только наверняка более криптостойкое.
|
Утилита wg genkey не делает никакой магии, это просто аналог чего-то типа "echo $RANDOM | md5sum | head -c 32 | base64", только наверняка более криптостойкое: мы просто генерируем 32 байта случайных значений и представляем их в виде base64.
|
||||||
|
|
||||||
Создаем два конфига:
|
Создаем два конфига:
|
||||||
На internal: /etc/wireguard/wg-internal.conf
|
На internal: /etc/wireguard/wg-internal.conf
|
||||||
@ -97,7 +99,7 @@ Interface-Address — это IP текущего пира. Вся адерсац
|
|||||||
ListenPort — это UDP-порт для подключения извне. Если не указать, будет прослушивать 51820. Если этот пир будет только подключаться к другим клиентам, можно и не использовать.
|
ListenPort — это UDP-порт для подключения извне. Если не указать, будет прослушивать 51820. Если этот пир будет только подключаться к другим клиентам, можно и не использовать.
|
||||||
Interface-PostUp и PostDown — это скрипты, выполняющиеся после поднятия и после остановки интерфейса. Есть еще PreUP и PreDown.
|
Interface-PostUp и PostDown — это скрипты, выполняющиеся после поднятия и после остановки интерфейса. Есть еще PreUP и PreDown.
|
||||||
|
|
||||||
Кроме публичных и приватных ключей есть еще опция PresharedKey, которая обеспечивает дополнительное шифрование симметричным ключом. Ключ генерируется командой wg genpsk и кладется в PresharedKey в секциях Peer на обоих пирах. Неиспользование этой опции не снижает нагрузку по шифровке-расшифровке: если ключ не указан, используется нулевое значение ключа.
|
Кроме публичных и приватных ключей есть еще опция PresharedKey, которая обеспечивает дополнительное шифрование симметричным шифром. Ключ генерируется командой wg genpsk и кладется в PresharedKey в секциях Peer на обоих пирах. Неиспользование этой опции не снижает нагрузку по шифровке-расшифровке: если ключ не указан, используется нулевое значение ключа. Для действительного обеспечения пост-квантовой безопасности (невозможности расшифровки данных квантовыми компьютерами) разработчики рекомендуют дополнительный внешний квантово-устойчивый механизм хендшека (например, Microsoft SIDH, который они пиарят именно в таком контексте), чей найденный общий ключ можно использовать в качестве PresharedKey.
|
||||||
|
|
||||||
Заклинания в PostUp достаточно просты. `ip route | awk '/default/ {print $5; exit}'` — это команда для подстановки имени сетевого интерфейса, куда по-умолчанию выполняется маршрутизация: как правило, это тот интерфейс, в который воткнут провайдер или роутер. `ip route | awk '/default/ {print $3; exit}'` — тоже самое, но подставляет IP-адрес дефолтного маршрута. Таким образом, первая страшная команда упрощается и превращается в "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE", которая представляет собой вклчение NAT в режиме маскарада: сервер будет отправлять пришедшие ему пакеты пакеты во внешнюю сеть, подменяя в них адрес отправителя на свой, чтобы ответы на эти пакеты тоже приходили ему, а не исходному отправителю.
|
Заклинания в PostUp достаточно просты. `ip route | awk '/default/ {print $5; exit}'` — это команда для подстановки имени сетевого интерфейса, куда по-умолчанию выполняется маршрутизация: как правило, это тот интерфейс, в который воткнут провайдер или роутер. `ip route | awk '/default/ {print $3; exit}'` — тоже самое, но подставляет IP-адрес дефолтного маршрута. Таким образом, первая страшная команда упрощается и превращается в "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE", которая представляет собой вклчение NAT в режиме маскарада: сервер будет отправлять пришедшие ему пакеты пакеты во внешнюю сеть, подменяя в них адрес отправителя на свой, чтобы ответы на эти пакеты тоже приходили ему, а не исходному отправителю.
|
||||||
Вторая страшная команда превращается в "ip rule add from 95.93.219.123 table main" — это необходимо для сервера internal, потому что иначе при активации маршрута 0.0.0.0/0 он начинает пересылать ответы на пакеты, приходящие ему на внешние адреса через туннель WG. Сервер на том конце, конечно, пересылает их по назначению, но тут уже не готов отправитель пакета: он присылает что-то на внешний адрес сервера internal, а ответ ему приходит с external. Естественно, при включенном rp_filter пакет отбрасывается. В этом случае сервер перестает быть доступен, например, по SSH снаружи, к нему надо коннектиться только по внутреннему IP wireguard-а. Отключать rp_filter у сервера это из пушки по воробьям, а вот дополнительное правило исправляет ситуацию.
|
Вторая страшная команда превращается в "ip rule add from 95.93.219.123 table main" — это необходимо для сервера internal, потому что иначе при активации маршрута 0.0.0.0/0 он начинает пересылать ответы на пакеты, приходящие ему на внешние адреса через туннель WG. Сервер на том конце, конечно, пересылает их по назначению, но тут уже не готов отправитель пакета: он присылает что-то на внешний адрес сервера internal, а ответ ему приходит с external. Естественно, при включенном rp_filter пакет отбрасывается. В этом случае сервер перестает быть доступен, например, по SSH снаружи, к нему надо коннектиться только по внутреннему IP wireguard-а. Отключать rp_filter у сервера это из пушки по воробьям, а вот дополнительное правило исправляет ситуацию.
|
||||||
@ -385,8 +387,20 @@ echo "Routes in routing table: $routes_count"
|
|||||||
|
|
||||||
Если вам принудительно надо маршрутизовать какую-то сеть через internal, то можно рядом со скриптом создать файлик subnets_user_list.txt в который поместить список подсетей, тогда они каждый раз будут добавляться к общему списку при обновлении, в bash-скрипте это есть.
|
Если вам принудительно надо маршрутизовать какую-то сеть через internal, то можно рядом со скриптом создать файлик subnets_user_list.txt в который поместить список подсетей, тогда они каждый раз будут добавляться к общему списку при обновлении, в bash-скрипте это есть.
|
||||||
|
|
||||||
|
# Шаг пятный: настраиваем фаервол
|
||||||
|
|
||||||
# Шаг пятый, бонусный и необязательный: кеширующий защищенный DNS over HTTPS
|
|
||||||
|
|
||||||
|
|
||||||
|
PostUp = ufw route allow in on wg0 out on eth0
|
||||||
|
PreDown = ufw route delete allow in on wg0 out on eth0
|
||||||
|
|
||||||
|
ufw allow 17968/udp
|
||||||
|
ufw allow OpenSSH
|
||||||
|
ufw disable
|
||||||
|
ufw enable
|
||||||
|
|
||||||
|
# Шаг шестой, бонусный и необязательный: кеширующий защищенный DNS over HTTPS
|
||||||
Теперь нам нужен еще один шаг: DNS. Можно, конечно, жить с DNS 1.1.1.1, но надо учитывать две вещи:
|
Теперь нам нужен еще один шаг: DNS. Можно, конечно, жить с DNS 1.1.1.1, но надо учитывать две вещи:
|
||||||
Трафик на него пойдет через external, что автоматически означает задержку порядка 100мс при каждом запросе. Можно его добавить в subnets_user_list.txt, и тогда трафик пойдет через локальную ноду и локальный сервер 1.1.1.1, что уменьшит задержку до 10-20мс, но ваши DNS-запросы будет доступны вашему провайдеру, что в случае локальной ноды может быть для кого-то неприемлимо. Несколькими командами можно легко сделать кеширующий DNS, который еще и будет работать с DNS over HTTPS, а значит, провайдеру будет доступен только сам факт использовани DoH, но не сами запросы. Но это, конечно, не обязательно: у меня internal находится в домашней сети, и я просто использую DNS микротика, который находится в той же сети. Но если у вас internal сервер это VPS, то можно сделать там и DNS сервер. Использовать будем cloudflared.
|
Трафик на него пойдет через external, что автоматически означает задержку порядка 100мс при каждом запросе. Можно его добавить в subnets_user_list.txt, и тогда трафик пойдет через локальную ноду и локальный сервер 1.1.1.1, что уменьшит задержку до 10-20мс, но ваши DNS-запросы будет доступны вашему провайдеру, что в случае локальной ноды может быть для кого-то неприемлимо. Несколькими командами можно легко сделать кеширующий DNS, который еще и будет работать с DNS over HTTPS, а значит, провайдеру будет доступен только сам факт использовани DoH, но не сами запросы. Но это, конечно, не обязательно: у меня internal находится в домашней сети, и я просто использую DNS микротика, который находится в той же сети. Но если у вас internal сервер это VPS, то можно сделать там и DNS сервер. Использовать будем cloudflared.
|
||||||
|
|
||||||
@ -463,7 +477,6 @@ DNS = 10.20.30.1, 1.1.1.1
|
|||||||
|
|
||||||
P.S. особые параноики могут запустить cloudflared на external, и скрыть от локального провайдера даже сам факт использования DoH. Для этого в proxy-dns-address в конфиге cloudflared и в dnsmasq.conf надо указать 10.20.30.2.
|
P.S. особые параноики могут запустить cloudflared на external, и скрыть от локального провайдера даже сам факт использования DoH. Для этого в proxy-dns-address в конфиге cloudflared и в dnsmasq.conf надо указать 10.20.30.2.
|
||||||
|
|
||||||
|
|
||||||
Пары ключей в статье — действующие, так что вы можете, ничего не исправляя в конфигах (только IP и имена адаптеров), залить их на два своих сервера и клиент и поиграться. Но для боевого применения ключи надо перегенерить, конечно. Так же, чтобы не усложнять статью, я не касался настройки файервола на серверах — если они торчат голой задницей в интернет, то это стоит сделать. О необходимости отключать авторизацию в ssh по паролю думаю, напоминать и так не надо.
|
Пары ключей в статье — действующие, так что вы можете, ничего не исправляя в конфигах (только IP и имена адаптеров), залить их на два своих сервера и клиент и поиграться. Но для боевого применения ключи надо перегенерить, конечно. Так же, чтобы не усложнять статью, я не касался настройки файервола на серверах — если они торчат голой задницей в интернет, то это стоит сделать. О необходимости отключать авторизацию в ssh по паролю думаю, напоминать и так не надо.
|
||||||
|
|
||||||
Если кто-то захочет это все красиво обернуть в два докера и прикрутить к этому веб-интерфейс (потому что конфиги клиентов все же удобнее создавать в нем) — добро пожаловать в issues на гитхабе.
|
Если кто-то захочет это все красиво обернуть в два докера и прикрутить к этому веб-интерфейс (потому что конфиги клиентов все же удобнее создавать в нем) — добро пожаловать в issues на гитхабе.
|
||||||
|
Loading…
Reference in New Issue
Block a user