At my workplace, we have a Public Wifi network, as well as our Private Wifi network. The Private side has access to see other computers, the printers, servers, and access to the Internet. On the Public side, the users need to authenticate with a captive portal with a username/password combo from our server (for our staff's personal devices only).

The key has been leaked long before I came to this job, and I have most things cleaned up. I have scripts (written by other team members, not myself!) that go through the DHCP leases on Debian Wheezy, and spit out the manufacturer, the DNS name, IP Address, and the MAC address of all the devices the DHCP server interacts with. With these scripts, I can create a blacklist of MAC addresses and iptables blocks them for me. I update /etc/blacklist.txt, and when iptables starts, it executes iptables -A INPUT $if -m mac --mac-source $i -j DROP (with $i being read from the file).

This will prevent their device from connecting to our network resources, and to the Internet. Unfortunately, it does not take effect until after the device has gotten an IP address from isc-dhcp-server. So, my issue is, how can I prevent them from even getting an IP address assigned to them? Yes, I know they could just assign themselves a static IP address and bypass the DHCP server, but I still want iptables to block them, based on their (hopefully non-changing) MAC address. Yes, I know I could increase the range on my DHCP server, but I want management to realize the struggle with managing the privately-owned devices taking up our work resources by connecting and bypassing our captive portal.

One solution (well, partial) that someone thought up was to create a blackhole class in my /etc/dhcp/dhcpd.conf file, and fill it with the MAC addresses of the devices I don't want connecting. This would work, but requires updating the MAC addresses in multiple places, which I don't want. I want to be able to update the MACs in one file, and then possibly run a script that will add the changes to my DHCP file, and my iptables rules.

  • 1
    This is a chicken/egg problem. You don't know about them until they tell you they exist. I don't see a way out of this problem in your current setup. You should probably reverse the policy (block everything and only whitelist the MAC addresses you know should be connecting to your network).
    – anon
    Commented Sep 29, 2014 at 18:13
  • If you filter the MAC addresses, then they should normally not be able to get (again) an IP address. Are you running that iptables command on the DHCP server itself?
    – Ale
    Commented Sep 29, 2014 at 18:24
  • @Ale The DHCP server might be using a socket at a lower layer of the networking stack. If it is using a socket on a layer beneath IP, then iptables won't block any packets from reaching the DHCP server.
    – kasperd
    Commented Sep 29, 2014 at 18:33
  • @kasperd Hm yes, that's a good point... indeed in this case a lower-level filtering like the etables proposed by MikeyB has to be used.
    – Ale
    Commented Sep 29, 2014 at 18:35
  • If a key leaks, you rotate it. Blacklisting MAC addresses is a never-ending game of whack-a-mole. Anybody determined enough to use a leaked key might also spoof a MAC address. They might even spoof a white-listed MAC address. Even if a host don't get to communicate with neither DHCP server nor gateway, it may still find a way to communicate through any of the other hosts on the network segment.
    – kasperd
    Commented Sep 29, 2014 at 18:38

4 Answers 4


Use ebtables instead of iptables to block MAC addresses at layer 2:

ebtables -A INPUT -s 00:11:22:33:44:55 -j DROP
  • Can you please give a syntax example of dropping the packets based on a Mac address? Otherwise this answer doesn't help me much, other than researching more, and possibly asking more questions on the subject. Commented Sep 29, 2014 at 18:45

Although I think using ebtables may be the answer, it's another layer that I did not want to add to my configuration. One of the other techs helped me make a script to parse through the blacklist of IP Addresses, and add them to a new pool, which gives out no IP address whatsover. It takes the regular blacklist (one MAC address per line) that I also spit into iptables, and just creates the new pool.

In my /etc/dhcp/dhcpd.conf file, I create a new class near the top:

class "blacklist" {
    match hardware;

In my pools with the "private side of the LAN", I add this:

deny members of "blacklist";

... and at the very end, I added:

include "/etc/dhcp/blacklist.conf";

Then, I create a Python script as per below:


my $if;
my @macs;
my $line = 0;

if ($ARGV[0]) {
    $if = "-i $ARGV[0]";

while (<stdin>) {

    next if /^$/;
    next if /^\s*#/;


    if (/^([a-f0-9]{2}((:|-)[a-f0-9]{2}){5})$/) {
        push(@macs, $_);
    else {
        die("syntax error on line $line\n");

open(OUT, ">/etc/dhcp/blacklist.conf");
foreach my $i (@macs) {
    $i =~ tr/-/:/;
    print OUT "subclass \"blacklist\" 1:$i;\n";

I save this, then I add the Execute bit with chmod +x /usr/local/sbin/dhcpd-macblock.py, and set a cron job that feeds the blacklist into the script every hour:

cat /etc/blacklist.txt | dhcpd-macblock.py

Every hour, it goes through, creating a new file with all the MAC addresses blocked that I don't want, and they don't even get a DHCP reservation, and my spots are slowly freeing up.


If you have access to that setting, and if the hardware permits it, a simpler sollution could be to configure your access point(s) to reject the MAC addresses you want to filter, instead of filtering them "later" with iptables. This would also solve the problem of people assigning a static IP to their device, as they could simply not associate with the network if they are filtered at AP-level. Of course, this can't solve the problem of "non-static" MAC addresses...

  • This also doesn't prevent them from plugging in with an ethernet cord. Yes, it could work for the wireless devices, but that also requires updating multiple APs with a blacklist, manually. I would prefer not. Commented Sep 29, 2014 at 18:49
  • @CanadianLuke indeed they can still use cables... I was assuming that the public network was only on WiFi, as Ethernet was not mentioned in the question. If the APs are professional devices, there should be a way to push a blacklist to them (or have them download it somewhere) so you wont have to manually update each. But of course, this wont solve the cable problem... except if you can do the same on the Ethernet switch (supposing it's a managed one).
    – Ale
    Commented Sep 29, 2014 at 19:00

As far as I know it is not possible to do except to use something like etables as was suggested, with the additional bookkeeping.

I've seen this problem before and the solution I found in use was pretty much the same as what you're already using. If you make the script run every few minutes then the time the unauthorized device can be on the network is minimal, that could be an acceptable trade-off.

You should also look into linking wireless authentication with an LDAP server, assuming you already use something like that it should be easy. Otherwise incorporate LDAP or some other centralised authentication system as soon as possible (local user accounts are a bad idea in most cases). Then either create generic guest account or a guest account on a case by case basis. That way even though users may have the wireless key they still can not get on the wireless until they authenticate. Normally that would be done via a webpage the wireless router will redirect traffic to. Only after authentication a route will be created to allow traffic.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .