Snippets:Simple router (Linux)
#!/bin/sh
# License: CC0
set -eu
iptables-nft-restore <<\EOF
*filter
:FORWARD DROP
-A FORWARD -i eth0 ! -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -j DROP
-A FORWARD ! -i eth0 -o eth0 -m state ! --state UNTRACKED -j ACCEPT
COMMIT
*nat
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
EOF
ip6tables-nft-restore <<\EOF
*filter
:FORWARD DROP
-A FORWARD -i eth0 ! -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -j DROP
-A FORWARD ! -i eth0 -o eth0 -m state ! --state UNTRACKED -j ACCEPT
COMMIT
*nat
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
EOF
sysctl -w net.ipv6.conf.all.forwarding=1 net.ipv4.ip_forward=1
- Replace "eth0" (in all instances where it exists in the above script) with the name of the outbound interface that you have Internet access on.
- In order for this script to actually be useful, your system must have at least one subordinate network relative to the network interface where you have Internet access on. This script will still run correctly even if there is no subordinate network, but it won't be very useful except in cases where the subordinate network interfaces are subject to hot plugging.
- The filter is configured such that the subordinate networks are allowed to access the Internet-facing interface, but the subordinate networks cannot communicate with each other, nor can the Internet-facing interface access any of the subordinate networks. Access to servers on the local system with the firewall is not restricted.
- This script uses Network Address Translation (NAT) to allow the subordinate networks to connect to the greater Internet without static routes or dynamic routing protocols. If you have static routes, routing protocols, or other circumstances where you are able to access the subordinate networks directly, then you can remove the NAT by omitting the "-j MASQUERADE" line.
- If you are using Docker in the same network namespace as the firewall rules[1], then you should set
--iptables=false
on theExecStart=
command oriptables: false
in/etc/docker/daemon.json
. The-p
option indocker run
for publishing ports will cease to work, but you can still use Socketbox or other similar tools. See Miscellaneous tidbits. - This script should be executed on system startup (e.g. in
/etc/rc.local
).
How it all started
- Main article: Subordinate network
- ↑ Refers to the network namespace in which the
dockerd
command is run, and can be modified by prependingnsenter --net=[path to network namespace]
(alsoip netns exec [name of network namespace]
) to the command specification or by addingNetworkNamespacePath=
orJoinsNamespaceOf=
to the systemd unit file. Not to be confused with--net=host
.