I have Ubuntu 10 as router with WAN(eth0) and LAN(eth1). How can I restric eth1 to accept only packets from certain MAC addresses and drop the rest? I am also about to setup DHCP to certain MAC addresses, however, anyone can manually set IP address. I have like 4-6 my own devices which can use the network.

link|improve this question

FWIW, anyone can manually set MAC addresses, too. – Insyte Mar 8 '11 at 4:31
But they can hardly guess the ones I'm using :) – Pablo Mar 8 '11 at 4:33
1  
All they have to do is sniff... – Insyte Mar 8 '11 at 4:34
sniff wifi? it's not so hostile environment :) Wired network is not accessible. I'm connected through Wifi bridge and need to restrict uninvited guests from wifi. – Pablo Mar 8 '11 at 4:37
Yes, sniff wifi. It's easier than sniffing wired in that it doesn't require physical access. The client MAC is sent in the clear even on WPA networks. (You are using WPA2, yes? WEP is... silly.) – Insyte Mar 8 '11 at 4:46
feedback

migrated from serverfault.com Mar 8 '11 at 12:14

This question came from our site for system administrators and desktop support professionals.

5 Answers

up vote 2 down vote accepted

As I mentioned in the comments, I don't think this buys you any real security, or even any more security than blocking based on IP, but something like this should do it:

/sbin/iptables -A INPUT -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:XX -j ACCEPT

Assuming, of course, that your default policy is DROP.

link|improve this answer
I'm sorry, the default policy is ACCEPT. Any way? – Pablo Mar 8 '11 at 7:15
Then change it to DROP... then use this command. – Bart De Vos Mar 8 '11 at 8:50
well, how to negate the way that if NOT specified mac, then DROP? – Pablo Mar 8 '11 at 10:10
feedback

( I am user63709; somehow my Google OpenID login and MyOpenID login got split, when it's actually the same in Stack Overflow)

arptables has its own policy. Do not confuse it with iptables's policy.

Since you want to "restric [sic] eth1 to accept only packets from certain MAC addresses and drop the rest", you will want a default DROP policy.

(BTW, I made a slight mistake in the arptables rules above. They should be:)

arptables -P IN DROP
arptables -A IN -i eth1 --source-hw <allowed_mac_address> -j ACCEPT
arptables -A IN -i eth1 --source-hw <allowed_mac_address> -j ACCEPT
... and so on ...

(Note again, that IN is a built-in chain specifically found only in arptables. Read arptables' man page for more information).

link|improve this answer
For some reason it worked during the testing, but didn't work when I put it on startup... no internet connection at all. – Pablo Mar 13 '11 at 12:30
@Michael that's strange... where did you put the arptables commands? the only reason I can think of: the -P IN DROP works, but the -A IN -i eth1 rules failed because the arptables commands got called before eth1 is fully up. try placing the commands in /etc/rc.local. don't forget to put in the full path to arptables (/sbin/arptables IIRC) – pepoluan Mar 13 '11 at 13:46
I put it the same place (above) iptables init, in /etc/NetworkManager/dispatcher.d/01ifupdown. Again, it works when I just run the script from shell. I tried also rc.local. Anyway, I've used iptables for that as mentioned here. Will upvote your answer as well, as it was useful to know! Thx – Pablo Mar 13 '11 at 13:56
@Michael hmmmm... really strange... another thing I can think of is the difference of the shell used by the startup scripts (sh instead of bash). you're not using bash-specific syntax, are you? – pepoluan Mar 14 '11 at 4:50
feedback

Here is a start for you:

iptables -P FORWARD DROP
iptables -I FORWARD -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:XX -j ACCEPT
iptables -I FORWARD -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:BB -j ACCEPT
iptables -P INPUT DROP
iptables -I INPUT -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:XX -j ACCEPT
iptables -I INPUT -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:BB -j ACCEPT

All mac addresses other than XX:XX:XX:XX:XX:XX and XX:XX:XX:XX:XX:BB will not be able to access your router or the internet.

link|improve this answer
does it really have to be also in FORWARD table? In which cases it might work? – Pablo Mar 8 '11 at 4:52
feedback

You might be interested in arptables.

It's kind of iptables, but specifically for layer 2. Although it can also 'peek' into some L3 information.

arptables -P IN DROP
arptables -A IN --source-hw <allowed_mac_address> -j ACCEPT
arptables -A IN --source-hw <allowed_mac_address> -j ACCEPT
... and so on ...

Whenever there's a new MAC Address you want to allow, just do arptables -A IN --source-hw <address> -j ACCEPT. The DROP policy ensures other addresses will be, uh, dropped.

link|improve this answer
how to negate mac address if default policy is ACCEPT? – Pablo Mar 8 '11 at 10:09
feedback

Michael, you can not specify more than one mac source per rule so you will need a set of rules like the following (if you are going to use iptables)

#Rules for allowing your mac addresses
/sbin/iptables -A FORWARD -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:11 -j ACCEPT
/sbin/iptables -A FORWARD -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:22 -j ACCEPT
/sbin/iptables -A FORWARD -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:33 -j ACCEPT
#One final rule to drop all packets which do not match one of the rules above (are not from one of your allowed macs)
/sbin/iptables -A FORWARD -i eth1 -j DROP

Note that these are in the FORWARD chain and not the INPUT chain. By having these rules in the FORWARD chain your linux router will not let any mac except your allowed ones to send or receive any traffic through the router. They will still be able to communicate with machines on the same subnet as their own (because that doesn't require them to pass through the router).

You can also control who can connect to your router by duplicating the above rules for the input chain.

#Rules for allowing your mac addresses
/sbin/iptables -A INPUT -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:11 -j ACCEPT
/sbin/iptables -A INPUT -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:22 -j ACCEPT
/sbin/iptables -A INPUT -i eth1 -m mac --mac-source XX:XX:XX:XX:XX:33 -j ACCEPT
#One final rule to drop all packets which do not match one of the rules above (are not from one of your allowed macs)
/sbin/iptables -A INPUT -i eth1 -j DROP

Reading your comment on one of the other shorter answers about which cases FORWARD and INPUT work with, here is a short explanation.

FORWARD only applies to packets going through your router to other subnets or to the outside world (through the WAN) interface. INPUT applies to packets which are destined to terminate on the router itself (eg. SSH connections to the router/linux box itself).

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.