# Enforcing DHCP usage on a network

## ToeiRei

I'm back here with my 'bad girls' again and I need to make sure they stick to DHCP usage. My basic idea would be something like 

```
iptables -N mac_ok

iptables -A FORWARD -i eth0 -j mac_ok

iptables -I mac_ok -m mac --mac-source 00:00:00:00:00:01 -j RETURN

iptables -A mac-ok -j REJECT --reject-with icmp-net-prohibited

```

regarding the dhcp.lease file I could grant access to the addresses listed. theoretically.

A cron script parsing the lease file would be too much hassle and lag as it would run every now and then and I am sure it wouldn't be an exact way as I would have to reset the firewalling to the rules above and hammer in the lease.

Is there any way to hook that into the dhcpd as this one is the only instance that knows for sure who's there...?

----------

## thegeezer

howdy,

you could consider chillispot and put guests in their own vlan

or something like 

```

tail -f  /var/log/dhcp/current | grep ACK | awk '{ print $9; }'

```

would give you a list of recently activated macs, but you might want to consider usign the MAC+IP in iptables in case someone gets a dhcp address then amends it

----------

## wthrowe

You might be able to do something with dhcpd events.  See dhcpd.conf(5) for a little information, but they don't seem to be too well documented so you'd probably have to experiment.  I've never used them myself, but I believe they allow you to run scripts whenever leases are given out or released.

----------

## Jaglover

Not sure what your setup is but you may do better by turning NAT off for good and leaving proxy the only way to get out.

----------

## darkphader

 *ToeiRei wrote:*   

> I'm back here with my 'bad girls' again and I need to make sure they stick to DHCP usage.

 

Agreed that that is how it should be but in your case to what end? What exactly, outside of someone stepping on another's IP address, are you trying to prevent?

The only 100% solution might be a static arp table (to control access, not exactly DHCP usage), but with lots of turnover that can be a management headache. Typical blocking at the firewall will generally train everyone to do the right thing. The main thing is probably to block DNS access from all but your network's local DNS cache (if you don't do this at the firewall, one could get their IP addess via DHCP, yet still override the DNS servers). You can also block SMTP access to the WAN from all but your mail server; block NTP from all but your local NTP server, etc.

----------

## ToeiRei

The dhcpd events is one thing I will definitively use.

We have a dhcp setup to allow the users to just 'plug & play' and save us some duplicated IP trouble.

