I decided to restrict Internet access from my LAN to known IP/MAC pairs only. Primary to block Internet access from my PS3, virtual machines and computers that do not need it. Simplest way to achieve this on Linux: filter packet coming from LAN interface in FORWARD chain.
On OpenWRT custom firewall rules can be defined in /etc/firewall.user. Before creating rules we need some method to create and (easily) maintain IP/MAC pairs. I decided t use /etc/ethers and /etc/hosts that already contains MACs, hostnames nad IPs (used by dnsmasq).
On my router I have /etc/ethers in format:
00:11:11:11:11:12 stargate 00:22:22:22:22:23 techie 00:33:33:33:33:34 tortoise ...
And /etc/hosts:
127.0.0.1 localhost OpenWrt ... 10.0.0.2 stargate 10.0.0.5 techie 10.0.0.14 tortoise ...
The only problem I found is parsing all those information in a simple way (eg. in a one line of sh/awk/perl/whatever script). Perl is not available in default installation of OpenWRT. SH cannot easily handle text files. Finally awk with grep seems to be really simple and efficient:
cmd = "cat /etc/hosts | grep " $2 ; cmd | getline ; print $1 " -j ACCEPT" }' /etc/ethers ; \
echo "iptables -A forwarding_rule -i br0 -j DROP")
This command (script?) parses /etc/ethers and /etc/hosts and creates firewall rules on standard output:
iptables -A forwarding_rule -i br0 -m mac --mac-source 00:11:11:11:11:12 -s 10.0.0.2 -j ACCEPT iptables -A forwarding_rule -i br0 -m mac --mac-source 00:22:22:22:22:23 -s 10.0.0.5 -j ACCEPT iptables -A forwarding_rule -i br0 -m mac --mac-source 00:33:33:33:33:34 -s 10.0.0.14 -j ACCEPT iptables -A forwarding_rule -i br0 -j DROP
Now it is easy to attach it to OpenWRT firewall in /etc/firewall.user. Just after flush rules insert:
(awk '{ printf "iptables -A forwarding_rule -i br0 -m mac --mac-source " $1 " -s " ; \
cmd = "cat /etc/hosts | grep " $2 ; cmd | getline ; print $1 " -j ACCEPT" }' /etc/ethers ; \
echo "iptables -A forwarding_rule -i br0 -j DROP") | sh
Note “| sh” at the end of command. This is needed to execute created rules.
Finally reload firewall rules:
/etc/init.d/S35firewall start
Try to access any Internet hosts from allowed and blocked (any not allowed) clients. Than check if it works:
iptables -vxL forwarding_rule



