This code was written as part of a syslog replacement daemon which I wrote
in PHP.
The ISP I work for made the decision to migrate away from using
Radius to DHCP. Due to the change, we needed a good way to be able to
capture incoming "subscriber session"/circuit information for DSL subscribers.
In the past we had always done session logging via Radius -> MySQL.
Once you switch to DHCP, there is no sense of user authentication if doing
IP assignment dynamically so there is no real way of knowing who is consuming
your IP's.
This also presents a problem when big brother comes in and asks what
subscriber had a given IP address on a certain date/time.
In order to create a similar means of session logging that could actually
be mapped back to a subscriber, I came up with the idea of putting code
into the dhcpd.conf file to build a syslog string upon capturing a
DHCPREQUEST with option-82 circuit id info in it. The syslog string is
formed in such a way that it contains the IP address being handed out,
the MAC address that is requesting it, the circuit id in the DSLAM involved,
etc. Some info we wanted to capture for the session record such as the
lease timers wasn't available via the packets being received so it became
necessary to query the dhcpd daemon for the additional info before a
record could be placed into MySQL.
After experimenting with the OMAPI tools for ISC's dhcpd, and seeing that
it occasionally hung dhcpd, I ruled out using that to query the dhcpd with.
I couldn't find anything out there already written to do this in PHP so I set out
to reading RFC's on the DHCP protocol and set out to write it myself.
This code is the product of that work.
The end result/model looks something like this:
dsl_subsriber -> DSLAM -> ROUTER/RHCP_RELAY -> dhcpd -> rsyslog -> phpSyslogd -> MySQL
When the dhcpd sends out the string with the session info in it, it is formatted
in name=value pairs which are delimited by |'s. It sends it to the local syslog
daemon, which in my case, is rsyslogd. rsyslogd is far more robust than the
syslogd that is distributed with RedHat. rsyslogd then forwards the syslog entry to
a remote syslog daemon...my phpSyslogd. When it receives a syslog message that
starts with "opt82=1", it parses the line, grabs the required info, then queries
the dhcpd for any additional/needed info..after which it builds a query string and
either inserts it into MySQL as a new subscriber session or updates their existing
one if it finds an active match on the MAC/IP pairing.
You get the idea. ;-)
There is of course more than just that to it, but that is the basics of the overall
design/model. This code is but one (albeit, crucial) part of it.
Please be sure to run this code somewhere other than your DHCP server itself.
As is noted in the code, dhcpd will *NOT* listen on the local box for incoming
DHCPLEASEQUERY packets. Those are intended for use by actual DHCP Relays such
as a router or access server so it expects them to come in from elsewhere.
There could no doubt be bugs in this code. I don't know of any at this point
but for all I know it could eat your house, breed with your dog and maybe even
build a taco stand for all I know. Point being, I take no responsibility for what
it may do to your system(s). USE AT YOUR OWN RISK!!!
Aside from that, feel free to send comments, patches, ideas, etc.
to me at pat@patwinn.com and..enjoy!
--Pat
HOW TO USE:
As stated in the code, simply edit the variables in the LeaseQuery.php script,
then from a box other than the dhcp server, run it as: php LeaseQuery.php.
That's it!
|