# Filtering by MAC address



## williamy (Jun 19, 2012)

I am using freebsd FreeBSD as a gateway, and I am trying to do filtering by MAC addresses.
*F*or example, I want to allow the traffic from machine A with MAC address xx xx xx xx. So I created a sample firewall rule like below.


```
#allow the traffic from that machine
allow all ip from any to any MAC xx:xx:xx:xx any
#allow the traffic back to that machine
allow all ip from any to any MAC any xx:xx:xx:xx
#block all others
deny all ip from any to any
```

But it doesn't work on my gateway. I am still reading the "PACKET FLOW" section of the ipfw's man page. and trying to find the reason.

Some friends already told me that some traffic is in layer3 only. So I can not match them with MAC addresses.  But I found that it works on PFSense.


----------



## phoenix (Jun 19, 2012)

There are a few things to watch out for when blocking at multiple layers in the TCP/IP protocol stack.  For example, every packet will go through the ruleset twice:  once at layer 2 (where the MAC addresses are checked), then again at layer 3 (where the IP addresses are checked).

You also need to set a sysctl to enable layer-2 filtering (you can add this to the rule script, or to /etc/sysctl.conf:
`# sysctl net.link.ether.ipfw=1`

The other thing to realise is that MAC addresses are written in reverse order:  *dest src*; whereas IP rules are written in forward order: *src dest*.

Finally, be very specific in your rules, especially when listing which interface and direction of packet travel.

Then you need to write your layer-2 rules:

```
# Interfaces
PRIVATE=em0
PUBLIC=xl0

# MAC addresses to block
# These only take effect if sysctl net.link.ether.ipfw=1
BAD_MACS_F=" { MAC any 00:1E:68:C7:B7:AF or MAC any 00:11:24:3E:FA:86 }"
BAD_MACS_T=" { MAC 00:1E:68:C7:B7:AF any or MAC 00:11:24:3E:FA:86 any }"

# Rules to block Internet access by MAC address
# First, you need to allow ARP traffic
$IPFW add 4 allow ip from any to any layer2 mac-type arp

# Block ethernet traffic [b]from[/b] specific MAC addresses (note: MACs are listed in "dest src" order)
$IPFW add 5 deny ip from any to any $BAD_MACS_F in recv $PRIVATE

# Block ethernet traffic [b]to[/b] specific MAC addresses (note: MACs are listed in "dest src" order)
$IPFW add 6 deny ip from any to any $BAD_MACS_T out xmit $PRIVATE

# Finally allow all other ethernet traffic
$IPFW add 7 allow ip from any to any MAC any any
```


----------



## williamy (Jun 19, 2012)

Thanks for your reply.

But you are talking about how to block a machine by its MAC address, It is a *blacklist*. And what I want to have is a *whitelist*. I want to allow this MAC address only and block all others.

Thanks all the same.


----------



## phoenix (Jun 19, 2012)

So you reverse rules 5, 6, and 7, making 5/6 allow rules, and 7 a deny rule.


----------



## williamy (Jun 19, 2012)

Thanks for advice. But I have tried this for more than two weeks already. Does the rule work on your FreeBSD? Did you try it? If it works on your environment, that means our environments have some differences. If so, can you please help in telling me how to set up a FreeBSD like yours. 

Thanks in advance.


----------



## Anonymous (Jun 19, 2012)

I may be wrong, however, I think that just anoher sysctl needs to be set to allow packet passing through ipfw more than once, please try:

`# sysctl net.inet.ip.fw.one_pass=0`

Best regards

Rolf


----------



## williamy (Jun 21, 2012)

Still not resolved. But thanks all the same,
I google a lot and found most people are doing *BlackList*. but I want to have a *WhiteList*.


----------



## SirDice (Jun 21, 2012)

williamy said:
			
		

> I google a lot and found most people are doing *BlackList*. but I want to have a *WhiteList*.


They are exactly the same. The only difference is how you handle the list. If you block everything on your list but allow everything else it's a blacklist. If you allow everything on the list and block everything else it's a whitelist.


----------



## williamy (Jun 21, 2012)

I want to block everything except the MAC address in the list. I think I should call it WhiteList. Can someone help please? That will be very helpful. Now I am reading the handbook section by section. Hoping someone can help me to speed up my schedule.


----------



## phoenix (Jun 21, 2012)

You should be able to do something like the following:

```
# Allow the ARP traffic from everyone
$IPFW add 4 allow ip from any to any layer2 mac-type arp

# Allow traffic [b]from[/b] specific MAC addresses
$IPFW add 5 allow ip from any to any $BAD_MACS_F in recv $PRIVATE

# Allow traffic [b]to[/b] specific MAC addresses
$IPFW add 6 allow ip from any to any $BAD_MACS_T out xmit $PRIVATE

# Allow all IP-level traffic
$IPFW add 7 allow ip from any to any via $PRIVATE

# Deny all MAC-level traffic
$IPFW add 8 deny ip from any to any MAC any any via $PRIVATE
```

Every packet goes through the packet filter twice.  If it's blocked at either level (MAC or IP), then it's blocked.


----------



## sezgin (Mar 12, 2017)

Hi;
Sorry I writing this subject because it was the most relevant topic

I am using freebsd 11.0 and I am trying to do bandwidth with pipe for MAC Address 
but I cant because if I use pipe sample -> *rule number 315* I cant connect internet 

if I use sample rule
ipfw -q add 315 allow ip from 192.168.1.13 to any { MAC any d8:bb:2c:b9:b6:34 } in recv em1 keep-state
ipfw -q add 316 allow ip from any to 192.168.1.13 { MAC d8:bb:2c:b9:b6:34 any } out xmit em1 keep-state

I can connect internet and nothing any problem 
*my sysctl.conf*
sysctl net.inet.ip.fw.one_pass=1
net.inet.ip.forwarding=1
net.link.ether.ipfw=1
net.inet.ip.fw.enable=1


*my firewall.sh config *

ipfw -q -f flush
ipfw pipe 1 config bw 5000Kbit mask src-ip 0xffffffff
ipfw pipe 1001 config bw 512Kbit mask src-ip 0xffffffff
ipfw pipe 2 config bw 30000Kbit
ipfw pipe 1002 config bw 50000Kbit

# First, you need to allow ARP traffic
ipfw -q add 304 allow ip from any to any layer2 mac-type arp

# my pc
ipfw -q add 315 pipe 2 ip from 192.168.1.13 to any { MAC any d8:bb:2c:b9:b6:34 } in recv em1 keep-state
ipfw -q add 316 pipe 1002 ip from any to 192.168.1.13 { MAC d8:bb:2c:b9:b6:34 any } out xmit em1 keep-state

ipfw -q add 350 allow ip from any to any { MAC any any } via em1

# Allow all IP-level traffic
#ipfw -q add 367 allow ip from any to any via em1

# Deny all MAC-level traffic
ipfw -q add 65533 deny ip from any to any MAC any any via em1
ipfw -q add 65534 deny all from any to any

Where is the my problem ? 

please help me I'm going to freak out :S


----------

