OpenWRT Multicast Filtering
Here are a few config files for an OpenWRT AP running on a Ubiquiti Nano Station Loco M2. Most Nano Stations have patch antennas which are somewhat directional. This is probably better than using an omni in your camp if you don't want people accessing your WiFi from too far away.
If you mount your directional antenna on the end of your camp closest to the man pointing back at the camp so it radiates outward toward the edge of the city, and also point it down slightly at the ground. Then this makes a somewhat oblong coverage area in your camp, with very little radiation towards the man and the rest of the city. What little escapes backwards radiates slightly upwards to the sky. I rode around some and checked it and the signal levels were comparable to some far away camps that I happened to see in the network list.
The instructions for reflashing your device are available elsewhere and are outside the scope of this writeup. However, please note that in the later versions of AirOS they changed the flash layout, and as of this posting OpenWRT has not updated their images yet. So you must first downgrade AirOS to something like 5.5.10
Before you reflash to OpenWRT. (Is there a better way now using urescue?)
Multiple Networks and NATing
If you would like to separate the privilege of your camp mates vs the passers by, you'll probably want to use different network interfaces and different subnets to do that. I suppose if you want to make do with just one network then the simplest thing to do would be to take the example config at the end of this write up and turn one of the networks off in the WiFi config. Otherwise read on.
As of this writing, the burning man network provides a NATed subnet for each camp that wants to connect. However, both networks can't easily use just one subnet so we'll have to make another one, and NAT it going out the upstream interface. In this case we chose the public net to use this new subnet, which makes it double NAted. Not ideal but it usually works. Since IPtables is part OpenWRTs basic install, you can just add one rule to get your new subnet to be NATed on the upstream interface:
IPTABLES=/usr/sbin/iptables
$IPTABLES -t nat -A POSTROUTING -o br-lan -s 192.168.2.0/24 -j MASQUERADE
You would want to change the hard coded upstream interface and the subnet above to the one you wanted to NAT. Though the example config will probably work for most folks with light editing.
Setting up multiple networks on one AP
Continuing on this theme, you need to configure your AP to give you two networks. They will by necessity have to be on the same channel, though one can be open, and the other can be a password protected network for just your camp mates. One thing I read, is that Microsoft clients can get confused if they see more than one network with the same BSSID (Mac address). So lets make them different:
/etc/config/wireles:
config wifi-device 'radio0'
option type 'mac80211'
option hwmode '11g'
option path 'pci0000:00/0000:00:00.0'
option htmode 'HT20'
option channel '1'
option txpower '9'
option country 'US'
config wifi-iface
option device 'radio0'
option mode 'ap'
option encryption 'none'
option ssid 'Cool Camp (6:30 & C) Public'
option network 'captive'
config wifi-iface
option device 'radio0'
option mode 'ap'
option ssid 'CoolCampPriv'
option encryption 'psk2'
option key 'OurSecret'
option macaddr 'AA:BB:CC:DD:EE:F1'
option network 'lan'
Note that the key must be at least eight characters long or the wifi is permanently disabled.
Blocking Multicast and other Garbage Traffic
At the Oregon Country Fair I played with filtering out all multicasts and most broadcast packets. We checked some wireshark captures and the packet count went down by half, of course most of the data volume is in the remaining good packets. Though this is very useful because then their are half as many opportunities for collisions. Mainly I did this on the end user AP's not the trunking links. Anyway it worked great.
For the Linux based firmware, such as DD-WRT, OpenWRT, and AirOS, which is actually a fork of OpenWRT, you can use EBtables to filter layer 2 traffic. EBtables is very similar to IPtables except it works in layer 2 instead of layer 3. Though there are a few plugins that provide some layer 3 matching for convenience.
Now AirOS also uses EBtables, and you can find lines in /tmp/system.cfg for configuring it. You should be able to add your own rules, say from the script below, to that file.
Here is a bash script that initializes EBtables with some multicast and broadcast filtering. Feel free to adapt it to your needs:
/etc/init.d/layer2/firewall:
#!/bin/sh /etc/rc.common
START=90
USE_PROCD=1
QUIET=""
INT="wlan0+"
ORG_SUBNET1="10.0.0.0/8"
ORG_SUBNET2="192.168.0.0/16"
BROADCAST1="10.3.255.255"
BROADCAST2="10.2.255.255"
IFCONFIG=/sbin/ifconfig
BRCTL=/usr/sbin/brctl
EBTABLES=/usr/sbin/ebtables
IPTABLES=/usr/sbin/iptables
INSMOD=/usr/sbin/insmod
RMMOD=/usr/sbin/rmmod
# Required openWRT packages: ebtables kmod-ebtables kmod-ebtables-ipv4 kmod-ebtables-watchers?
load_modules() {
# Required kernel modules
# Choose relocatable ebtables-modules and
# dont turn off possible error messages!
$INSMOD ebtables
$INSMOD ebtable_broute
$INSMOD ebtable_filter
$INSMOD ebtable_nat
$INSMOD ebt_802_3
$INSMOD ebt_among
$INSMOD ebt_limit
$INSMOD ebt_mark_m
$INSMOD ebt_pkttype
$INSMOD ebt_stp
$INSMOD ebt_vlan
$INSMOD ebt_mark
$INSMOD ebt_redirect
# Ebtables IPv4 Moduels
$INSMOD ebt_arp
$INSMOD ebt_ip
$INSMOD ebt_arpreply
$INSMOD ebt_dnat
$INSMOD ebt_snat
}
unload_modules() {
# Ebtables IPv4 Moduels
$RMMOD ebt_arp
$RMMOD ebt_ip
$RMMOD ebt_arpreply
$RMMOD ebt_dnat
$RMMOD ebt_snat
# Base Ebtables modules
$RMMOD ebt_802_3
$RMMOD ebt_among
$RMMOD ebt_limit
$RMMOD ebt_mark_m
$RMMOD ebt_pkttype
$RMMOD ebt_stp
$RMMOD ebt_vlan
$RMMOD ebt_mark
$RMMOD ebt_redirect
$RMMOD ebtable_nat
$RMMOD ebtable_filter
$RMMOD ebtable_broute
$RMMOD ebtables
}
# ===================================================
# ORDER IS CRITICAL IN FILTER SETUP, DONT MUCK IT UP!
# ===================================================
restart() {
echo "restarting..."
stop_service
start_service
}
start_service() {
echo "starting service..."
load_modules
# sleep 5
# Set up Policies
$EBTABLES -t filter -P FORWARD DROP
# Drop ARP gratuitous packets?
$EBTABLES -t filter -A FORWARD -i $INT -p arp --arp-gratuitous -j DROP
# Accept all arps just on our organization subnet(s)
$EBTABLES -t filter -A FORWARD -i $INT -p arp --arp-ip-dst $ORG_SUBNET1 -j ACCEPT
$EBTABLES -t filter -A FORWARD -i $INT -p arp --arp-ip-dst $ORG_SUBNET2 -j ACCEPT
# Drop the rest
$EBTABLES -t filter -A FORWARD -i $INT -p arp -j DROP
# We may need more than just replys here. Should go to OUTPUT? All arps?
$EBTABLES -t filter -A FORWARD -o $INT -p arp --arp-opcode Reply -j ACCEPT
$EBTABLES -t filter -A FORWARD -o $INT -p arp --arp-opcode ARP_NAK -j ACCEPT
# Drop the rest?
# $EBTABLES -t filter -A FORWARD -o $INT -p arp -j DROP
# Drop all subnet broadcasts
$EBTABLES -t filter -A FORWARD -o $INT -p ipv4 --ip-destination $BROADCAST1 -j DROP
$EBTABLES -t filter -A FORWARD -o $INT -p ipv4 --ip-destination $BROADCAST2 -j DROP
# Accept all DHCP discovers and requests in interfaces
# TEST $EBTABLES -t filter -A FORWARD -i $INT -d broadcast? -p IPv4 --ip-prot udp -ip-sport 68 --ip-dport 67 -j ACCEPT
# Accept all DHCP Offers and ACKs from the servers.
# TEST $EBTABLES -t filter -A FORWARD -o $INT -d broadcast -p IPv4 --ip-prot udp --ip-dport 67 --ip-dport 68 -j ACCEPT
# Quick and dirty accept of all DHCP packets
$EBTABLES -t filter -A FORWARD -p IPv4 --ip-prot udp --ip-dport 67:68 -j ACCEPT
# Just drop all multicasts period
$EBTABLES -t filter -A FORWARD --pkttype-type multicast -j DROP
$EBTABLES -t filter -A INPUT --pkttype-type multicast -j DROP
$EBTABLES -t filter -A OUTPUT --pkttype-type multicast -j DROP
# Drop the rest of the broadcasts
$EBTABLES -t filter -A FORWARD -d broadcast -j DROP
# Accept all IPv4 and 802_1Q
$EBTABLES -t filter -A FORWARD -p IPv4 -j ACCEPT
$EBTABLES -t filter -A FORWARD -p 802_1Q -j ACCEPT
# Everything else is DROPPED as per the policy
}
stop_service() {
echo "Clearing all layer 2 filter rules..."
# Clear filter table
$EBTABLES -t filter -F
$EBTABLES -t filter -X
$EBTABLES -t filter -P INPUT ACCEPT
$EBTABLES -t filter -P FORWARD ACCEPT
$EBTABLES -t filter -P OUTPUT ACCEPT
# Clear nat table
$EBTABLES -t nat -F
$EBTABLES -t nat -X
$EBTABLES -t nat -P PREROUTING ACCEPT
$EBTABLES -t nat -P OUTPUT ACCEPT
$EBTABLES -t nat -P POSTROUTING ACCEPT
# Clear broute table
$EBTABLES -t broute -F
$EBTABLES -t broute -X
$EBTABLES -t broute -P BROUTING ACCEPT
unload_modules
}
reload_service() {
echo "reload service..."
}
boot() {
# Be silent on boot, firewall might be started by hotplug already,
# so don't complain in syslog.
QUIET=-q
echo "Booting service..."
}
# (sleep 300; stop_service ) &
Typically you would start the script something like this:
/etc/rc.local:
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
/etc/init.d/layer2firewall start
exit 0
A Complete Example Configuration
Here is a complete config with all the fixens. You will need to load these additional OpenWRT modules for it to work:
ebtables, kmod-ebtables, kmod-ebtables-ipv4, nodogsplash, sqm-scripts, luci-app-sqm, kmod-ifb
I think tc is a dependency of sqm-scripts, if not you will need that one too.
OpenWRT_sample_config.tgz
--
ClifCox - 28 Jun 2017