IPFW Restrict access to local network

Hello. I have the following problem. I have a machine running FreeBSD 11.0-RELEASE-p9. It has the following network interfaces configuration:
Code:
re0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
   options=82099<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
   ether 10:fe:ed:02:b9:18
   nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
   media: Ethernet autoselect (1000baseT <full-duplex>)
   status: active
re1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
   options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
   ether bc:5f:f4:68:23:19
   inet 176.77.48.52 netmask 0xffff8000 broadcast 176.77.127.255
   nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
   media: Ethernet autoselect (100baseTX <full-duplex>)
   status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
   options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
   inet6 ::1 prefixlen 128
   inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
   inet 127.0.0.1 netmask 0xff000000
   nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
   groups: lo
wlan0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
   ether 30:b5:c2:6b:4a:8e
   nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
   media: IEEE 802.11 Wireless Ethernet autoselect mode 11ng <hostap>
   status: running
   ssid skynetV25 channel 5 (2432 MHz 11g ht/20) bssid 30:b5:c2:6b:4a:8e
   regdomain 32924 country CN indoor ecm authmode WPA2/802.11i
   privacy MIXED deftxkey 2 AES-CCM 2:128-bit AES-CCM 3:128-bit
   txpower 20 scanvalid 60 protmode CTS ampdulimit 64k ampdudensity 8
   shortgi wme burst dtimperiod 1 -dfs
   groups: wlan
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
   ether 02:27:ad:54:af:00
   inet 192.168.20.1 netmask 0xffffff00 broadcast 192.168.20.255
   nd6 options=9<PERFORMNUD,IFDISABLED>
   groups: bridge
   id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
   maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
   root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
   member: re0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
           ifmaxaddr 0 port 1 priority 128 path cost 55
   member: wlan0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
           ifmaxaddr 0 port 4 priority 128 path cost 33333

Here re1 is connected to the outside world, re0 goes to local network (via external switch), wlan0 is an access point for wireless devices in my home. re0 and wlan0 are bridged via bridge0, so both wired and wireless devices form my local network. Also this machine runs DHCP server and dynamic DNS. Here is /etc/rc.conf:

Code:
hostname="resurrected.home"
dumpdev="AUTO"
zfs_enable="YES"
sshd_enable="YES"
powerd_enable="YES"
rpcbind_enable="YES"
mountd_enable="YES"
nfs_server_enable="YES"
nfs_reserved_port_only="YES"
gateway_enable="YES"
firewall_enable="YES"
firewall_script="/etc/firewall.sh"
ifconfig_re0="up"
ifconfig_re1="DHCP"
wlans_ath0="wlan0"
create_args_wlan0="wlanmode hostap"
ifconfig_wlan0="mode 11g channel 5:ht/20 up"
hostapd_program="/usr/local/sbin/hostapd"
hostapd_enable="YES"
cloned_interfaces="bridge0"
ifconfig_bridge0="inet 192.168.20.1 netmask 255.255.255.0 addm wlan0 addm re0 up"
nginx_enable="YES"
php_fpm_enable="YES"
distccd_enable="NO"
distccd_flags="-j 4 --listen 192.168.20.1 -a 192.168.20.0/24 --stats --user distcc --daemon -P /var/run/distccd.pid"
polipo_enable="YES"
named_enable="YES"
dhcpd_enable="YES"
dhcpd_ifaces="bridge0"
# Need access to internet
tor_enable="YES"
ntpd_enable="YES"

As you can see, this machine also runs tor and NFS server. There are devices in my home network which cannot be trusted completely (such as my tablet running Windows 10 ;)). I want to restrict traffic to local network for them, so they can only access DHCP and DNS servers. Traffic for trusted machines can be unrestricted. What is important, all "bad" devices are wireless, so as I understand the wireless star topology, all traffic between network's participants goes through access point. So I wrote this ipfw script (it's running on the same resurrected.home):

Code:
#!/bin/sh

IPFW="/sbin/ipfw -q"
IFACE="re1"
SKIP="skipto 20000"

# Ports list:
SSH="22"
TELNET="23"
SMTP="25"
WHOIS="43"
WWW="80"
HTTPS="443"
POP3="110"
SSMTP="465"
POP3S="995"
GIT="9418"
FTPC="21"
FTPD="20"
IRC="6660-7000"
NTP="123"
TORRENT="20250-20255"
DHT="20250"

OPENPORTS="$WWW,$HTTPS"
OPENPORTS="$OPENPORTS,$SSH,$WHOIS,$GIT"

