- Регистрация
- 23 Август 2023
- Сообщения
- 3 710
- Лучшие ответы
- 0
- Реакции
- 0
- Баллы
- 243
Offline
Ты завёл себе домашний сервер. Развернул пару удобных сервисов: фотохостинг, облако, панель управления, мониторинг. Всё крутится, всё работает, доступ из интернета есть, какая красота скажешь ты.
Но вот только одна мелочь… про защиту-то ты и забыл.
Пока сервер никому не интересен, всё кажется в порядке и ни о чём не беспокоишься. Но стоит оставить хоть одну админку открытой наружу, как на неё придут боты, сканеры и «коллекционеры чужих логинов». Через неделю в логах можно увидеть десятки попыток авторизации, а через месяц вполне реальный взлом.
Так что, если ты хочешь спокойно использовать свой сервер без страха, что кто-то вскроет админку, то пора задуматься о защите. Не о громоздких корпоративных решениях, а о простом и понятном инструменте, который создаёт надёжный частный контур вокруг твоих сервисов.
Именно это и будет делать VPN. Он не просто будет шифровать трафик, а еще определять, кто вообще имеет право попасть к твоему серверу.
Тут все без магии и долгой настройки. Я сам считал, что это не так то просто и нужно обладать определенными навыками на уровне сетевого инженера. На деле же все делается за один вечер, если следовать уже рабочей схеме и не собирать грабли.
Эта статья как раз поможет тебе пройти весь путь без лишней боли.
Ее я уже испытал за тебя, высиживая часами, матерясь на монитор и пытаясь понять, почему «оно не работает, всё же сделано правильно».
Я продумал, как сделать настройку проще и понятнее, исправил собственные ошибки и теперь делюсь готовым, проверенным решением, которое тебе останется только повторить и докрутить под свои сервисы.
📌 Важное уточнение: В этой статье я исхожу из того, что у тебя есть статический IP-адрес (или белый IP от провайдера) и на него настроен домен (например, home-server.ru). Это стандартная и самая распространённая конфигурация для домашнего сервера с внешним доступом.
Если у тебя другая ситуация: DDNS, проброс через NAT провайдера, Cloudflare Tunnel или что-то ещё — тебе нужно будет адаптировать решение под свой случай. Если возникнут сложности, напиши в комментариях или в мой Telegram-канал — разберу твой кейс и, возможно, дополню статью или выпущу отдельный материал.
Содержание
1 Механизм работы
Прежде чем «натягивать» защиту и переходить к конфигам, разберём общую логику.
Проще говоря:
Такой подход даёт гибкость в разделении: какие сервисы остаются публичными, а какие - физически недоступны без VPN.
1.1 схема разделения доступов
🌍 ПУБЛИЧНАЯ ЗОНА (Интернет)
────────────────────────────────────────────────────────────────────────
HTTPS :443 UDP :51820
────────────────────────────────────────────────────────────────────────
│ │
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ РОУТЕР │ │ РОУТЕР │
│ проброс 80, 443 │ │ проброс 51820 (VPN)│
└────────┬───────────┘ └──────────┬─────────┘
│ │
│ ▼
обычный клиент (145.168.21.43) ┌──────────────────────────────────┐
│ │ │
│ │ - WireGuard (10.8.0.0/24) │
▼ │ - dnsmasq (локальный DNS) │
┌───────────────────────────────┐ │ │
│ │ │ ▸ резолвит: │
│ - nginx │ │ photos.home-server.ru │
│ │ │ home-server.ru │
│ - photos.home-server.ru │ └────────────────┬─────────────────┘
│ Immich прямой доступ │ │
│ - home-server.ru → │ │
│ Proxmox │ ▼
│ только для (10.8.0.0/24) │ ◀───── VPN-клиент (10.8.0.x)
└───────────────┬───────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ - Immich публичный фото-сервис │
│ - Proxmox доступен только из VPN │
└─────────────────────────────────────────────────────┘
Главная идея состоит в том, что для сервисов, которые мы хотим защитить, в nginx будет фильтрация доступа к сервисам по IP клиента: если IP подходит под маску VPN-клиента — пропускаем, не подходит — отвечаем 403.
Чтобы собрать эту схему, нужны три компонента: VPN, reverse-proxy и локальный DNS-резолвер.
1.2 VPN - закрытый вход в частную сеть
VPN (в моём случае - WireGuard) создаёт защищённый туннель между твоим устройством и домашней сетью.
Подключившиеся клиенты получают адреса из отдельной подсети - например, 10.8.0.0/24. То есть при подключении по VPN образуется своя «виртуальная» сеть со своими IP.
Только эти IP-адреса имеют право обращаться к приватным сервисам (это контролируется на уровне NGINX и/или firewall).
1.3 Reverse-proxy - единая точка входа
Reverse-proxy (в моём случае - NGINX) принимает входящие запросы на 80/443 и решает, что с ними делать:
Иными словами, это диспетчер трафика: знает, что куда идёт, и не пропускает лишнего.
1.4 Локальный DNS для VPN-клиентов
В моём случае это dnsmasq. Он:
Пример записей:
home-server.ru → 192.168.31.90 (NGINX)
photos.home-server.ru → 192.168.31.90 (NGINX)
На клиентах в конфиге WireGuard пропишем DNS = 10.8.0.1 - тогда резолвинг внутренних имён всегда будет идти через VPN-DNS.
Теперь ты понимаешь, как всё устроено. Дальше идёт практика — настройка каждого компонента по очереди. Не переживай, я старался все пояснять, чтобы даже неопытный пользователь справился с установкой.
2 Настройка роутера
Показывать я буду на примере своей веб панели роутера, она может отличаться от того, что стоит у тебя, но суть ты поймешь.
Детали
Нужно, чтобы IP твоего сервера был постоянным, мы будем использовать его тут и в дальнейшем при настройке конфигураций на сервере.
У меня это выглядит следующим образом:
Здесь я задал постоянный IP - 192.168.31.90
Теперь пробрасываем порты на зарезервированный IP:
3 Настраиваем vpn
В этом разделе мы поднимем VPN-сервер на WireGuard в Docker контейнере.
Он создаст частную подсеть 10.8.0.0/24, через которую будут доступны все приватные сервисы.
Дополнительную информацию по сервису ты можешь получить на официальном сайте.
3.1 Подготовка: установка Docker
Для работы WireGuard в контейнере нам нужен Docker и Docker Compose. Если у тебя уже установлен Docker, можешь пропустить этот раздел.
mkdir ~/vpn
cd ~/vpn
cat << EOF > docker-compose.vpn.yml
version: '3.8'
services:
vpn:
image: linuxserver/wireguard
container_name: vpn
network_mode: "host"
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=0
- PGID=0
- TZ=Europe/Moscow
- SERVERURL=home-server.ru
- SERVERPORT=51820
- PEERS=mackbook,ipad
- PEERDNS=auto
- INTERNAL_SUBNET=10.8.0.0
- ALLOWEDIPS=10.8.0.0/24,192.168.31.90/32
- LOG_CONFS=false
volumes:
- ./wireguard/config:/config
restart: unless-stopped
EOF
Разберём конфигурацию подробнее для того, чтобы ты смог сконфигурировать сервис под свой случай.
Параметры, которые тебе с большей вероятностью нужно будет заменить:
Переменные окружения:
environment:
- PUID=0
- PGID=0
- TZ=Europe/Moscow
- SERVERURL=home-server.ru
- SERVERPORT=51820
- PEERS=mackbook,ipad
- PEERDNS=auto
- INTERNAL_SUBNET=10.8.0.0
- ALLOWEDIPS=10.8.0.0/24,192.168.31.90/32
- LOG_CONFS=false
💡 Совет: Не пугайся количества параметров — в 90% случаев достаточно поменять только SERVERURL и PEERS. Остальное работает "из коробки".
Включаем пересылку пакетов (IP forwarding)
Чтобы VPN-сервер мог маршрутизировать трафик между клиентами и локальной сетью, нужно включить пересылку пакетов:
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Это заставляет сервер работать как маршрутизатор:
Запуск контейнера
Теперь всё готово для запуска VPN-сервера:
docker compose -f docker-compose.vpn.yml up -d
После запуска ты получаешь:
При настройке VPN есть важная особенность, с которой ты можешь столкнуться, если находишься в той же домашней сети, что и сервер.
1 В чём проблема
Параметр AllowedIPs в WireGuard на стороне клиента задаёт маршруты — то есть говорит операционной системе: "вот эти адреса отправляй через VPN-туннель".
Казалось бы, можно указать:
AllowedIPs = 10.8.0.0/24, 192.168.31.0/24
И всё должно работать: VPN-подсеть + вся домашняя сеть. Но вот загвоздка.
Когда ты подключаешься к VPN находясь в той же домашней сети (например, сидишь дома, подключён к своему Wi-Fi с адресом 192.168.31.x), операционная система видит, что адрес 192.168.31.90 (сервер) находится в той же локальной сети, к которой ты уже подключён напрямую.
И тут происходит конфликт приоритетов в таблице маршрутизации:
Локальный маршрут имеет больший приоритет (меньшую метрику), потому что система считает прямое подключение к локальной сети более предпочтительным, чем туннель.
В итоге трафик идёт напрямую, в обход VPN.
2 Как это проявляется
3 Почему так происходит
В таблице маршрутизации ОС правила имеют приоритет по длине префикса (маске подсети):
Но когда маски одинаковые (/24 через Wi-Fi vs /24 через VPN), система смотрит на метрику маршрута — и локальное подключение обычно выигрывает.
4 Решение
Нужно добавить более специфичный маршрут — указать конкретный IP сервера с маской /32. В маршрутизации более конкретный маршрут всегда имеет приоритет над общим, независимо от метрики.
Поэтому вместо:
AllowedIPs = 10.8.0.0/24, 192.168.31.0/24
Используем:
AllowedIPs = 10.8.0.0/24, 192.168.31.90/32
Где 192.168.31.90 — это IP твоего сервера (на котором крутится Nginx иWireGuard).
Теперь:
5 Когда эта проблема НЕ проявляется
Если ты подключаешься к VPN из другой сети (например, с мобильного интернета, из кафе, с работы), там подсеть другая (скажем 172.16.x.x), и конфликта нет — трафик нормально идёт через туннель даже с AllowedIPs = 10.8.0.0/24, 192.168.31.0/24.
Но лучше сразу использовать /32 — это универсально работает везде, независимо от того, откуда ты подключаешься.
📖 Из личного опыта: Я потратил часа 4 на понимание этой проблемы. Перепроверил все конфиги, отследил все хождения запросов, искал ошибку везде. В итоге нашёл информацию об этом нюансе в интернете — оказалось, всё дело в приоритетах маршрутизации. Теперь ты не потратишь эти 4 часа!
3.4 Добавление VPN-клиентов
Чтобы добавить больше узлов/клиентов, необходимо увеличить PEERS значение в нашем docker-compose.vpn.yml или добавить больше элементов в список и пересоздать контейнер.
docker compose -f docker-compose.vpn.yml down
docker compose -f docker-compose.vpn.yml up -d
🎉 Отлично! VPN-сервер запущен и готов к работе. Но клиентам ещё нужно научиться обращаться к сервисам по доменам вместо IP. Для этого настроим DNS.
4 Настраиваем DNS-резолвер (dnsmasq)
Чтобы клиенты VPN могли обращаться к сервисам по доменам (home-server.ru, photos.home-server.ru и т.п.), добавим лёгкий DNS-сервер dnsmasq.
Установка
Как это работает
Проверка работы
Хорошо, DNS настроен! Осталось настроить Nginx — и защита будет полной. Это последний технический шаг перед подключением устройств.
5 Настраиваем Reverse-proxy
В этом разделе я буду показывать всё на примере nginx - одного из самых популярных HTTP‑серверов, который часто используется в качестве reverse‑proxy.
Подробнее с возможностями и конфигурацией nginx можно ознакомиться в официальной документации.
Мы не будем подробно рассматривать настройку поддержки TLS в nginx, поскольку это выходит за рамки текущей статьи. Тем не менее, настоятельно рекомендую добавить её. Для этого достаточно настроить Certbot, что несложно и хорошо документировано. То, как это настроить, хорошо поясняется на сайте проекта.
5.1 Вариант A - «Всё в Docker» (рекомендую)
Этот вариант подразумевает, что и Nginx, и сами сервисы живут в Docker и общаются друг с другом по внутренней сети Docker, без лишних пробросов портов и танцев с IP‑адресами.Nginx смотрит наружу (80/443), а внутри проксирует запросы в другие контейнеры по их именам внутри одной сети edge_net.
docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
- "443:443"
networks:
- edge_net
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
edge_net:
external: true
docker-compose.app.yml
version: '3.8'
services:
myapp:
image: myapp:latest
container_name: nginx
expose:
- "9000" # порт доступен только внутри сети edge_net
networks:
- edge_net
networks:
edge_net:
external: true
конфигурация nginx.conf
events {}
http {
upstream myapp {
server myapp:9000;
}
server {
listen 80;
server_name home-server.ru;
# доступ только из VPN
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp;
}
}
}
Плюсы подхода
- Всё изолировано внутри Docker: порты приложений не торчат на хост, наружу выходят только 80/443 с nginx.
- Упрощённый DNS: в proxy_pass и upstream используем имена сервисов ( myapp ), Docker сам резолвит их в IP.
Минусы подхода
- Требует «докеризовать» приложение.
- Отладка иногда чуть менее наглядна: нужно помнить про внутреннюю сеть Docker и её DNS, а не просто стучаться на localhost:port.
как добавить в текущую реализацию
Создаем docker сеть для nginx и сервисов:
docker network create edge_net
Создаем для удобства директорию nginx:
mkdir ~/nginx
cd ~/nginx
Создаем файл nginx.conf:
cat << EOF > nginx.conf
events {}
http {
upstream myapp {
server myapp:9000;
}
server {
listen 80;
server_name home-server.ru;
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp;
}
}
}
EOF
Создаём файл docker-compose.nginx.yml:
cat << EOF > docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
- "443:443"
networks:
- edge_net
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
edge_net:
external: true
EOF
Не забудьте добавить свой docker сервис в сеть edge_net
Запускаем nginx:
docker compose -f docker-compose.nginx.yml up -d
5.2 Вариант B - «Nginx в Docker → сервис на хосте»
Этот вариант нужен, когда приложение крутится на хосте, у него свой порт (например, 127.0.0.1:9000 ), и ты не хочешь/не можешь его перенести в Docker.
Здесь мы просто запускаем nginx в контейнере и даём ему доступ к сети хоста.
docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
network_mode: host # контейнер использует сеть хоста
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
nginx.conf
events {}
http {
upstream myapp_host {
server 127.0.0.1:9000; # существующий сервис на хосте
}
server {
listen 80;
server_name home-server.ru;
# доступ только из VPN
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp\\\_host;
}
}
}
Плюсы подхода
- Не нужно переносить существующий сервис в Docker - он остаётся как есть, ты добавляешь только тонкий Nginx‑слой поверх.
- Простая схема отладки: бекенд по‑прежнему доступен на 127.0.0.1:9000 , Nginx на 80/443 того же хоста.
- Хорошо подходит для «старых» или тяжёлых сервисов, где контейнеризация откладывается на потом.
Минусы подхода
- Если на хосте уже есть другой веб‑сервер на 80/443, придётся либо переносить его, либо разруливать конфликты портов.
- В отличие от варианта «всё в Docker», приложение всё ещё «торчит» на хосте (хотя только на 127.0.0.1 ), и часть сетевой логики остаётся вне Docker.
как добавить в текущую реализацию
Создаем для удобства директорию nginx:
mkdir ~/nginx
cd ~/nginx
Создаем файл nginx.conf:
cat << EOF > nginx.conf
events {}
http {
upstream myapp_host {
server 127.0.0.1:9000;
}
server {
listen 80;
server_name home-server.ru;
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp\\\\_host;
}
}
}
EOF
Создаём файл docker-compose.nginx.yml:
cat << EOF > docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
network_mode: host
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
EOF
Запускаем nginx:
docker compose -f docker-compose.nginx.yml up -d
5.3 Вариант C - «Всё на хосте (без Docker)»
Этот вариант для максимально простой схемы. Все компоненты, приложения и nginx установлены прямо на хосте, без контейнеров.
Плюсы подхода
- Минимум частей: ничего не нужно устанавливать и обновлять в контейнерах, только пакеты ОС.
- Хорош для небольшого домашнего сервера или одной‑двух служб, когда Docker избыточен.
Минусы подхода
- Нет изоляции приложений: все процессы делят одну систему (библиотеки, окружение, зависимости).
- Развёртывание и обновление сложнее повторять: нет декларативного описания в compose‑файле, всё завязано на состояние хоста.
- При росте числа сервисов конфигурация на голом хосте начинает быстро обрастать «зоопарком» юнитов, пакетов и ручных настроек.
как добавить в текущую реализацию
Установите nginx и включите его в автозапуск:
sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
Отключаем дефолтный сайт Ubuntu, чтобы он не мешал нашему конфигу:
sudo rm /etc/nginx/sites-enabled/default
Создаем конфиг для нашего домена:
sudo tee /etc/nginx/sites-available/home-server.ru >/dev/null << 'EOF'
server {
listen 80;
server_name home-server.ru;
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://127.0.0.1:9000;
}
}
EOF
Включаем сайт и проверяем конфигурацию:
sudo ln -s /etc/nginx/sites-available/home-server.ru /etc/nginx/sites-enabled/home-server.ru
sudo nginx -t
Перезапускаем nginx, чтобы применить изменения:
sudo systemctl restart nginx
Вся инфраструктура готова! Теперь самое приятное — подключить свои устройства к VPN и проверить, что всё работает.
6 Устанавливаем VPN-конфиг на устройства
На этом этапе у нас уже есть:
Осталось забрать нужный .conf на устройство и импортировать его в официальное приложение WireGuard.
6.1 Где найти конфиги клиентов
Конфиги были автоматически сгенерированы при первом запуске контейнера WireGuard.
Заходим в директорию с конфигами:
cd ~/vpn/wireguard/config/
ls
В консоли ты увидишь директории с префиксом peer_ — это конфиги для VPN-клиентов. В моём случае это peer_mackbook и peer_ipad.
Заходим в директорию нужного клиента:
cd peer_mackbook
ls
Здесь лежат два файла:
Выведем в консоль содержимое конфига:
cat peer_mackbook.conf
Пример того, что увидишь:
[Interface]
Address = 10.8.0.2/32
PrivateKey = <приватный ключ клиента>
DNS = 10.8.0.1
[Peer]
PublicKey = <публичный ключ сервера>
PresharedKey = <общий ключ>
Endpoint = home-server.ru:51820
AllowedIPs = 10.8.0.0/24, 192.168.31.90/32
PersistentKeepalive = 25
Разбор параметров:
Секция [Interface] (настройки клиента):
Перейди на официальный сайт WireGuard и скачай приложение для своей платформы
6.4 Импорт конфига на ПК (Windows/macOS/Linux)
Скопируй файл конфига с сервера на свой компьютер:
Вариант A — через SCP:
scp user@192.168.31.90:~/vpn/wireguard/config/peer_ipad/peer_ipad.conf ~/Downloads/
Вариант B — вручную:
Передай файл с компьютера на мобильное устройство:
Импортируй конфиг в приложение WireGuard:
Активируй подключение:
Скопируй файл конфига с сервера на свой компьютер:
Вариант A — через SCP:
scp user@192.168.31.90:~/vpn/wireguard/config/peer_ipad/peer_ipad.conf ~/Downloads/
Вариант B — вручную:
Передай файл с компьютера на мобильное устройство:
Импортируй конфиг в приложение WireGuard:
Активируй подключение:
После активации VPN проверь доступ к защищённому сервису.
Проверь доступ с включённым VPN:
Открой браузер и введи:
http://home-server.ru
Должен открыться твой сервис.
Проверь, что блокировка работает БЕЗ VPN: Отключи VPN в приложенииWireGuard и попробуй снова открыть http://home-server.ru. Теперь должна быть ошибка подключения или 403 Forbidden — это значит, что защита работает, и без VPN доступа нет.
🎉 Поздравляю! VPN настроен и работает. Переходим к финальной проверке всей системы.
7 Набор быстрых проверок (self-audit)
Перед тем как считать настройку законченной, пройдём по ключевым точкам и убедимся, что всё работает корректно.
7.1 Проверка VPN-сервера
Убедимся, что контейнер WireGuard запущен и интерфейс поднят.
Проверим, что dnsmasq слушает на VPN-интерфейсе и корректно резолвит внутренние домены.
Убедимся, что Nginx запущен и правильно фильтрует доступ по IP.
Финальная проверка всей цепочки с клиентского устройства (компьютер, телефон, планшет).
Подключаемся к VPN:
Проверяем доступ к защищённому домену:
Если всё работает — поздравляем, защита настроена!
Проверяем блокировку без VPN:
Это подтверждает, что без VPN доступ действительно закрыт.
8 Что делать, если не работает
Если что-то пошло не так, не паникуй. Большинство проблем решаются за несколько минут, если знать, куда смотреть.
Добро пожаловать в раздел отладки! Если ты здесь, значит что-то пошло не так. Не переживай — 9 из 10 проблем решаются проверкой логов и перечитыванием конфигов. Разберём самые частые случаи.
8.1 VPN не подключается
Симптомы:
Что проверить:
1 Порт 51820/UDP открыт на роутере?
Проверь настройки проброса портов на роутере (см. главу 2). Убедись, что:
2 Контейнер WireGuard запущен?На сервере проверь статус:
docker ps | grep vpn
Должен увидеть контейнер vpn в статусе Up. Если его нет:
cd ~/vpn
docker compose -f docker-compose.vpn.yml up -d
3 Интерфейс wg0 поднят?
Проверь на сервере:
ip a show wg0
Должен увидеть интерфейс с адресом 10.8.0.1/24 в состоянии UP.
Если интерфейса нет — перезапусти контейнер:
docker restart vpn
4 Firewall на сервере не блокирует порт?
Проверь, есть ли активный firewall:
sudo ufw status
Если активен — добавь правило для WireGuard:
sudo ufw allow 51820/udp
sudo ufw reload
5 Смотрим логи WireGuard
Логи контейнера покажут, в чём проблема:
docker logs vpn --tail 50
8.2 DNS не резолвит домены
Симптомы:
Что проверить:
1 DNS указан в клиентском конфиге?
Открой файл конфига на устройстве (в приложении WireGuard → Edit):
[Interface]
DNS = 10.8.0.1
Параметр DNS должен быть равен 10.8.0.1. Если его нет — добавь вручную и сохрани.
2 dnsmasq запущен на сервере?
Проверь статус:
sudo systemctl status dnsmasq
Должен быть active (running). Если нет:
sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq
3 dnsmasq слушает на 10.8.0.1?
Проверь:
sudo ss -tulpn | grep ':53'
Должен увидеть dnsmasq на адресах 10.8.0.1:53 и 127.0.0.1:53.
Если не слушает на 10.8.0.1 — проверь конфиг ~/vpn/dnsmasq.conf:
cat ~/vpn/dnsmasq.conf
Должны быть строки:
listen-address=10.8.0.1
listen-address=127.0.0.1
interface=wg0
Если конфиг неправильный — исправь и перезапусти:
sudo systemctl restart dnsmasq
4 Домены прописаны в dnsmasq?
Проверь:
grep 'address=' ~/vpn/dnsmasq.conf
Должен увидеть:
address=/home-server.ru/192.168.31.90
address=/photos.home-server.ru/192.168.31.90
Если нет — добавь вручную (см. главу 4).
5 Тестируем резолвинг с сервера
На сервере выполни:
dig @10.8.0.1 home-server.ru
В секции ANSWER должен быть IP 192.168.31.90. Если нет — проблема в конфиге dnsmasq.
6 Тестируем резолвинг с клиента
На клиенте (с активным VPN):
macOS/Linux:
nslookup home-server.ru
Windows (PowerShell):
nslookup home-server.ru
Должен вернуть 192.168.31.90. Если возвращает другой IP или ошибку — DNS клиента не использует VPN.
8.3 Nginx отдаёт ошибки
1 Forbidden
Причина: Nginx видит IP клиента, который не входит в разрешённую подсеть 10.8.0.0/24.
Что проверить:
2 Bad Gateway
Причина: Nginx не может достучаться до бэкенд-сервиса.
Что проверить:
3 Gateway Timeout
Причина: Сервис отвечает слишком долго (более 60 секунд).
Решение: Увеличь таймаут вNginx:
proxy_read_timeout 300;
proxy_connect_timeout 300;
8.4 Чеклист диагностики
Если не знаешь, с чего начать — проходи по этому списку сверху вниз:
8.5 Нужна помощь?
Если ты прошёл весь чеклист, но проблема не решилась:
Помни: 90% проблем решаются внимательным чтением логов и проверкой конфигов. Не спеши, всё получится!
9 Итоги
9.1 Что мы построили
🎉 Поздравляю! Ты прошёл путь от открытого сервера до защищённой инфраструктуры с VPN-доступом.
Вот что теперь у тебя есть:
Всё это работает вместе как единая система: VPN создаёт частную сеть, DNS резолвит внутренние домены, а Nginx пропускает только авторизованных клиентов.
9.2 Преимущества решения
🔒 Безопасность:
✨ Простота:
🔧 Гибкость:
9.3 Когда это решение подходит
✅ Используй эту схему, если:
❌ НЕ подходит, если:
9.4 Обратная связь
Поделись результатом:
Больше материалов и то, чем занимаюсь я, публикую в своём Telegram-канале. Подписывайся, если хочешь держать руку на пульсе!
Если эта статья была полезна, жду твоего фидбека и комментариев.
Возможно я дополню статью твоим кейсом и упоминанием или найду идеи на новые статьи. Буду рад любой форме обратной связи!
10 Финал
Если ты дочитал до конца, значит, тот самый «ненадёжно открытый сервер из вступления» у тебя превратился в аккуратно закрытый контур с VPN. Поблагодари себя за проделанную работу и спи спокойно — за сервисы теперь можно не переживать.
*хотя абсолютной безопасности не существует.
Но вот только одна мелочь… про защиту-то ты и забыл.
Пока сервер никому не интересен, всё кажется в порядке и ни о чём не беспокоишься. Но стоит оставить хоть одну админку открытой наружу, как на неё придут боты, сканеры и «коллекционеры чужих логинов». Через неделю в логах можно увидеть десятки попыток авторизации, а через месяц вполне реальный взлом.
Так что, если ты хочешь спокойно использовать свой сервер без страха, что кто-то вскроет админку, то пора задуматься о защите. Не о громоздких корпоративных решениях, а о простом и понятном инструменте, который создаёт надёжный частный контур вокруг твоих сервисов.
Именно это и будет делать VPN. Он не просто будет шифровать трафик, а еще определять, кто вообще имеет право попасть к твоему серверу.
Тут все без магии и долгой настройки. Я сам считал, что это не так то просто и нужно обладать определенными навыками на уровне сетевого инженера. На деле же все делается за один вечер, если следовать уже рабочей схеме и не собирать грабли.
Эта статья как раз поможет тебе пройти весь путь без лишней боли.
Ее я уже испытал за тебя, высиживая часами, матерясь на монитор и пытаясь понять, почему «оно не работает, всё же сделано правильно».
Я продумал, как сделать настройку проще и понятнее, исправил собственные ошибки и теперь делюсь готовым, проверенным решением, которое тебе останется только повторить и докрутить под свои сервисы.
📌 Важное уточнение: В этой статье я исхожу из того, что у тебя есть статический IP-адрес (или белый IP от провайдера) и на него настроен домен (например, home-server.ru). Это стандартная и самая распространённая конфигурация для домашнего сервера с внешним доступом.
Если у тебя другая ситуация: DDNS, проброс через NAT провайдера, Cloudflare Tunnel или что-то ещё — тебе нужно будет адаптировать решение под свой случай. Если возникнут сложности, напиши в комментариях или в мой Telegram-канал — разберу твой кейс и, возможно, дополню статью или выпущу отдельный материал.
1 Механизм работы
1.1 Схема разделения доступов
1.2 VPN - закрытый вход в частную сеть
1.3 Reverse-proxy - единая точка входа
1.4 Локальный DNS для VPN-клиентов
2 Настройка роутера
3 Настраиваем VPN
3.1 Подготовка: установка Docker
3.2 Запускаем WireGuard в Docker
3.3 Важный нюанс: проблема с одинаковыми подсетями
3.4 Добавление VPN-клиентов
4 Настраиваем DNS-резолвер (dnsmasq)
4.1 Как это работает
4.2 Проверка работы
5 Настраиваем Reverse-proxy
5.1 Вариант A - «Всё в Docker» (рекомендую)
5.2 Вариант B - «Nginx в Docker → сервис на хосте»
5.3 Вариант C - «Всё на хосте (без Docker)»
6 Устанавливаем VPN-конфиг на устройства
6.1 Где найти конфиги клиентов
6.2 Пример клиентского конфига
6.3 Установка приложения WireGuard
6.4 Импорт конфига на ПК (Windows/macOS/Linux)
6.5 Импорт конфига на мобильные (iOS/Android)
6.6 Проверка подключения
7 Набор быстрых проверок (self-audit)
7.1 Проверка VPN-сервера
7.2 Проверка DNS-резолвера
7.3 Проверка Nginx
7.4 Сквозной тест с клиента
8 Что делать, если не работает
8.1 VPN не подключается
8.2 DNS не резолвит домены
8.3 Nginx отдаёт ошибки
8.4 Чеклист диагностики
8.5 Нужна помощь?
9 Итоги
9.1 Что мы построили
9.2 Преимущества решения
9.3 Когда это решение подходит
9.4 Обратная связь
10 Финал
1 Механизм работы
Прежде чем «натягивать» защиту и переходить к конфигам, разберём общую логику.
Публичные сервисы (например, фотогалерея) остаются доступными из интернета по HTTPS - чтобы ими могли пользоваться те, у кого нет конфигурации VPN. При желании их можно в один шаг «завести» за VPN.
Административные панели и всё чувствительное - доступны только через VPN.
Проще говоря:
всё, что нужно друзьям и обычным пользователям - снаружи;
всё, что нужно только тебе - внутри VPN.
Такой подход даёт гибкость в разделении: какие сервисы остаются публичными, а какие - физически недоступны без VPN.
1.1 схема разделения доступов
🌍 ПУБЛИЧНАЯ ЗОНА (Интернет)
────────────────────────────────────────────────────────────────────────
HTTPS :443 UDP :51820
────────────────────────────────────────────────────────────────────────
│ │
▼ ▼
┌────────────────────┐ ┌────────────────────┐
│ РОУТЕР │ │ РОУТЕР │
│ проброс 80, 443 │ │ проброс 51820 (VPN)│
└────────┬───────────┘ └──────────┬─────────┘
│ │
│ ▼
обычный клиент (145.168.21.43) ┌──────────────────────────────────┐
│ │ │
│ │ - WireGuard (10.8.0.0/24) │
▼ │ - dnsmasq (локальный DNS) │
┌───────────────────────────────┐ │ │
│ │ │ ▸ резолвит: │
│ - nginx │ │ photos.home-server.ru │
│ │ │ home-server.ru │
│ - photos.home-server.ru │ └────────────────┬─────────────────┘
│ Immich прямой доступ │ │
│ - home-server.ru → │ │
│ Proxmox │ ▼
│ только для (10.8.0.0/24) │ ◀───── VPN-клиент (10.8.0.x)
└───────────────┬───────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ - Immich публичный фото-сервис │
│ - Proxmox доступен только из VPN │
└─────────────────────────────────────────────────────┘
Главная идея состоит в том, что для сервисов, которые мы хотим защитить, в nginx будет фильтрация доступа к сервисам по IP клиента: если IP подходит под маску VPN-клиента — пропускаем, не подходит — отвечаем 403.
Чтобы собрать эту схему, нужны три компонента: VPN, reverse-proxy и локальный DNS-резолвер.
1.2 VPN - закрытый вход в частную сеть
VPN (в моём случае - WireGuard) создаёт защищённый туннель между твоим устройством и домашней сетью.
Подключившиеся клиенты получают адреса из отдельной подсети - например, 10.8.0.0/24. То есть при подключении по VPN образуется своя «виртуальная» сеть со своими IP.
Только эти IP-адреса имеют право обращаться к приватным сервисам (это контролируется на уровне NGINX и/или firewall).
1.3 Reverse-proxy - единая точка входа
Reverse-proxy (в моём случае - NGINX) принимает входящие запросы на 80/443 и решает, что с ними делать:
отдаёт публичные сервисы «как обычно», без дополнительных фильтров;
ограничивает доступ к приватным доменам (home-server.ru) только для клиентов из VPN-подсети (allow 10.8.0.0/24; deny all
Иными словами, это диспетчер трафика: знает, что куда идёт, и не пропускает лишнего.
1.4 Локальный DNS для VPN-клиентов
В моём случае это dnsmasq. Он:
слушает wg0 (интерфейс VPN) и 127.0.0.1,
отвечает только клиентам VPN по адресу 10.8.0.1,
выдаёт LAN-IP для внутренних доменов, чтобы маршрут до них шёл через туннель, а не в обход.
Пример записей:
home-server.ru → 192.168.31.90 (NGINX)
photos.home-server.ru → 192.168.31.90 (NGINX)
На клиентах в конфиге WireGuard пропишем DNS = 10.8.0.1 - тогда резолвинг внутренних имён всегда будет идти через VPN-DNS.
Теперь ты понимаешь, как всё устроено. Дальше идёт практика — настройка каждого компонента по очереди. Не переживай, я старался все пояснять, чтобы даже неопытный пользователь справился с установкой.
2 Настройка роутера
Показывать я буду на примере своей веб панели роутера, она может отличаться от того, что стоит у тебя, но суть ты поймешь.
Детали
Нужно, чтобы IP твоего сервера был постоянным, мы будем использовать его тут и в дальнейшем при настройке конфигураций на сервере.
У меня это выглядит следующим образом:
Здесь я задал постоянный IP - 192.168.31.90
Теперь пробрасываем порты на зарезервированный IP:
51820/UDP — для WireGuard (VPN-подключения)
80/TCP и 443/TCP — для Nginx (веб-доступ к сервисам)
3 Настраиваем vpn
В этом разделе мы поднимем VPN-сервер на WireGuard в Docker контейнере.
Он создаст частную подсеть 10.8.0.0/24, через которую будут доступны все приватные сервисы.
Дополнительную информацию по сервису ты можешь получить на официальном сайте.
3.1 Подготовка: установка Docker
Для работы WireGuard в контейнере нам нужен Docker и Docker Compose. Если у тебя уже установлен Docker, можешь пропустить этот раздел.
Обновляем систему
sudo apt update
sudo apt upgrade -y
Устанавливаем зависимости
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common gnupg
Добавляем GPG-ключ Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Добавляем официальный репозиторий Docker
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] Index of linux/ubuntu/ https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Обновляем индекс пакетов
sudo apt update
Устанавливаем Docker Engine + Docker Compose plugin
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Запускаем и включаем Docker
sudo systemctl enable docker
sudo systemctl start docker
Добавляем пользователя в группу docker Чтобы не писать sudo перед каждой командой Docker:
sudo usermod -aG docker $USER
Применяем изменения групп
newgrp docker
Или перелогинься в систему, чтобы изменения вступили в силу.
Создаем для удобства директорию vpn:
mkdir ~/vpn
cd ~/vpn
Создаём файл docker-compose.vpn.yml:
cat << EOF > docker-compose.vpn.yml
version: '3.8'
services:
vpn:
image: linuxserver/wireguard
container_name: vpn
network_mode: "host"
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=0
- PGID=0
- TZ=Europe/Moscow
- SERVERURL=home-server.ru
- SERVERPORT=51820
- PEERS=mackbook,ipad
- PEERDNS=auto
- INTERNAL_SUBNET=10.8.0.0
- ALLOWEDIPS=10.8.0.0/24,192.168.31.90/32
- LOG_CONFS=false
volumes:
- ./wireguard/config:/config
restart: unless-stopped
EOF
Разберём конфигурацию подробнее для того, чтобы ты смог сконфигурировать сервис под свой случай.
Параметры, которые тебе с большей вероятностью нужно будет заменить:
Переменные окружения:
environment:
- PUID=0
- PGID=0
- TZ=Europe/Moscow
- SERVERURL=home-server.ru
- SERVERPORT=51820
- PEERS=mackbook,ipad
- PEERDNS=auto
- INTERNAL_SUBNET=10.8.0.0
- ALLOWEDIPS=10.8.0.0/24,192.168.31.90/32
- LOG_CONFS=false
PUID / PGID
UID и GID пользователя внутри контейнера, от имени которого будут созданы файлы в /config.
В примере используется 0 (root) - просто и универсально. При желании можно завести отдельного пользователя.
TZ
Часовой пояс. Нужен для того, чтобы время в логах совпадало с твоим локальным.
SERVERURL
Внешний адрес, по которому к тебе будут подключаться клиенты:
домен (home-server.ru),
или белый IP сервера. Этот параметр попадает в готовые клиентские конфиги как Endpoint =home-server.ru:51820.
SERVERPORT
Порт WireGuard на стороне сервера. Здесь 51820, но можно выбрать любой свободный UDP-порт.
Этот же порт мы уже пробросили на роутере (см. главу 2).
PEERS
Количество клиентов, для которых контейнер сам сгенерирует конфиги, или список имён через запятую. Контейнер сделает автогенерацию wg0.conf +peerX.conf и их QR‑кодов.
Формат:
PEERS=1 - один клиент peer1 .
PEERS=mackbook,ipad - два клиента с такими именами.
PEERDNS
Какой DNS‑сервер будет прописан в конфигурациях клиентов ( DNS = ... ).
Значения:
auto (по умолчанию) - клиенты используют DNS самого контейнера, который в свою очередь форвардит запросы туда же, куда ходит основной хост.
Любой IP, например 1.1.1.1 или 8.8.8.8 .
INTERNAL_SUBNET
Базовый адрес подсети VPN.
В примере: 10.8.0.0, значит, клиенты будут получать адреса вида 10.8.0.x.
ALLOWEDIPS
Какие сети клиент будет маршрутизировать через туннель.
В примере:
10.8.0.0/24 — сама VPN-подсеть (чтобы клиенты видели друг друга и сервер),
192.168.31.90/32 — конкретный IP сервера с маской /32.
⚠️ Важно: Используем именно /32 (один конкретный хост), а не /24 (всю подсеть).
Это гарантирует, что трафик к серверу всегда пойдёт через VPN-туннель, даже когда ты подключён из той же домашней сети — подробности в разделе 3.3 ниже.
Весь остальной интернет-трафик (обычные сайты) будет идти напрямую через твоё текущее подключение (Wi-Fi, мобильный интернет), а не через VPN. Это называется split-tunnel режим — он экономит трафик домашнего интернета и даёт максимальную скорость.
LOG_CONFS
Включить или выключить вывод QR‑кодов конфигураций клиентов в лог контейнера.
Значения: true или false (по умолчанию false). Я поставил false, конфиги мы потом возьмем из сгенерированных файлов.
Описание сервиса
services:
vpn:
image: linuxserver/wireguard
container_name: vpn
vpn - имя сервиса внутри compose-файла.
image - готовый образ от LinuxServer.io с WireGuard + удобной обвязкой.
container_name - как контейнер будет называться в docker ps, логах и командах.
Сеть и права
network_mode: "host"
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
network_mode: "host" Контейнер использует сеть хоста, а не отдельную сеть docker(docker-bridge). Это позволяет WireGuard создавать интерфейс wg0 прямо на хосте и слушать порт51820/udp без дополнительных порт-мапов.
cap_add: NET_ADMIN Даёт контейнеру право, чтобы:
поднимать интерфейсы,
менять маршруты,
настраивать iptables. Все это нужно для корректной работы wireguard
cap_add: SYS_MODULE Разрешает загружать модуль ядра wireguard, если он ещё не подгружен в систему.
Тома
volumes:
- ./wireguard/config:/config
./wireguard/config:/config
В эту директорию на хосте будут сохраняться:
ключи сервера
конфиги клиентов
базовый wg0.conf
Это позволяет:
переживать перезапуски / обновления контейнера
удобно копировать .conf на устройства
Политика рестартов restart: unless-stopped Это гарантирует, что контейнер:
поднимется после перезагрузки сервера,
перезапустится после ошибок,
не будет стартовать только в одном случае - если его явно остановили (docker stop vpn).
💡 Совет: Не пугайся количества параметров — в 90% случаев достаточно поменять только SERVERURL и PEERS. Остальное работает "из коробки".
Включаем пересылку пакетов (IP forwarding)
Чтобы VPN-сервер мог маршрутизировать трафик между клиентами и локальной сетью, нужно включить пересылку пакетов:
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Это заставляет сервер работать как маршрутизатор:
принимает пакеты от VPN-клиента (10.8.0.x),
пересылает их в локальную сеть (192.168.31.x),
и обратно — отвечает клиенту через туннель.
Запуск контейнера
Теперь всё готово для запуска VPN-сервера:
docker compose -f docker-compose.vpn.yml up -d
После запуска ты получаешь:
Контейнер vpn проверка:
docker ps
Должен увидеть контейнер vpn в статусе Up.
Интерфейс wg0 на хосте Проверка:
ip a show wg0
Должен увидеть интерфейс с адресом 10.8.0.1/24 в состоянии UP.
Конфигурация сервера и клиентов На хосте появилась директория:
ls ./wireguard/config
Внутри лежат конфиги WireGuard.
Готовность добавлять клиентов Не нужно вручную генерировать ключи — всё делает скрипт внутри контейнера.
При настройке VPN есть важная особенность, с которой ты можешь столкнуться, если находишься в той же домашней сети, что и сервер.
1 В чём проблема
Параметр AllowedIPs в WireGuard на стороне клиента задаёт маршруты — то есть говорит операционной системе: "вот эти адреса отправляй через VPN-туннель".
Казалось бы, можно указать:
AllowedIPs = 10.8.0.0/24, 192.168.31.0/24
И всё должно работать: VPN-подсеть + вся домашняя сеть. Но вот загвоздка.
Когда ты подключаешься к VPN находясь в той же домашней сети (например, сидишь дома, подключён к своему Wi-Fi с адресом 192.168.31.x), операционная система видит, что адрес 192.168.31.90 (сервер) находится в той же локальной сети, к которой ты уже подключён напрямую.
И тут происходит конфликт приоритетов в таблице маршрутизации:
С одной стороны, WireGuard создаёт маршрут: "трафик к 192.168.31.0/24 отправляй через туннель wg0"
С другой стороны, уже существует локальный маршрут: "трафик к 192.168.31.0/24 отправляй через Wi-Fi интерфейс напрямую"
Локальный маршрут имеет больший приоритет (меньшую метрику), потому что система считает прямое подключение к локальной сети более предпочтительным, чем туннель.
В итоге трафик идёт напрямую, в обход VPN.
2 Как это проявляется
Подключаешься к VPN из домашней сети
DNS через VPN резолвит home-server.ru в LAN IP 192.168.31.90
Браузер отправляет запрос на 192.168.31.90
Запрос идёт напрямую, минуя туннель
Nginx видит твой реальный домашний IP (например, 192.168.31.150), а не VPN IP (10.8.0.x)
Получаешь 403 Forbidden, потому что Nginx разрешает только 10.8.0.0/24
3 Почему так происходит
В таблице маршрутизации ОС правила имеют приоритет по длине префикса (маске подсети):
Более конкретный маршрут (/32, /30) имеет больший приоритет
Менее конкретный маршрут (/24, /16) имеет меньший приоритет
Но когда маски одинаковые (/24 через Wi-Fi vs /24 через VPN), система смотрит на метрику маршрута — и локальное подключение обычно выигрывает.
4 Решение
Нужно добавить более специфичный маршрут — указать конкретный IP сервера с маской /32. В маршрутизации более конкретный маршрут всегда имеет приоритет над общим, независимо от метрики.
Поэтому вместо:
AllowedIPs = 10.8.0.0/24, 192.168.31.0/24
Используем:
AllowedIPs = 10.8.0.0/24, 192.168.31.90/32
Где 192.168.31.90 — это IP твоего сервера (на котором крутится Nginx иWireGuard).
Теперь:
Маршрут к 192.168.31.90/32 (через VPN) более конкретен, чем 192.168.31.0/24 (через Wi-Fi)
Трафик к конкретному IP сервера 192.168.31.90 гарантированно пойдёт через туннель
VPN-клиент всегда будет приходить с адреса 10.8.0.x
Nginx пропустит запрос
5 Когда эта проблема НЕ проявляется
Если ты подключаешься к VPN из другой сети (например, с мобильного интернета, из кафе, с работы), там подсеть другая (скажем 172.16.x.x), и конфликта нет — трафик нормально идёт через туннель даже с AllowedIPs = 10.8.0.0/24, 192.168.31.0/24.
Но лучше сразу использовать /32 — это универсально работает везде, независимо от того, откуда ты подключаешься.
📖 Из личного опыта: Я потратил часа 4 на понимание этой проблемы. Перепроверил все конфиги, отследил все хождения запросов, искал ошибку везде. В итоге нашёл информацию об этом нюансе в интернете — оказалось, всё дело в приоритетах маршрутизации. Теперь ты не потратишь эти 4 часа!
Чтобы добавить больше узлов/клиентов, необходимо увеличить PEERS значение в нашем docker-compose.vpn.yml или добавить больше элементов в список и пересоздать контейнер.
docker compose -f docker-compose.vpn.yml down
docker compose -f docker-compose.vpn.yml up -d
🎉 Отлично! VPN-сервер запущен и готов к работе. Но клиентам ещё нужно научиться обращаться к сервисам по доменам вместо IP. Для этого настроим DNS.
4 Настраиваем DNS-резолвер (dnsmasq)
Чтобы клиенты VPN могли обращаться к сервисам по доменам (home-server.ru, photos.home-server.ru и т.п.), добавим лёгкий DNS-сервер dnsmasq.
Установка
Устанавливаем dnsmasq
sudo apt install -y dnsmasq
Добавляем сервис в автозапуск при старте системы:
sudo systemctl enable dnsmasq
Создаем файл dnsmasq.conf в директории vpn:
cd ~/vpn
cat << EOF > dnsmasq.conf
# слушаем VPN и локально
listen-address=10.8.0.1
listen-address=127.0.0.1
# интерфейс VPN
interface=wg0
bind-interfaces
# внутренние домены → LAN IP reverse-proxy
address=/home-server.ru/192.168.31.90
address=/photos.home-server.ru/192.168.31.90
EOF
Создаем символическую ссылку в /etc/dnsmasq.d:
sudo ln -s $HOME/vpn/dnsmasq.conf /etc/dnsmasq.d/vpn.conf
Перезапустим dnsmasq
sudo systemctl restart dnsmasq
Как это работает
Все клиенты VPN будут использовать DNS 10.8.0.1.
При запросе home-server.ru - dnsmasq вернёт LAN IP сервера 192.168.31.90 (где установлен Nginx).
Nginx увидит клиента как 10.8.0.x и разрешит доступ (по allow 10.8.0.0/24).
Проверка работы
Проверяем, что dnsmasq запущен и слушает 10.8.0.1:53:
sudo ss -tulpn | grep ':53'
Проверяем, что домены резолвятся в нужный IP:
dig @10.8.0.1 home-server.ru
dig @10.8.0.1 photos.home-server.ru
В секции ANSWER должен быть адрес 192.168.31.90
Хорошо, DNS настроен! Осталось настроить Nginx — и защита будет полной. Это последний технический шаг перед подключением устройств.
5 Настраиваем Reverse-proxy
В этом разделе я буду показывать всё на примере nginx - одного из самых популярных HTTP‑серверов, который часто используется в качестве reverse‑proxy.
Подробнее с возможностями и конфигурацией nginx можно ознакомиться в официальной документации.
Мы не будем подробно рассматривать настройку поддержки TLS в nginx, поскольку это выходит за рамки текущей статьи. Тем не менее, настоятельно рекомендую добавить её. Для этого достаточно настроить Certbot, что несложно и хорошо документировано. То, как это настроить, хорошо поясняется на сайте проекта.
5.1 Вариант A - «Всё в Docker» (рекомендую)
Этот вариант подразумевает, что и Nginx, и сами сервисы живут в Docker и общаются друг с другом по внутренней сети Docker, без лишних пробросов портов и танцев с IP‑адресами.Nginx смотрит наружу (80/443), а внутри проксирует запросы в другие контейнеры по их именам внутри одной сети edge_net.
docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
- "443:443"
networks:
- edge_net
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
edge_net:
external: true
docker-compose.app.yml
version: '3.8'
services:
myapp:
image: myapp:latest
container_name: nginx
expose:
- "9000" # порт доступен только внутри сети edge_net
networks:
- edge_net
networks:
edge_net:
external: true
конфигурация nginx.conf
events {}
http {
upstream myapp {
server myapp:9000;
}
server {
listen 80;
server_name home-server.ru;
# доступ только из VPN
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp;
}
}
}
Плюсы подхода
- Всё изолировано внутри Docker: порты приложений не торчат на хост, наружу выходят только 80/443 с nginx.
- Упрощённый DNS: в proxy_pass и upstream используем имена сервисов ( myapp ), Docker сам резолвит их в IP.
Минусы подхода
- Требует «докеризовать» приложение.
- Отладка иногда чуть менее наглядна: нужно помнить про внутреннюю сеть Docker и её DNS, а не просто стучаться на localhost:port.
как добавить в текущую реализацию
Создаем docker сеть для nginx и сервисов:
docker network create edge_net
Создаем для удобства директорию nginx:
mkdir ~/nginx
cd ~/nginx
Создаем файл nginx.conf:
cat << EOF > nginx.conf
events {}
http {
upstream myapp {
server myapp:9000;
}
server {
listen 80;
server_name home-server.ru;
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp;
}
}
}
EOF
Создаём файл docker-compose.nginx.yml:
cat << EOF > docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
- "443:443"
networks:
- edge_net
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
edge_net:
external: true
EOF
Не забудьте добавить свой docker сервис в сеть edge_net
Запускаем nginx:
docker compose -f docker-compose.nginx.yml up -d
5.2 Вариант B - «Nginx в Docker → сервис на хосте»
Этот вариант нужен, когда приложение крутится на хосте, у него свой порт (например, 127.0.0.1:9000 ), и ты не хочешь/не можешь его перенести в Docker.
Здесь мы просто запускаем nginx в контейнере и даём ему доступ к сети хоста.
docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
network_mode: host # контейнер использует сеть хоста
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
nginx.conf
events {}
http {
upstream myapp_host {
server 127.0.0.1:9000; # существующий сервис на хосте
}
server {
listen 80;
server_name home-server.ru;
# доступ только из VPN
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp\\\_host;
}
}
}
Плюсы подхода
- Не нужно переносить существующий сервис в Docker - он остаётся как есть, ты добавляешь только тонкий Nginx‑слой поверх.
- Простая схема отладки: бекенд по‑прежнему доступен на 127.0.0.1:9000 , Nginx на 80/443 того же хоста.
- Хорошо подходит для «старых» или тяжёлых сервисов, где контейнеризация откладывается на потом.
Минусы подхода
- Если на хосте уже есть другой веб‑сервер на 80/443, придётся либо переносить его, либо разруливать конфликты портов.
- В отличие от варианта «всё в Docker», приложение всё ещё «торчит» на хосте (хотя только на 127.0.0.1 ), и часть сетевой логики остаётся вне Docker.
как добавить в текущую реализацию
Создаем для удобства директорию nginx:
mkdir ~/nginx
cd ~/nginx
Создаем файл nginx.conf:
cat << EOF > nginx.conf
events {}
http {
upstream myapp_host {
server 127.0.0.1:9000;
}
server {
listen 80;
server_name home-server.ru;
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://myapp\\\\_host;
}
}
}
EOF
Создаём файл docker-compose.nginx.yml:
cat << EOF > docker-compose.nginx.yml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx
network_mode: host
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
EOF
Запускаем nginx:
docker compose -f docker-compose.nginx.yml up -d
5.3 Вариант C - «Всё на хосте (без Docker)»
Этот вариант для максимально простой схемы. Все компоненты, приложения и nginx установлены прямо на хосте, без контейнеров.
Плюсы подхода
- Минимум частей: ничего не нужно устанавливать и обновлять в контейнерах, только пакеты ОС.
- Хорош для небольшого домашнего сервера или одной‑двух служб, когда Docker избыточен.
Минусы подхода
- Нет изоляции приложений: все процессы делят одну систему (библиотеки, окружение, зависимости).
- Развёртывание и обновление сложнее повторять: нет декларативного описания в compose‑файле, всё завязано на состояние хоста.
- При росте числа сервисов конфигурация на голом хосте начинает быстро обрастать «зоопарком» юнитов, пакетов и ручных настроек.
как добавить в текущую реализацию
Установите nginx и включите его в автозапуск:
sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
Отключаем дефолтный сайт Ubuntu, чтобы он не мешал нашему конфигу:
sudo rm /etc/nginx/sites-enabled/default
Создаем конфиг для нашего домена:
sudo tee /etc/nginx/sites-available/home-server.ru >/dev/null << 'EOF'
server {
listen 80;
server_name home-server.ru;
allow 10.8.0.0/24;
deny all;
location / {
proxy_pass http://127.0.0.1:9000;
}
}
EOF
Включаем сайт и проверяем конфигурацию:
sudo ln -s /etc/nginx/sites-available/home-server.ru /etc/nginx/sites-enabled/home-server.ru
sudo nginx -t
Перезапускаем nginx, чтобы применить изменения:
sudo systemctl restart nginx
Вся инфраструктура готова! Теперь самое приятное — подключить свои устройства к VPN и проверить, что всё работает.
6 Устанавливаем VPN-конфиг на устройства
На этом этапе у нас уже есть:
работающий сервер WireGuard в контейнере vpn;
сгенерированные конфиги клиентов в ./wireguard/config.
Осталось забрать нужный .conf на устройство и импортировать его в официальное приложение WireGuard.
6.1 Где найти конфиги клиентов
Конфиги были автоматически сгенерированы при первом запуске контейнера WireGuard.
Заходим в директорию с конфигами:
cd ~/vpn/wireguard/config/
ls
В консоли ты увидишь директории с префиксом peer_ — это конфиги для VPN-клиентов. В моём случае это peer_mackbook и peer_ipad.
Заходим в директорию нужного клиента:
cd peer_mackbook
ls
Здесь лежат два файла:
peer_mackbook.conf — конфигурационный файл для импорта
peer_mackbook.png — QR-код для быстрого импорта на мобильные устройства
Выведем в консоль содержимое конфига:
cat peer_mackbook.conf
Пример того, что увидишь:
[Interface]
Address = 10.8.0.2/32
PrivateKey = <приватный ключ клиента>
DNS = 10.8.0.1
[Peer]
PublicKey = <публичный ключ сервера>
PresharedKey = <общий ключ>
Endpoint = home-server.ru:51820
AllowedIPs = 10.8.0.0/24, 192.168.31.90/32
PersistentKeepalive = 25
Разбор параметров:
Секция [Interface] (настройки клиента):
Address = 10.8.0.2/32 — IP-адрес клиента в VPN-сети (каждый клиент получает свой уникальный адрес)
PrivateKey — приватный ключ клиента (генерируется автоматически, никому не показывай)
DNS = 10.8.0.1 — DNS-сервер для резолвинга внутренних доменов (наш dnsmasq) Секция [Peer] (настройки сервера):
PublicKey — публичный ключ сервера WireGuard
PresharedKey — дополнительный общий ключ для усиления безопасности (опционально)
Endpoint = home-server.ru:51820 — адрес и порт сервера для подключения
AllowedIPs = 10.8.0.0/24, 192.168.31.90/32 — какие сети маршрутизировать через VPN:
10.8.0.0/24 — VPN-подсеть (для связи между клиентами и сервером)
192.168.31.90/32 — IP сервера в локальной сети (почему /32 — см. раздел 3.3)
PersistentKeepalive = 25 — отправлять keepalive-пакеты каждые 25 секунд (держит соединение активным за NAT)
Перейди на официальный сайт WireGuard и скачай приложение для своей платформы
6.4 Импорт конфига на ПК (Windows/macOS/Linux)
Скопируй файл конфига с сервера на свой компьютер:
Вариант A — через SCP:
scp user@192.168.31.90:~/vpn/wireguard/config/peer_ipad/peer_ipad.conf ~/Downloads/
Вариант B — вручную:
Выведи содержимое:
cat ~/vpn/wireguard/config/peer_ipad/peer_ipad.conf
Скопируй весь текст
Создай файл peer_ipad.conf на своём компьютере
Вставь туда скопированный текст
Передай файл с компьютера на мобильное устройство:
Для iOS/macOS: используй AirDrop
Для Android: через USB, Bluetooth или облако (Google Drive, Dropbox)
Универсально: через мессенджер (Telegram "Избранное", отправь файл самому себе)
Импортируй конфиг в приложение WireGuard:
Открой приложение WireGuard на телефоне
Нажми "+" → "Create from file or archive"
Выбери файл peer_ipad.conf
Конфиг импортируется в приложение
Активируй подключение:
Включи переключатель напротив туннеля
Статус должен измениться на "Active"
Скопируй файл конфига с сервера на свой компьютер:
Вариант A — через SCP:
scp user@192.168.31.90:~/vpn/wireguard/config/peer_ipad/peer_ipad.conf ~/Downloads/
Вариант B — вручную:
Выведи содержимое:
cat ~/vpn/wireguard/config/peer_ipad/peer_ipad.conf
Скопируй весь текст
Создай файл peer_ipad.conf на своём компьютере
Вставь туда скопированный текст
Передай файл с компьютера на мобильное устройство:
Для iOS/macOS: используй AirDrop
Для Android: через USB, Bluetooth или облако (Google Drive, Dropbox)
Универсально: через мессенджер (Telegram "Избранное", отправь файл самому себе)
Импортируй конфиг в приложение WireGuard:
Открой приложение WireGuard на телефоне
Нажми "+" → "Create from file or archive"
Выбери файл peer_ipad.conf
Конфиг импортируется в приложение
Активируй подключение:
Включи переключатель напротив туннеля
Статус должен измениться на "Active"
После активации VPN проверь доступ к защищённому сервису.
Проверь доступ с включённым VPN:
Открой браузер и введи:
http://home-server.ru
Должен открыться твой сервис.
Если видишь 403 Forbidden — что-то не так с маршрутизацией или конфигом Nginx (см. главу 8).
Если страница не загружается — проверь DNS и маршруты (см. главу 8).
Проверь, что блокировка работает БЕЗ VPN: Отключи VPN в приложенииWireGuard и попробуй снова открыть http://home-server.ru. Теперь должна быть ошибка подключения или 403 Forbidden — это значит, что защита работает, и без VPN доступа нет.
🎉 Поздравляю! VPN настроен и работает. Переходим к финальной проверке всей системы.
7 Набор быстрых проверок (self-audit)
Перед тем как считать настройку законченной, пройдём по ключевым точкам и убедимся, что всё работает корректно.
7.1 Проверка VPN-сервера
Убедимся, что контейнер WireGuard запущен и интерфейс поднят.
Проверяем статус контейнера:
docker ps | grep vpn
Ожидаем увидеть контейнер vpn в статусе Up.
Проверяем интерфейс wg0 на хосте:
ip a show wg0
Должен быть виден интерфейс с адресом 10.8.0.1/24 в состоянии UP.
Смотрим подключённых клиентов:
docker exec vpn wg show
Если клиенты подключены, увидите их публичные ключи и последнее время handshake. Если клиенты ещё не подключались, список peers будет пустым — это нормально.
Проверим, что dnsmasq слушает на VPN-интерфейсе и корректно резолвит внутренние домены.
Проверяем, что dnsmasq запущен и слушает порт 53:
sudo ss -tulpn | grep ':53'
Должны увидеть процесс dnsmasq, слушающий на 10.8.0.1:53 и 127.0.0.1:53.
Тестируем резолвинг (с сервера):
dig @10.8.0.1 home-server.ru
dig @10.8.0.1 photos.home-server.ru
В секции ANSWER должен быть адрес 192.168.31.90 (LAN IP сервера). Если домены не резолвятся, проверьте записи в ~/vpn/dnsmasq.conf и перезапустите dnsmasq:
sudo systemctl restart dnsmasq
Убедимся, что Nginx запущен и правильно фильтрует доступ по IP.
Для Docker-варианта:
docker ps | grep nginx
Ожидаем увидеть контейнер с именем nginx в статусе Up.
Для установки на хосте:
sudo systemctl status nginx
Ожидаем увидеть active (running) в выводе команды.
Тестируем блокировку доступа БЕЗ VPN:
curl -I http://home-server.ru
Ожидаем 403 Forbidden — это значит, что Nginx корректно блокирует доступ к защищённым доменам.
Финальная проверка всей цепочки с клиентского устройства (компьютер, телефон, планшет).
Подключаемся к VPN:
Открываем приложение WireGuard на твоём устройстве
Активируем подключение к серверу
Должен появиться статус "Connected" или "Активно"
Проверяем доступ к защищённому домену:
Открываем браузер
Вводим в адресной строке: http://home-server.ru
Должна открыться целевая страница
Если всё работает — поздравляем, защита настроена!
Проверяем блокировку без VPN:
Отключаем VPN в приложении WireGuard
Обновляем страницу в браузере или пробуем зайти снова на http://home-server.ru
Должны получить ошибку подключения (браузер не может подключиться к сайту) или 403
Это подтверждает, что без VPN доступ действительно закрыт.
8 Что делать, если не работает
Если что-то пошло не так, не паникуй. Большинство проблем решаются за несколько минут, если знать, куда смотреть.
Добро пожаловать в раздел отладки! Если ты здесь, значит что-то пошло не так. Не переживай — 9 из 10 проблем решаются проверкой логов и перечитыванием конфигов. Разберём самые частые случаи.
8.1 VPN не подключается
Симптомы:
Приложение WireGuard показывает "Inactive" или "Handshake failed"
Подключение зависает на "Activating..."
Сразу после активации происходит отключение
Что проверить:
1 Порт 51820/UDP открыт на роутере?
Проверь настройки проброса портов на роутере (см. главу 2). Убедись, что:
Порт 51820 UDP (не TCP!) пробросил на IP сервера
IP сервера совпадает с тем, что указан в пробросе
2 Контейнер WireGuard запущен?На сервере проверь статус:
docker ps | grep vpn
Должен увидеть контейнер vpn в статусе Up. Если его нет:
cd ~/vpn
docker compose -f docker-compose.vpn.yml up -d
3 Интерфейс wg0 поднят?
Проверь на сервере:
ip a show wg0
Должен увидеть интерфейс с адресом 10.8.0.1/24 в состоянии UP.
Если интерфейса нет — перезапусти контейнер:
docker restart vpn
4 Firewall на сервере не блокирует порт?
Проверь, есть ли активный firewall:
sudo ufw status
Если активен — добавь правило для WireGuard:
sudo ufw allow 51820/udp
sudo ufw reload
5 Смотрим логи WireGuard
Логи контейнера покажут, в чём проблема:
docker logs vpn --tail 50
8.2 DNS не резолвит домены
Симптомы:
VPN подключается, но home-server.ru не открывается
Браузер говорит "DNS_PROBE_FINISHED_NXDOMAIN"
ping home-server.ru не находит хост
Что проверить:
1 DNS указан в клиентском конфиге?
Открой файл конфига на устройстве (в приложении WireGuard → Edit):
[Interface]
DNS = 10.8.0.1
Параметр DNS должен быть равен 10.8.0.1. Если его нет — добавь вручную и сохрани.
2 dnsmasq запущен на сервере?
Проверь статус:
sudo systemctl status dnsmasq
Должен быть active (running). Если нет:
sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq
3 dnsmasq слушает на 10.8.0.1?
Проверь:
sudo ss -tulpn | grep ':53'
Должен увидеть dnsmasq на адресах 10.8.0.1:53 и 127.0.0.1:53.
Если не слушает на 10.8.0.1 — проверь конфиг ~/vpn/dnsmasq.conf:
cat ~/vpn/dnsmasq.conf
Должны быть строки:
listen-address=10.8.0.1
listen-address=127.0.0.1
interface=wg0
Если конфиг неправильный — исправь и перезапусти:
sudo systemctl restart dnsmasq
4 Домены прописаны в dnsmasq?
Проверь:
grep 'address=' ~/vpn/dnsmasq.conf
Должен увидеть:
address=/home-server.ru/192.168.31.90
address=/photos.home-server.ru/192.168.31.90
Если нет — добавь вручную (см. главу 4).
5 Тестируем резолвинг с сервера
На сервере выполни:
dig @10.8.0.1 home-server.ru
В секции ANSWER должен быть IP 192.168.31.90. Если нет — проблема в конфиге dnsmasq.
6 Тестируем резолвинг с клиента
На клиенте (с активным VPN):
macOS/Linux:
nslookup home-server.ru
Windows (PowerShell):
nslookup home-server.ru
Должен вернуть 192.168.31.90. Если возвращает другой IP или ошибку — DNS клиента не использует VPN.
8.3 Nginx отдаёт ошибки
1 Forbidden
Причина: Nginx видит IP клиента, который не входит в разрешённую подсеть 10.8.0.0/24.
Что проверить:
Клиент действительно получает IP из VPN?
На клиенте с активным VPN:
ip addr show wg0 # macOS/Linux
Должен увидеть адрес типа 10.8.0.2/32.
Трафик идёт через туннель?
Проблема с маршрутизацией (см. раздел 3.3). Проверь AllowedIPs в клиентском конфиге:
AllowedIPs = 10.8.0.0/24, 192.168.31.90/32
IP сервера должен быть с маской /32.
Nginx правильно настроен?
Проверь конфиг Nginx:
# Для Docker-варианта
docker exec nginx cat /etc/nginx/nginx.conf
# Для варианта на хосте
sudo nginx -T | grep -A 10 "server_name home-server.ru"
Должен увидеть:
allow 10.8.0.0/24;
deny all;
Смотрим логи Nginx:
# Docker-вариант
docker logs nginx --tail 50
# Хост-вариант
sudo tail -f /var/log/nginx/error.log
Ищи строки с IP клиента и причиной отказа.
2 Bad Gateway
Причина: Nginx не может достучаться до бэкенд-сервиса.
Что проверить:
Сервис запущен?
Для Docker:
docker ps | grep <имя_сервиса>
Для процесса на хосте:
sudo systemctl status <имя_сервиса>
Порт бэкенда открыт?
Проверь, слушает ли сервис на нужном порту:
sudo ss -tulpn | grep <порт>
Nginx правильно настроен?
Проверь proxy_pass в конфиге:
proxy_pass http://127.0.0.1:9000; # или имя контейнера
Для Docker-сети должно быть имя контейнера (http://myapp:9000).
3 Gateway Timeout
Причина: Сервис отвечает слишком долго (более 60 секунд).
Решение: Увеличь таймаут вNginx:
proxy_read_timeout 300;
proxy_connect_timeout 300;
8.4 Чеклист диагностики
Если не знаешь, с чего начать — проходи по этому списку сверху вниз:
Проверка | Команда | Что должно быть |
|---|---|---|
Контейнер VPN запущен | docker ps | grep vpn | Up |
Интерфейс wg0 поднят | ip a show wg0 | 10.8.0.1/24, UP |
Порт 51820 открыт на роутере | Проверь настройки роутера | Проброс на IP сервера |
dnsmasq запущен | sudo systemctl status dnsmasq | active (running) |
dnsmasq слушает на VPN | sudo ss -tulpn | grep ':53' | 10.8.0.1:53 |
Домены прописаны | cat ~/vpn/dnsmasq.conf | address=/home-server.ru/... |
DNS резолвится | dig @10.8.0.1 home-server.ru | 192.168.31.90 в ANSWER |
Nginx запущен | docker ps | grep nginx или systemctl status nginx | Up или active |
Nginx разрешает VPN | nginx -T | grep allow | allow 10.8.0.0/24; |
Клиент получил IP | В приложении WireGuard | 10.8.0.x |
DNS клиента настроен | Конфиг клиента | DNS = 10.8.0.1 |
8.5 Нужна помощь?
Если ты прошёл весь чеклист, но проблема не решилась:
Перечитай раздел, в котором застрял — возможно, пропустил важную деталь
Собери информацию для диагностики:
Вывод docker ps
Вывод docker logs vpn --tail 100
Вывод sudo systemctl status dnsmasq
Скриншот настроек VPN-клиента
Напиши в комментариях с описанием проблемы и собранной информацией
Загляни в мой Telegram-канал — там я разберу твой кейс и по возможности помогу с проблемой.
Помни: 90% проблем решаются внимательным чтением логов и проверкой конфигов. Не спеши, всё получится!
9 Итоги
9.1 Что мы построили
🎉 Поздравляю! Ты прошёл путь от открытого сервера до защищённой инфраструктуры с VPN-доступом.
Вот что теперь у тебя есть:
Защищённый туннель WireGuard — современный VPN-сервер с автоматической генерацией конфигов клиентов
Внутренний DNS-резолвер dnsmasq — позволяет обращаться к сервисам по понятным доменам вместо IP
Reverse-proxy Nginx — единая точка входа, которая фильтрует трафик и разделяет доступ
Гибкая схема доступа — публичные сервисы остаются доступными всем, приватные защищены VPN
Всё это работает вместе как единая система: VPN создаёт частную сеть, DNS резолвит внутренние домены, а Nginx пропускает только авторизованных клиентов.
9.2 Преимущества решения
🔒 Безопасность:
Административные панели физически недоступны без VPN — никакие боты и сканеры их не достанут
Современное шифрование WireGuard (ChaCha20, Poly1305) защищает трафик от перехвата
Ключи генерируются автоматически, минимум ручной работы = меньше ошибок
✨ Простота:
Вся настройка делается за один вечер, даже если ты не сетевой инженер
Docker-контейнеры упрощают развёртывание и обновление
Конфиги клиентов генерируются автоматически — просто скопируй и импортируй
🔧 Гибкость:
Публичные сервисы (фотогалерея) остаются доступными всем
Приватные сервисы (Proxmox, мониторинг) защищены VPN
Легко добавлять новых клиентов и сервисы
9.3 Когда это решение подходит
✅ Используй эту схему, если:
У тебя есть статический IP или белый IP от провайдера
Нужен защищённый доступ к домашним сервисам (Proxmox, NAS, камеры и т.п.)
Хочешь разделить публичные и приватные сервисы
Количество клиентов — до 10-20 устройств (семья, друзья)
Готов потратить пару часов на настройку ради спокойствия
❌ НЕ подходит, если:
Нет статического IP и не хочешь настраивать DDNS (хотя это решаемо)
Нужна корпоративная VPN для большой компании (используй коммерческие решения)
Требуется двухфакторная аутентификация (WireGuard работает только по ключам)
9.4 Обратная связь
Поделись результатом:
Напиши в комментариях, получилось ли настроить защиту с первого раза
Поделись статьёй с теми, кто тоже держит домашний сервер — они скажут спасибо
Больше материалов и то, чем занимаюсь я, публикую в своём Telegram-канале. Подписывайся, если хочешь держать руку на пульсе!
Если эта статья была полезна, жду твоего фидбека и комментариев.
Возможно я дополню статью твоим кейсом и упоминанием или найду идеи на новые статьи. Буду рад любой форме обратной связи!
10 Финал
Если ты дочитал до конца, значит, тот самый «ненадёжно открытый сервер из вступления» у тебя превратился в аккуратно закрытый контур с VPN. Поблагодари себя за проделанную работу и спи спокойно — за сервисы теперь можно не переживать.
*хотя абсолютной безопасности не существует.