fix typos

This commit is contained in:
vvzvlad 2022-08-27 18:45:40 +03:00
parent c1145b2fc5
commit eae6759ac8

View File

@ -19,17 +19,21 @@
Ах да, еще UDP. UDP для туннелей это хорошо, потому что у TCP уже есть механизмы, которые позволяют ему работать на неидеальных соединениях, а UDP представляет из себя именно такое соединение. А когда вы засовываете TCP в TCP, то отказываетесь от большей части этих механизмов (инкапсулированный TCP-пакет будет гарантированно доставлен другой стороне, хотя протокол допускает недоставку), но все еще несете весь оверхед вида "хендшейк соединения для отправки хендшейка". Ах да, еще UDP. UDP для туннелей это хорошо, потому что у TCP уже есть механизмы, которые позволяют ему работать на неидеальных соединениях, а UDP представляет из себя именно такое соединение. А когда вы засовываете TCP в TCP, то отказываетесь от большей части этих механизмов (инкапсулированный TCP-пакет будет гарантированно доставлен другой стороне, хотя протокол допускает недоставку), но все еще несете весь оверхед вида "хендшейк соединения для отправки хендшейка".
Не говоря уж о том, что инкапсулировать UDP в TCP — ничуть не лучшая идея, потому что сразу рушит все предположения всяких скайпов о том, что лучше пропустить пару пакетов, чем уменьшить задержку: каждый UDP пакет в этом случае будет принудительно перепослан и доставлен корректно, не считаясь с тем, сколько это займет времени. Не говоря уж о том, что инкапсулировать UDP в TCP — ничуть не лучшая идея, потому что сразу рушит все предположения всяких скайпов о том, что лучше пропустить пару пакетов, чем уменьшить задержку: каждый UDP пакет в этом случае будет принудительно перепослан и доставлен корректно, не считаясь с тем, сколько это займет времени.
Особенно для одинокого пользователя-хакера приятна работа с шифрованием: нет ни необходимости в сертификатах и удостоверяющих центрах, ни в логинах-паролях, все, что нужно — это с тем пиром, с которым хотите установить соединение, передать друг другу публичные ключи вашего интерфейса 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. Часть из этих инструментов может работать совместно с WG, а часть способа его заменять в качестве инструмента стеганографии: WG изначально создавался под скорость и криптографическую защищенность. Еще одним минусом WG является то, что трафик не обфусцирован — DPI может обнаружить трафик WireGuard, так что его можно довольно легко заблокировать (не говоря уж о блокировке UDP совсем, что почти не мешает вебу, но гарантированно ломает работу WireGuard). Для скрытия трафика рекомендуется использовать специализированное ПО — Cloak, Obfsproxy, Shadowsocks, Stunnel, SoftEther, SSTP, или, в конце-концов, простой SSH. Часть из этих инструментов может работать совместно с WG, а часть способа его заменять в качестве инструмента стеганографии: WG изначально создавался под скорость и криптографическую защищенность.
Если очень упрощать, ключи работают следующим образом: у нас есть закрытый (приватный) ключ, из которого можно сгенерировать открытый, или публичный. Наоборот — нельзя, из открытого ключа мы получить закрытый никак не можем. После чего, мы можем зашифровать с помощью закрытого ключа какую-то строку, а при помощи открытого — расшифровать ее и тем самым убедиться, что у собеседника точно есть закрытый ключ, а значит, он тот, за кого себя выдает. Таким образом, мы можем без проблем передавать открытый ключ — он всего лишь позволяет проверить подлинность автора, но не притвориться им. Это как в SSH — публичный ключ лежит на сервере, где его потеря небольшая беда: все что сможет сделать с ним злоумышленник это положить его на свой сервер, чтобы вы к нему могли подключиться с помощью закрытого ключа. Если очень упрощать, ключи работают следующим образом: у нас есть закрытый (приватный) ключ, из которого можно сгенерировать открытый, или публичный. Наоборот — нельзя, из открытого ключа мы получить закрытый никак не можем. После чего, мы можем зашифровать с помощью закрытого ключа какую-то строку, а при помощи открытого — расшифровать ее и тем самым убедиться, что у собеседника точно есть закрытый ключ, а значит, он тот, за кого себя выдает. Таким образом, мы можем без проблем передавать открытый ключ — он всего лишь позволяет проверить подлинность автора, но не притвориться им.
Это как в SSH — публичный ключ лежит на сервере, где его потеря небольшая беда: все что сможет сделать с ним злоумышленник это положить его на свой сервер, чтобы вы к нему могли подключиться с помощью закрытого ключа.
Так вот, в WG первый этап подключения заключается в том, что каждая сторона с помощью зашифрованного приватным ключом сообщения доказывает собеседнику, что она именно она: это проверяется публичным ключом. Так вот, в WG первый этап подключения заключается в том, что каждая сторона с помощью зашифрованного приватным ключом сообщения доказывает собеседнику, что она именно она: это проверяется публичным ключом.
Второй этап — это создание с помощью этих ключей и матана симметричных ключей для шифрования самого трафика. Благодаря тому, что расшифровать зашифрованное публичным ключом нельзя без приватного, мы сможем создать ключ для симметричного шифрования и отправить его по защищенному каналу. Этот шаг необходим потому, что симметричное шифрование — это гораздо менее ресурсоемкая операция, и минус у нее только один: необходимость синхронизации ключа у обоих сторон, при том, что перехват ключа третьей стороной ведет к возможности расшифровки трафика. Но эта проблема решается с помощью ассиметричной схемы. Это называется "Протокол Диффи — Хеллмана" — способ защищенного получения общего секретного ключа. В WG используется ECDH — вариация Диффи-Хеллмана на эллиптических кривых. Первые два этапа в терминах WG называется рукопожатием или хендшейком. Второй этап — это создание с помощью этих ключей и матана симметричных ключей для шифрования самого трафика. Благодаря тому, что расшифровать зашифрованное публичным ключом нельзя без приватного, мы сможем создать ключ для симметричного шифрования и отправить его по защищенному каналу. Этот шаг необходим потому, что симметричное шифрование — это гораздо менее ресурсоемкая операция, и минус у нее только один: необходимость синхронизации ключа у обоих сторон, при том, что перехват ключа третьей стороной ведет к возможности расшифровки трафика. Но эта проблема решается с помощью ассиметричной схемы. Это называется "Протокол Диффи — Хеллмана" — способ защищенного получения общего секретного ключа. В WG используется ECDH — вариация Диффи-Хеллмана на эллиптических кривых. Первые два этапа в терминах WG называется рукопожатием или хендшейком.
После всего этого эти симметричные ключи используются уже для шифрования трафика. Раз в 2 минуты происходит новое рукопожатие, и сессионные ключи меняются. После всего этого эти симметричные ключи используются уже для шифрования трафика. Раз в 2 минуты происходит новое рукопожатие, и сессионные ключи меняются.
Разумеется, все немного сложнее — например, отправляются не сами ключи, а сгенерированные на основе их эферемные ключи, которые удаляются сразу после операции, и так далее. Заинтересовавшихся отправляю к [краткому описанию криптографии](https://www.wireguard.com/protocol/). Разумеется, все немного сложнее — например, отправляются не сами ключи, а сгенерированные на основе их эферемные ключи, которые удаляются сразу после операции, и так далее. Заинтересовавшихся отправляю к [краткому описанию криптографии](https://www.wireguard.com/protocol/).
А мы же перейдем к более практическим действиям. А мы же перейдем к более практическим действиям.
## Шаг первый: создаем и настраиваем два сервера. ## Шаг первый: создаем и настраиваем два сервера.
@ -133,7 +137,7 @@ root@:~# ip route | awk '/default/ { print $5 }'
Продолжим писать конфиг: в оба конфига надо добавить секцию **Peer**, чтобы связать сервера друг с другом. Продолжим писать конфиг: в оба конфига надо добавить секцию **Peer**, чтобы связать сервера друг с другом.
Я намеренно не привожу сразу готовые конфиги, потому что хочу показать механизм создания конфигов в ручном режиме — в свое время у меня были проблемы с тем, что я генерировал конфиги утилитами типа ```easy-wg-quick``` или веб-интерфейсами, которые спрашивают тебя о названии клиента и красиво показывают QR-код, но отнюдь не способствуют пониманию того, как работает WG на самом деле. Я намеренно не привожу сразу готовые конфиги, потому что хочу показать механизм создания конфигов в ручном режиме — в свое время у меня были проблемы с тем, что я генерировал конфиги утилитами типа ```easy-wg-quick``` или веб-интерфейсами, которые спрашивают тебя о названии клиента и красиво показывают QR-код, но отнюдь не способствуют пониманию того, как работает WG на самом деле.
Итак, добавляем в каждый конфиг по секции **Peer**, для чего генерируем из приватного ключа публичный (вот в ```pubkey``` как раз происходит крипто-магия): Итак, добавляем в каждый конфиг секцию **Peer**, для чего генерируем из приватного ключа публичный (вот в ```pubkey``` как раз происходит крипто-магия):
```bash ```bash
echo "kOd3FVBggwpjD3AlZKXUxNTzJT0+f3MJdUdR8n6ZBn8=" | wg pubkey echo "kOd3FVBggwpjD3AlZKXUxNTzJT0+f3MJdUdR8n6ZBn8=" | wg pubkey
MxnOnIlKfSyZyRutnYyoWHb3Izjalgf1t8F1oPJiyyw= MxnOnIlKfSyZyRutnYyoWHb3Izjalgf1t8F1oPJiyyw=
@ -158,8 +162,9 @@ PersistentKeepalive=25
В данных примерах **AllowedIPs** можно читать как "адреса, трафик на которые будет маршрутизироваться в туннель этого пира, и с которых пир сможет отправить что-то в туннель". В данных примерах **AllowedIPs** можно читать как "адреса, трафик на которые будет маршрутизироваться в туннель этого пира, и с которых пир сможет отправить что-то в туннель".
То есть, пункт ```AllowedIPs = 10.20.30.3/32``` означает, буквально, "только запросы на 10.20.30.3 (адрес пира WG) отправлять в туннель", т.е. дать доступ только до машины этого клиента. То есть, пункт ```AllowedIPs = 10.20.30.3/32``` означает, буквально, "только запросы на 10.20.30.3 (адрес пира WG) отправлять в туннель", т.е. дать доступ только до машины этого клиента.
Пункт ```AllowedIPs = 192.168.88.0/24``` означает, что при запросе адреса из этой подсети этот запрос уйдет в туннель клиента, и если у него включен форвардинг и ему доступна эта подсеть, то к ней можно будет получить доступ. Пункт ```AllowedIPs = 192.168.88.0/24``` означает, что при запросе адреса из этой подсети этот запрос уйдет в туннель клиента, и если у него включен форвардинг и ему доступна эта подсеть, то к ней можно будет получить доступ.
А ```AllowedIPs = 0.0.0.0/0``` означает, что в туннель надо маршрутизировать весь трафик вообще. Правда, это не относится к трафику, например, локальной сети: приоритет у маршрута, который создается из маски подсети и адреса шлюза, выше, чем у 0.0.0.0/0. Также, маршрут 0.0.0.0/0 перебьют маршруты других пиров, если они будут в конфиге. ```AllowedIPs = 0.0.0.0/0``` означает, что в туннель надо маршрутизировать весь трафик вообще. Правда, это не относится к трафику, например, локальной сети: приоритет у маршрута, который создается из маски подсети и адреса шлюза, выше, чем у 0.0.0.0/0. Также, маршрут 0.0.0.0/0 перебьют маршруты других пиров, если они будут в конфиге.
В данном случае ```AllowedIPs=10.20.30.0/24``` означает что трафик с **external** в подсеть 10.20.30.0-10.20.30.255 будет уходить в туннель к **internal**. В принципе, нужды в этом особо нет, **external** у нас исключительно выходная нода. Но вдруг мы как-нибудь захотим зайти оттуда по ssh на какую-нибудь другую машину. В данном случае ```AllowedIPs=10.20.30.0/24``` означает что трафик с **external** в подсеть 10.20.30.0-10.20.30.255 будет уходить в туннель к **internal**. В принципе, нужды в этом особо нет, **external** у нас исключительно выходная нода. Но вдруг мы как-нибудь захотим зайти оттуда по ssh на какую-нибудь другую машину.
Повторяем генерацию публичного ключа с **external**: Повторяем генерацию публичного ключа с **external**:
@ -361,7 +366,7 @@ default via 195.2.79.1 dev ens3 onlink
... ...
``` ```
Вот 195.2.79.1 и ens3 и есть нужные нам данные. Используем уже знакомые нам подстановочные команды и создадим новый маршрут: Вот ```195.2.79.1``` и ```ens3``` и есть нужные нам данные. Используем уже знакомые нам подстановочные команды и создадим новый маршрут:
```bash ```bash
target_ip="212.193.158.175/32" target_ip="212.193.158.175/32"
gateway=`ip route | awk '/default/ {print $3; exit}'` gateway=`ip route | awk '/default/ {print $3; exit}'`
@ -391,24 +396,27 @@ HOST: vvzvladMBP14.local Loss% Snt Last Avg Best Wrst StDev
5.|-- cdn.ngenix.net 0.0% 10 3.8 5.0 3.8 8.4 1.3 5.|-- cdn.ngenix.net 0.0% 10 3.8 5.0 3.8 8.4 1.3
``` ```
Сбермаркет, правда, все еще не открываемся: видимо, проверяет на наличие VPN какой-то другой сервер, а не тот, в адрес которого резолвится имя домена. Ура, сбермаркет открывается! Правда, так может сработать не со всеми сервисами: например, JS на сайте может дернуть другой сервер, а не тот, в адрес которого резолвится имя домена, и до которого нет маршрута.
Можно сходить на https://asnlookup.com/, вбить туда адрес, и получить принадлежность адреса к AS и заодно список подсетей этой autonomous system (AS34879, OOO Sovremennye setevye tekhnologii). С большой вероятностью для более-менее крупных компаний это и будет их сетевая инфраструктура (ну или по крайней мере, инфраструктура, относящаяся к конкретному сайту), прописав для которой маршруты, вы обеспечите доступ на нужный вам сайт/сервис. Для мелких сайтов вы скорее всего получите AS хостера или дата-центра, но, во-первых, это тоже сработает, а во-вторых, мелкие сайты обычно и не закрывают иностранные диапазоны, потому что не испытывают проблем с DDOSом из-за границы. Можно сходить на https://asnlookup.com/, вбить туда адрес, и получить принадлежность адреса к AS и заодно список подсетей этой autonomous system (AS34879, OOO Sovremennye setevye tekhnologii). С большой вероятностью для более-менее крупных компаний это и будет их сетевая инфраструктура (ну или по крайней мере, инфраструктура, относящаяся к конкретному сайту), прописав для которой маршруты, вы обеспечите доступ на нужный вам сайт/сервис. Для мелких сайтов вы скорее всего получите AS хостера или дата-центра, но, во-первых, это тоже сработает, а во-вторых, мелкие сайты обычно и не закрывают иностранные диапазоны, потому что не испытывают проблем с DDOSом из-за границы.
Но можно сделать проще: засунуть в маршруты все адреса российского сегмента (спасибо [статье](https://habr.com/en/post/659655/) на хабре) и не париться о ручном добавлении. Но можно сделать проще и автоматически: засунуть в маршруты вообще все адреса российского сегмента (спасибо [статье](https://habr.com/en/post/659655/) на хабре) и не париться о ручном добавлении.
RIPE отдает их все в виде JSON вот по этому адресу: https://stat.ripe.net/data/country-resource-list/data.json?resource=ru RIPE отдает их все в виде JSON вот по этому адресу: https://stat.ripe.net/data/country-resource-list/data.json?resource=ru
Утилита jq преобразует из json в список подсетей: ```curl https://stat.ripe.net/data/country-resource-list/data.json?resource=ru | jq -r ".data.resources.ipv4[]"``` Утилита ```jq``` преобразует из JSON в список подсетей: ```curl https://stat.ripe.net/data/country-resource-list/data.json?resource=ru | jq -r ".data.resources.ipv4[]"```
Правда, почему-то некоторые адреса там в формате ```195.85.234.0-195.85.236.255```, а не подсети, поэтому для них нам необходима еще утилита ipcalc: Правда, почему-то некоторые адреса там в формате ```195.85.234.0-195.85.236.255```, а не в виде подсети. Их там с десяток, можно было бы и забить, но если уж начали делать, давайте сделаем до конца и красиво.
Нам для них нужна утилита ipcalc:
```bash ```bash
root@trikster-internal:~# ipcalc 195.85.234.0-195.85.236.255 |grep -v "deaggregate" root@trikster-internal:~# ipcalc 195.85.234.0-195.85.236.255 |grep -v "deaggregate"
195.85.234.0/23 195.85.234.0/23
195.85.236.0/24 195.85.236.0/24
``` ```
Выделить эти адреса из базового списка можно банально через ```grep '-'``` или ```grep -v '/'```. Но их там немного, и на них, в принципе, можно забить. Выделить эти адреса из базового списка можно банально через ```grep '-'``` или ```grep -v '/'```.
Скрипт на баше выглядит как-то так (я не удержался и добавил туда еще и прогрессбар): Скрипт на баше выглядит как-то так (я не удержался и добавил туда еще и прогрессбар):
```bash ```bash
#!/bin/bash
function ProgressBar { function ProgressBar {
let _progress=(${1}*100/${2}*100)/100 let _progress=(${1}*100/${2}*100)/100
@ -458,13 +466,14 @@ echo "Routes in routing table: $routes_count"
``` ```
Добавим строчки в крон (```export EDITOR=nano; crontab -e```), чтобы он запускался каждую неделю (для того, чтобы обновить список адресов, если они поменялись) и после перезагрузки: Добавим строчки в крон (```EDITOR=nano crontab -e```), чтобы он запускался после перезагрузки, и каждую неделю для того, чтобы обновить список адресов, если они поменялись:
``` ```
@reboot sleep 30 && bash /root/update_ru_routes.sh > /root/update_routes_log.txt 2>&1 @reboot sleep 30 && bash /root/update_ru_routes.sh > /root/update_routes_log.txt 2>&1
0 3 * * mon bash /root/update_ru_routes.sh > /root/update_routes_log.txt 2>&1 0 3 * * mon bash /root/update_ru_routes.sh > /root/update_routes_log.txt 2>&1
``` ```
Если вам принудительно надо маршрутизировать какую-то сеть через **internal**, то можно рядом со скриптом создать файлик ```subnets_user_list.txt```, в который поместить список подсетей, тогда они каждый раз будут добавляться к общему списку при обновлении, в bash-скрипте это есть. Мой, например, выглядит так: Если вам принудительно надо маршрутизировать какую-то сеть через **internal**, то можно рядом со скриптом создать файлик ```subnets_user_list.txt```, в который поместить список подсетей, тогда они каждый раз будут добавляться к общему списку при обновлении, в bash-скрипте это есть.
Мой, например, выглядит так:
``` ```
#avito #avito
146.158.48.0/21 146.158.48.0/21
@ -477,24 +486,25 @@ echo "Routes in routing table: $routes_count"
95.161.64.0/20 95.161.64.0/20
149.154.160.0/21 149.154.160.0/21
``` ```
Первая подсеть — это для мобильного приложения Авито: ее почему-то не было в списке RIPE. Дальше подсети для Телеграма, чтобы хоть немного ускорить загрузку фото и видео. Первая подсеть — для мобильного приложения Авито: ее почему-то не было в списке RIPE. Дальше подсети для Телеграма, чтобы хоть немного ускорить загрузку фото и видео.
Проверяем: Проверяем:
![](ip.png) ![](ip.png)
Оп, и два разных сервиса показывают нам разные адреса, потому что один хостится где-то внутри россии, а другой — снаружи. Работает! Оп, и два разных сервиса показывают нам разные адреса, потому что один сервис хостится где-то внутри россии, а другой — снаружи. Работает!
Кстати, если у вас **internal** находится в домашней сети, бонусом вы получаете доступ к домашней сети из любого места, где находится устройство со включенным VPN: маршрут 0.0.0.0/0 на устройстве отправляет в VPN весь трафик, а **internal**, замечая трафик в ту подсеть, в которой он находится, отправляет ее в локальный порт, а не в туннель до **external**. Очень удобно: у меня в домашней сети работает сервер с докерами web2rss, ownCloud, navidrome, freshrss, rss-bridge, homeassistant, и мне для получения к ним доступа совершенно не надо заморачиваться с пробросом портов, авторизацией каждого сервера и https. Кстати, если у вас **internal** находится в домашней сети, бонусом вы получаете доступ к домашней сети из любого места, где находится устройство со включенным VPN: маршрут 0.0.0.0/0 на устройстве отправляет в VPN весь трафик, а **internal**, замечая трафик в ту подсеть, в которой он находится, отправляет ее в локальный порт, а не в туннель до **external**. Очень удобно: у меня в домашней сети работает сервер с докерами web2rss, ownCloud, navidrome, freshrss, rss-bridge, homeassistant, и мне для получения к ним доступа совершенно не надо заморачиваться с пробросом портов, авторизацией каждого сервера и https, не говоря уж о том, что некоторые сервисы, типа IoT-устройств, не имеют ни авторизации, ни шифрования в принципе.
Окончательная схема выглядит так: Окончательная схема выглядит так:
![](net_scheme_3.png) ![](net_scheme_3.png)
## Шаг пятый: настраиваем фаервол ## Шаг пятый: настраиваем фаервол
Хорошей привычкой и тоном будет закрытие всего ненужного на серверах. Полезной привычкой и хорошим тоном будет закрытие всего ненужного на серверах.
Для начала на обоих серверах редактируем файл ```/etc/default/ufw```, изменяя значение "**DEFAULT_FORWARD_POLICY**" на **ACCEPT**. Для начала на обоих серверах редактируем файл ```/etc/default/ufw```, изменяя значение "**DEFAULT_FORWARD_POLICY**" на **ACCEPT**.
Теперь выполняем следующие команды на **internal**: Теперь выполняем следующие команды на **internal**:
```bash ```
ufw reset ufw reset
ufw default deny incoming ufw default deny incoming
ufw default allow outgoing ufw default allow outgoing
@ -507,7 +517,7 @@ ufw enable
Что происходит, думаю, понятно — запретить все, разрешить исходящие, входящие ssh и подключения к WG, а что приходит из туннеля — разрешить. Что происходит, думаю, понятно — запретить все, разрешить исходящие, входящие ssh и подключения к WG, а что приходит из туннеля — разрешить.
На **external** тоже самое, но открывать порт для WG не надо — он подключается сам. На **external** тоже самое, но открывать порт для WG не надо — он подключается сам.
```bash ```
ufw reset ufw reset
ufw default deny incoming ufw default deny incoming
ufw default allow outgoing ufw default allow outgoing
@ -517,10 +527,13 @@ systemctl enable ufw --now
ufw enable ufw enable
``` ```
Еще хорошо бы поставить и настроить fail2ban, или хотя бы перенести ssh на другой порт. В любом случае, отключение парольной авторизации на ssh вообще и переход только на ключи — это базовая операция. Еще хорошо бы поставить и настроить fail2ban, или хотя бы перенести SSH на другой порт. В любом случае, отключение входа по паролю через SSH вообще и переход только на ключевую авторизацию — это базовая операция, независимо ни от чего.
## Шаг шестой, бонусный и необязательный: кеширующий защищенный DNS over HTTPS ## Шаг шестой, бонусный и необязательный: кеширующий защищенный DNS over HTTPS
Теперь нам нужна еще одна вещь: DNS. Можно, конечно, жить с DNS 1.1.1.1, но надо учитывать, что трафик на него пойдет через **external**, что автоматически означает задержку порядка 100мс при каждом запросе. Можно, конечно, добавить 1.1.1.1/32 в ```subnets_user_list.txt```, и тогда трафик пойдет через локальную ноду и локальный сервер 1.1.1.1, что уменьшит задержку до 10-20мс, но ваши DNS-запросы будет доступны вашему провайдеру, что в случае локальной ноды может быть для кого-то неприемлемо. Несколькими командами можно легко сделать кеширующий DNS, который еще и будет работать с DNS over HTTPS, а значит, провайдеру будет доступен только сам факт использовании DoH, но не сами запросы. Но это, конечно, не обязательно: у меня **internal** находится в домашней сети, и я просто использую DNS микротика, который находится в той же сети и умеет в DoH. Но если у вас **internal** сервер это VPS, то можно сделать там и DNS сервер. Использовать будем ```cloudflared``` и ```dnsmasq```. Теперь нам нужна еще одна вещь: DNS.
Можно, конечно, жить с DNS 1.1.1.1, но надо учитывать, что трафик на него пойдет через **external**, что автоматически означает задержку порядка 100мс при каждом запросе. Можно, конечно, добавить 1.1.1.1/32 в ```subnets_user_list.txt```, и тогда трафик пойдет через локальную ноду и локальный сервер 1.1.1.1, что уменьшит задержку до 10-20мс, но ваши DNS-запросы будет доступны вашему провайдеру, что в случае локальной ноды может быть для кого-то неприемлемо.
Несколькими командами можно легко сделать кеширующий DNS, который еще и будет работать с DNS over HTTPS, а значит, провайдеру будет доступен только сам факт использовании DoH, но не сами запросы. Но это, конечно, не обязательно: у меня **internal** находится в домашней сети, и я просто использую DNS микротика, который находится в той же сети и умеет в DoH. Но если у вас **internal** сервер это VPS, то можно сделать там и DNS сервер. Использовать будем ```cloudflared``` и ```dnsmasq```.
Добавляем репозитарий: Добавляем репозитарий:
```bash ```bash
@ -611,6 +624,7 @@ P.S. особые параноики могут запустить cloudflared
## Заключение ## Заключение
Пары ключей в статье — действующие, так что вы можете, ничего не исправляя в конфигах (только IP **internal**-сервера), залить их на свои сервера и клиент и поиграться. Но для боевого применения ключи надо перегенерить, конечно. Пары ключей в статье — действующие, так что вы можете, ничего не исправляя в конфигах (только IP **internal**-сервера), залить их на свои сервера и клиент и поиграться. Но для боевого применения ключи надо перегенерить, конечно.
Благо, сделать это просто, даже если вам лень разбираться с ручной генерацией ключей — я сделал небольшой bash-скрипт для этого. Достаточно сделать так на **internal**-сервере: Благо, сделать это просто, даже если вам лень разбираться с ручной генерацией ключей — я сделал небольшой bash-скрипт для этого. Достаточно сделать так на **internal**-сервере:
```bash ```bash