zapret in lxc container as gateway for home devices
In an attempt to raise zapret for all home devices, I decided to change the firmware on the router. But my Mikrotik completely refused to write the Openwrt firmware to ROM. Therefore, I needed a solution with the stock RouterOS firmware. Good thing it supports GRE tunnels (primitive, convenient).
I have a home “under-bed” server running Debian and working as a “smart” home, NAS, spinning Telegram bots. You can set up zapret on it and select the server as a gateway for all home devices.
Why does it make sense to run zapret in a container instead of on the server?
Isolated environment. For example, a container with complex nft rules is isolated from the server's nft tables (fail2ban). Separate update management, etc.
We do not route regular server traffic through the GRE tunnel (GRE is the WAN for the container). Server traffic still goes directly through the router.
You can raise several containers with different zapret settings. Select tactics in a separate container. You can make gateway containers with different settings for different home devices.
If these are not arguments, then you can install zapret on the host (read – server, hypervisor). In this case, it is good if the host has not one physical interface, but at least two (look at nano pi). One interface will work in LAN, the second will be WAN, but both interfaces will be connected to the LAN ports of the router. For single-port devices and single-board computers, the second physical interface can be an inexpensive USB network adapter. If there is only one physical interface, then you can create a virtual WAN in the form of a GRE tunnel with the router (similar to how it is described below in the case of a container).
Below is an instruction on how to set up an lxc container with zapret on a host with a single physical network interface.
1) Router: MikroTik settings
IP address of the router 192.168.1.1
assigned to the bridge bridge1
– default setting.
Let's create a GRE interface using commands via the console:
/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
– this is the IP of the lxc container, which we will configure later.
2) Host: network settings
Debian 12 “Bookworm” host with address 192.168.1.78
and the only network interface enp3s0
. Let's put this network interface into the bridge bridge0
. To the bridge bridge0
lxc container with zapret will be connected.
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) Host: lxc
We will install a container management system
apt install lxc lxc-templates
You can immediately disable the default bridge created by lxc-net – lxcbr0
. Created bridge0
previously.
nano /etc/default/lxc-net
USE_LXC_BRIDGE="false"
systemctl restart lxc-net
Let's create an lxc container with debian and additional packages (by default, the system doesn't even have ping). In addition to debian, you can choose any other template for the container, but debian suits me completely.
lxc-create -t debian -n ntc -- -r bookworm --packages=nftables,dnsutils,iputils-ping,git,curl,links
ntc
– this is an arbitrary name that will be part of the path to the container's rootfs – /var/lib/lxc/ntc/rootfs/
. Packages nftables, git, curl will be needed for zapret. With the help of links it is convenient to check the availability of sites directly from the command line.
After creation, the container is stopped. Let's immediately define the network settings of the container itself – we will bind the container to the bridge bridge0
host, and enable autostart of the container with the launch of the host.
nano /var/lib/lxc/ntc/config
lxc.net.0.link = bridge0
lxc.start.auto = 1
We configure the IP of the container and the GRE interface of the container with the router.
The gre3 tunnel will be established between the IP routers 192.168.1.1
and IP container 192.168.1.79
there will be corresponding IP addresses at the ends of the tunnel 192.168.3.1
(router) and 192.168.3.2
(container).
The gre3 interface in the container will be the WAN interface (the gateway is specified for it) and NAT will be enabled for it after startup (post-up command).
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
Specify DNS server addresses.
nano /var/lib/lxc/ntc/rootfs/etc/resolv.conf
nameserver 8.8.8.8
nameserver 1.1.1.1
Now you can run the container with the command lxc-start ntc
connect to container lxc-attach ntc
check active interfaces, ping sites.
It would be a good idea to check whether exchange between network interfaces is enabled (output 1 – enabled) in the container:
cat /proc/sys/net/ipv4/ip_forward
By default, the option is enabled. If necessary, edit in the container settings:
/etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward=1
4) Installing zapret in the container
Launching the container lxc-start ntc
we connect to his environment lxc-attach ntc
. We give commands from this block in the container environment. Do not forget, by default in the container only root, act carefully.
git clone --depth 1 https://github.com/bol-van/zapret.git ~/zapret
When installing zapret, you will need to answer a number of questions. It is important to note that the WAN interface in the container is gre3
!
~/zapret/install_easy.sh
After installation, it is worth indicating those strategies for bypassing blocking that were selected manually or by the utility zapret/blockcheck.sh
. For example, like this:
nano /opt/zapret/config
NFQWS_OPT_DESYNC="--dpi-desync=fake,split2 --dpi-desync-ttl=5"
5) Home devices
You can specify a new gateway in the router's DHCP server settings 192.168.1.79
. Or specify this gateway manually on home devices.
P.S.
For the purpose of testing bypass tactics, it makes sense to create a separate container (for example, ntc-test
) in which GRE tunnels are not raised, but the router is specified as the default gateway.
Select blocking techniques with zapret/blockcheck.sh
in the ntc container it will not work simultaneously with its regular operation as a gateway.