Background history so far: We have a rather open network, running a NAT rule and some local services like DNS, NTP, ... as it was requested by management. This is the perfect environment for filesharing people and we had a couple of users firing up their bittorrent and the network was pretty much flooded. As a consequence I was asked to block several IPs (iptables -j DROP) - the result was nice for a couple of hours as we could access the network again until some IPs were changed (which was NOT done by the DHCP). The management thinks that they need to have a documentation of name/ip/mac to get around legal issues (I'm not a lawyer but I know this is useless).

They want it, they pay for, they get it (and as soon as some new HW arrives, squid.)

----------

## ToeiRei

Just in case you'd need to know, I solved it using the dhcp events. Pretty weird, but that's how it works:

```

on commit {

        set ClientIP = binary-to-ascii(10, 8, ".", leased-address);

        set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));

        execute("/etc/dhcp/add-client.sh", "commit", ClientIP, ClientMac);

        }

on release {

        set clientIP = binary-to-ascii(10, 8, ".", leased-address);

        set clientMAC = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));

        execute("/etc/dhcp/kill-client.sh", "release", clientIP, clientMAC);

        }

on expiry {

        set clientIP = binary-to-ascii(10, 8, ".", leased-address);

        if(exists agent.remote-id) {

                set clientMAC = binary-to-ascii(16, 8, ":", substring(option agent.remote-id, 2, 6));

                        execute("/etc/dhcp/kill-client.sh", "expiry", clientIP, clientMAC);

                } else {

                        execute("/etc/dhcp/kill-ip.sh", "expiry", clientIP);

                }

        }

}

```

our scripts so far in theory:

add-client.sh adds an IP/MAC pair to the firewall (if IP comes from MAC, then you may forward)

kill-client.sh removes an IP/MAC pair from the ruleset

kill-ip.sh just removes anything related to that IP from the firewall

I am not sure if IP addresses 'sign off' from a dhcp server so all of my scripts are like the following one to monitor (leased in that case as it is the commit script):

```

#!/bin/bash

# $3 = MAC

# $2 = IP

timestamp=`date +%Y%m%d-%H:%M:%S`

echo $timestamp: ${3} leased ip ${2} >> /tmp/test.txt

```

Later I'd go with something like the following code for extending the 'access list' assuming I can :

```

#!/bin/bash

# $3 = MAC

# $2 = IP

RULEOCCURE=`iptables -L -n|grep -c $1`

if [ $RULEOCCURE -eq 0 ]; then

       /sbin/iptables -A FORWARD -s ${2} -i eth1 -m mac --mac ${3} -j ACCEPT

fi

```

another attempt would be adding rules that actually expire:

iptables -I FORWARD ... --seconds 600 -j DROP - which should be possible... but I'd be glad to have a more precise way than to just shoot into the dark

----------

## depontius

 *ToeiRei wrote:*   

> Just in case you'd need to know, I solved it using the dhcp events. Pretty weird, but that's how it works:
> 
> ...
> 
> I am not sure if IP addresses 'sign off' from a dhcp server so all of my scripts are like the following one to monitor (leased in that case as it is the commit script):
> ...

 

This takes a little knowledge of dhcp, and you've started by doing some stuff that I never even knew about...  But there are a few more things about dhcp that work in your favor.  First, dhcp has a "release" operation, so clients can tell you when they're no longer using an address.  Unfortunately the operant term was "can" instead of "must" - the "release" is optional.  Next the good news... In your dhcp server you can set a lease time.  The default lease is something like 12 hours or so, but it's easy to change, and in fact I've had it set down to about 1/2 hour before.  You could tweak your lease time as desired, then match the "--seconds nnn" value in the firewall script to that, and they would work together.

----------

## ToeiRei

I am aware of that releasing addresses is optional, but that's why I test things - especially which hooks are triggered...

----------

## darkphader

 *depontius wrote:*   

> First, dhcp has a "release" operation, so clients can tell you when they're no longer using an address.  Unfortunately the operant term was "can" instead of "must" - the "release" is optional.

 

Some DHCP options for Windows clients:

```
option space windoze;

option windoze.nbt      code 1 = unsigned integer 32;

option windoze.release  code 2 = unsigned integer 32;

option windoze.metric   code 3 = unsigned integer 32;

if substring (option vendor-class-identifier, 0, 8) = "MSFT 5.0" {

        # 2 = disable NetBIOS over TCP

        option windoze.nbt 2;

        # 1 = send DHCPRELEASE on shutdown

        option windoze.release 1;

        # default route cost metric

        option windoze.metric 1;

        vendor-option-space windoze;
```

Not sure if the one will guarantee you see a release, but in general you should.

----------

## depontius

Don't forget about the lease time.  Even if clients don't have to release, they must respect the lease interval.  You can use the anticipated lease expiration time in conjunction with tweaking your firewall.  You'd want a restartable timer, so that a lease renew restarts the timer, but that's no great shakes.

----------

## ToeiRei

Status so far: I have the scripts running since some hours now and some hosts already were shut down, restarted and so on. All I did see was the commit event and expire lines. Nothing like 'release'. So far the DHCP....

Now I guess I am stuck with some iptables-kung-fu.

darkphader, your options for the DHCP did help a little to reduce junk traffic in the network. BIG thanks for that.

off topic sarcasm: they say it's the same thing with sex and documentation. worse is better than nothing... 

regarding that execute command for DHCP, I never had that bad sex...

----------

