zapret в lxc-контейнере как шлюз для домашних устройств

в 17:10, , рубрики: Debian, dpi, GRE, lxc

В попытках поднять zapret для всех домашних устройств решил поменять прошивку на роутере. Но мой Mikrotik напрочь отказался записывать прошивку Openwrt в ПЗУ. Поэтому мне понадобилось решение со стоковой прошивкой RouterOS. Хорошо, она поддерживает GRE‑туннели (примитивно, удобно).

У меня есть домашний «подкроватный» сервер работает на Debian и трудится в качестве «умного» дома, NAS'а, крутит Telegram‑ботов. Можно поднять zapret на нём и выбрать сервер шлюзом для всех домашних устройств.

Почему имеет смысл запускать zapret не на сервере, а в контейнере?

  1. Изолированное окружение. Например, контейнер со сложными nft правилами изолирован от nft таблиц сервера (fail2ban). Раздельное управление обновлениями и пр.

  2. Не гоняем обычный трафик сервера через GRE-туннель (GRE является WAN'ом для контейнера). Трафик сервера по-прежнему ходит напрямую через роутер.

  3. Можно поднять несколько контейнеров с разными настройками 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 не получится одновременно с его штатной работой в качестве шлюза.

Автор: yohabi

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js