В попытках поднять zapret для всех домашних устройств решил поменять прошивку на роутере. Но мой Mikrotik напрочь отказался записывать прошивку Openwrt в ПЗУ. Поэтому мне понадобилось решение со стоковой прошивкой RouterOS. Хорошо, она поддерживает GRE‑туннели (примитивно, удобно).
У меня есть домашний «подкроватный» сервер работает на Debian и трудится в качестве «умного» дома, NAS'а, крутит Telegram‑ботов. Можно поднять zapret на нём и выбрать сервер шлюзом для всех домашних устройств.
Почему имеет смысл запускать zapret не на сервере, а в контейнере?
Изолированное окружение. Например, контейнер со сложными nft правилами изолирован от nft таблиц сервера (fail2ban). Раздельное управление обновлениями и пр.
Не гоняем обычный трафик сервера через GRE-туннель (GRE является WAN'ом для контейнера). Трафик сервера по-прежнему ходит напрямую через роутер.
Можно поднять несколько контейнеров с разными настройками zapret'а. Подбирать тактики в отдельном контейнере. Можно сделать контейнеры-шлюзы с отличающимися настройками для разных домашних устройств.
Если это не доводы, то можно установить zapret на хост (читай - сервер, гипервизор). В таком случае, хорошо, если у хоста не один физический интерфейс, а минимум два (посмотрите в сторону nano pi). Один интерфейс будет работать в LAN, второй - будет WAN, но подключены оба интерфейса будут к LAN-портам роутера. У однопортовых устройств и одноплатников вторым физическим интерфейсом может быть недорогой сетевой USB-адаптер. Если физический интерфейс один, то можно создать виртуальный WAN в виде GRE-туннеля с роутером (подобно тому, как описано ниже в случае с контейнером).
Ниже инструкция, как поднять lxc-контейнер с zapret'ом на хосте с единственным физическим сетевым интерфейсом.
1) Роутер: настройки MikroTik
IP адрес роутера 192.168.1.1
, присвоен мосту bridge1
- настройка по умолчанию.
Создадим GRE-интерфейс командами через консоль:
/interface gre add !keepalive local-address=192.168.1.1 name=gre3 remote-address=192.168.1.79
/ip address add address=192.168.3.1/24 interface=gre3 network=192.168.3.0
/interface list member add interface=gre3 list=LAN
192.168.1.79
- это IP lxc-контейнера, который настроим позже.
2) Хост: сетевые настройки
Хост Debian 12 "Bookworm" с адресом 192.168.1.78
и единственным сетевым интерфейсом enp3s0
. Заведем этот сетевой интерфейс в мост bridge0
. К мосту bridge0
будет подключаться lxc-контейнер с zapret'ом.
nano /etc/network/interfaces
auto bridge0
iface bridge0 inet static
bridge_ports enp3s0
address 192.168.1.78/24
broadcast 192.168.1.255
gateway 192.168.1.1
bridge_fd 0
bridge_maxwait 0
bridge_stp off
3) Хост: lxc
Установим систему управления контейнерам
apt install lxc lxc-templates
Можно сразу отключить дефолтный мост создаваемый lxc-net - lxcbr0
. Создали bridge0
ранее.
nano /etc/default/lxc-net
USE_LXC_BRIDGE="false"
systemctl restart lxc-net
Создадим lxc-контейнер с debian и дополнительными пакетами (по умолчанию в системе нет даже ping). Помимо debian можно выбрать любой другой шаблон для контейнера, но debian меня полностью устраивает.
lxc-create -t debian -n ntc -- -r bookworm --packages=nftables,dnsutils,iputils-ping,git,curl,links
ntc
- это произвольное название, которое будет частью пути к rootfs контейнера - /var/lib/lxc/ntc/rootfs/
. Пакеты nftables, git, curl понадобятся для zapret'а. С помощью links удобно проверить доступность сайтов прямо из командной строки.
После создания контейнер остановлен. Сразу определим сетевые настройки самого контейнера - привяжем контейнер к мосту bridge0
хоста, и включим автозапуск контейнера с запуском хоста.
nano /var/lib/lxc/ntc/config
lxc.net.0.link = bridge0
lxc.start.auto = 1
Конфигурируем IP контейнера и GRE-интерфейс контейнера с роутером.
Туннель gre3 будет установлен между IP-роутера 192.168.1.1
и IP-контейнера 192.168.1.79
, на концах туннеля будут соответствующие IP-адреса 192.168.3.1
(роутер) и 192.168.3.2
(контейнер).
Интерфейс gre3 в контейнере будет WAN интерфейсом (для него указан gateway) и для него будет включаться NAT после старта (команда post-up).
nano /var/lib/lxc/ntc/rootfs/etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.1.79/24
broadcast 192.168.1.255
auto gre3
iface gre3 inet static
address 192.168.3.2/24
gateway 192.168.3.1
pre-up iptunnel add gre3 mode gre local 192.168.1.79 remote 192.168.1.1 ttl 255
post-up nft add table NAT; nft add chain NAT POSTROUTING {type nat hook postrouting priority srcnat \; policy accept \;}; nft add rule NAT POSTROUTING oifname "gre3" masquerade
post-down iptunnel del gre3
Указать адреса DNS серверов.
nano /var/lib/lxc/ntc/rootfs/etc/resolv.conf
nameserver 8.8.8.8
nameserver 1.1.1.1
Теперь можно запустить контейнер командой lxc-start ntc
, подключиться к контейнеру lxc-attach ntc
, проверить активные интерфейсы, попинговать сайты.
Не лишним будет проверить, включен ли обмен между сетевыми интерфейсами (выход 1 - включен) в контейнере:
cat /proc/sys/net/ipv4/ip_forward
По умолчанию, опция включена. При необходимости править в настройках контейнера:
/etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward=1
4) Установка zapret в контейнер
Запускаем контейнер lxc-start ntc
, подключаемся к его окружению lxc-attach ntc
. Команды из этого блока даём в окружении контейнера. Не забываем, по умолчанию в контейнера только root, действуем осторожно.
git clone --depth 1 https://github.com/bol-van/zapret.git ~/zapret
При установке zapret потребуется ответить на ряд вопросов. Важно указать, что WAN интерфейсом в контейнере является gre3
!
~/zapret/install_easy.sh
После установки стоит указать те стратегии обхода блокировок, которые удалось подобрать вручную или утилитой zapret/blockcheck.sh
. Например, так:
nano /opt/zapret/config
NFQWS_OPT_DESYNC="--dpi-desync=fake,split2 --dpi-desync-ttl=5"
5) Домашние устройства
В настройках DHCP-сервера роутера можно указать новый шлюз 192.168.1.79
. Либо указывать этот шлюз вручную на домашних устройствах.
P.S.
Для целей проверки тактик обхода имеет смысл создать отдельный контейнер (например, ntc-test
) в котором не поднимать туннели GRE, а шлюзом по умолчанию указать роутер.
Подбирать методики блокировок с zapret/blockcheck.sh
в контейнере ntc не получится одновременно с его штатной работой в качестве шлюза.
RTFM13
Я пошел немного другим путём. Добавил еще одну L2 сеть в роутер, которая на уровне L3 обрабатывается в контейнере, а для проброса в контейнер использую 802.1q, как наименее ресурсоемкий и наиболее доступный. Настройки для OpenWRT, но микротик это тоже должен уметь из коробки.