BADMACS="1c:b7:2c:4e:24:df c0:21:0d:21:44:97"
SUBNET="192.168.20.0/24"

LOCALIFACES="re0 wlan0 bridge0"

$IPFW -f flush
$IPFW -f nat flush

# Start NAT
$IPFW nat 1 config if $IFACE log same_ports reset

# Deny fragmented packets
$IPFW add deny ip from any to any frag in

# Allow ARP
$IPFW add allow ip from any to any layer2 mac-type arp

# Allow loopback
$IPFW add allow ip from any to any via lo0

# Early NAT for stateful rules
$IPFW add nat 1 ip from any to any in via $IFACE

# Restrict untrusted cell phone/tablet traffic
for mac in $BADMACS; do
   $IPFW add allow tcp from any to me dst-port 53,80 mac any $mac in setup keep-state
   $IPFW add allow udp from any to me dst-port 53 mac any $mac in keep-state
   $IPFW add allow udp from any 68 to me dst-port 67 mac any $mac in keep-state
   $IPFW add allow icmp from any to me mac any $mac in
   $IPFW add deny ip from any to me mac any $mac in
done

# Enable LAN traffic
for lan_iface in $LOCALIFACES; do
   $IPFW add allow ip from any to any via $lan_iface
done

# Torrents on this machine
$IPFW add allow tcp from me $TORRENT to any out via $IFACE
$IPFW add allow tcp from any to me $TORRENT in via $IFACE
$IPFW add allow udp from me $DHT to any out via $IFACE
$IPFW add allow udp from any to me $DHT in via $IFACE

# Allow DNS for this machine
$IPFW add allow tcp from me to any 53 out via $IFACE setup keep-state
$IPFW add allow udp from me to any 53 out via $IFACE keep-state

# DHCP for this machine
$IPFW add allow udp from any 68 to any dst-port 67 out via $IFACE keep-state

$IPFW add $SKIP tcp from { me or $SUBNET } to any $OPENPORTS out \
    via $IFACE setup keep-state

# NTP
$IPFW add $SKIP udp from { me or $SUBNET } to any $NTP out via $IFACE keep-state

# Steam
$IPFW add $SKIP udp from { me or $SUBNET } to any dst-port 27015-27022 out via $IFACE keep-state

# ICMP out and limited in
$IPFW add $SKIP icmp from any to any out via $IFACE keep-state
$IPFW add $SKIP icmp from any to any in icmptypes 3,8,11 via $IFACE

# Reset established tcp connections which do not match dynamic rules
#$IPFW add reset tcp from any to { me or $SUBNET } tcpflags ack,!fin in via $IFACE

$IPFW add deny all from any to any
$IPFW add 20000 nat 1 ip from any to any out via $IFACE
$IPFW add allow ip from any to any

I also put net.inet.ip.fw.one_pass=0 and net.link.ether.ipfw=1 to /etc/sysctl.conf

I decided to filter "bad" devices by MAC addresses. This is the problematic part:
Code:
for mac in $BADMACS; do
   $IPFW add allow tcp from any to me dst-port 53,80 mac any $mac in setup keep-state
   $IPFW add allow udp from any to me dst-port 53 mac any $mac in keep-state
   $IPFW add allow udp from any 68 to me dst-port 67 mac any $mac in keep-state
   $IPFW add allow icmp from any to me mac any $mac in
   $IPFW add deny ip from any to me mac any $mac in
done
It does its job, i.e. allows traffic only for DNS, DHCP and local web server (all running on access point, resurrected.home) for "bad" devices, blocking everything else. But if I change these lines to something like this:
Code:
for mac in $BADMACS; do
   $IPFW add allow tcp from any to me dst-port 53,80 mac any $mac in setup keep-state
   $IPFW add allow udp from any to me dst-port 53 mac any $mac in keep-state
   $IPFW add allow udp from any 68 to me dst-port 67 mac any $mac in keep-state
   $IPFW add allow icmp from any to { me or $SUBNET } mac any $mac in
   $IPFW add deny ip from any to { me or $SUBNET } mac any $mac in
done
All traffic to $SUBNET (which is my local network) still passes unfiltered, only traffic which is designated to access point itself is blocked. I cannot understand why this happens. Please help me to block traffic from "bad devices" to the entire home network, no just to the access point.

P.S. Also, I used this thread Thread 32841 which describes MAC filtering and was very helpful
 
This doesn't answer your question, but have you considered simply assigning wlan0 to a different network (not bridged) and filtering that?
 
Back
Top