MAC addresses in DHCPv6
tomasz at isc.org
Mon Jun 23 10:27:06 UTC 2014
Kea 0.9.0 is going to be released in the next several weeks. This is the
first post about proposed designs for the next release after 0.9. (Let's
tentatively call it 0.9.1). Everyone is encouraged to participate in
those discussions, not just ISC engineers.
Administrators are used to use MAC addresses in their network
management. MAC is easily available in the DHCPv4 (DHCPv4 uses raw
sockets, there's also CHADDR field that contains MAC). That is not the
case in DHCPv6, where MAC were replaced by DUIDs. Administrators have
databases of their existing equipment and want to identify IPv6 devices
MAC address is not readily available in DHCPv6. There are several ways
in which client's MAC address can be obtained by the DHCPv6 server. None
of them is 100% reliable. Here's the complete list:
1. Parse DUID in client-id option. The most common type of DUID is
DUID-LLT, which contains MAC address plus a timestamp. In most cases, it
is possible to extract MAC from the DUID-LLT. However, there are several
problems with that approach. First, RFC3315 forbids parsing DUIDs and
they must be treated as an opaque value. Second, devices may use other
types of DUID, for example DUID-EN or DUID-UUID, which does not contain
MAC address at all. Third, a device with multiple network interfaces can
(and often does) use the same DUID on all interfaces, so some of those
interfaces are transmitting DHCPv6 messages with DUIDs that do not match
MAC address of the interface they are transmitted on. That is a valid
behavior according to RFC3315. Fourth, this information can easily be
spoofed. That is especially important when the MAC address is needed due
to law enforcement requirements.
2. Extract MAC from senders IPv6 link-local address. Classic IPv6
link-local addresses are generated using EUI-64, which is basically MAC
address with extra well known bits. It is possible to reverse the
process and extract MAC from such addresses. Unfortunately, that process
is not reliable. There are 2 cases, where it fails. The first one is
when the client is using IPv6 privacy extensions. Instead of using
EUI-64 based link-local addresses, it then uses randomly generated
link-local address that change over time. That extension is supported
and enabled by default on Windows machines since I think Windows Vista.
The second case is when unicast traffic is enabled. Clients can use
their global address (not containing MAC) to communicate with the server
3. Extract MAC from incoming DHCPv6 packet. In principle, the DHCPv6
server receives the whole packet, including source MAC address. The
problem is that every DHCPv6 server I know of, uses UDP sockets to send
and receive traffic. The problem is that Linux kernel does not offer the
capability to extract MAC address information from UDP socket.
Furthermore, this information is of any use only for directly connected
clients. If the client is behind a relay agent, that method is useless
as it would obtain relay's, not client's MAC address. To implement this
method correctly, a change in the Linux kernel is needed. There are
invalid attempts at solving this by sending neighbor discovery queries,
but they are broken in the sense that they are susceptible to packet
spoofing (which is not acceptable for a feature that may be used for law
4. Client link address option (RFC6939). IETF attempted to solve the
problem of MAC in DHCPv6 and published RFC6939. This RFC defines a
client link address option. That option is inserted by relay agents and
contains MAC address of received messages from the clients. For a
directly connected clients, the server is supposed to extract MAC
addresses on their own (see #3 above). This solution will work correctly
once deployed. The current problem with it is that it is not widely
supported by relay vendors.
5. Remote-id option. In some specific deployments (e.g. cable networks),
the relay agents (CMTS in the cable terminology) insert remote-id option
that contains the MAC address of the clients (cable modems). In
principle, that can be used and interpreted as MAC addresses, but that
approach would work only if certain rather strict requirements were met
(if the access technology is cable, if supported spec is DOCSIS3.0, if ...).
6. Vendor options. In cable networks, cable modems that support
DOCSIS3.0 are sending docsis options that contain modem's MAC address. I
don't have docsis specs right now, but I think that was an option 36 in
vendor space 4491. This has the same properties and limitations as 5
above: usage restricted to certain access technologies with specific
spec versions of the docsis.
As shown above, there are multiple ways in which MAC can be obtained in
DHCPv6. Although we're not going to support them all at once, the number
will be growing over time, so the solution must be extensible.
As none of those methods is fully reliable, we will not depend on its
availability, just make that information accessible. How that
information is used, is out of scope for this discussion (I'll send out
a separate mail about host reservation soon).
It seems that we need to do the following tasks:
a) we will pick which mechanisms we want to support first. It seems that
1 (extract from DUID) and 4 (RFC6939, client link address option) are
reasonable first choices. Hopefully, we'll work on the remaining ones at
some later time.
b) we will extend Pkt6 with 2 extra fields:
- MAC address (will keep the MAC) - probably varchar(20) will be the
format here (in some access technologies MAC may be up to 20 bytes
- MAC source - that will be an enum value that will specify where the
MAC info came from.
c) Implement selected MAC acquisition code. Depending on which method(s)
we chose, it will be called either in IfaceMgr::receive6() or somewhere
d) Extend Lease6 structure with the same fields as in b)
e) extend the lease storage to store those 2 extra fields (MAC address
and MAC source). I'm afraid that includes updating all 3 backends
(memfile, MySQL, PostgreSQL). We may decide to extend them in the order
we chose, but I think it is important to do them all. Otherwise, we'll
get into the mess of implementing some ugly logic ("if the backend
supports storing MACs, do X, otherwise do Y").
f) Since b) and c) will automatically be accessible via hooks, we will
only need to test and document that capability, no need to write extra
code for hooks API.
g) This is not really needed for now, but that is something we may do
some time later. Since multiple MAC address sources are available, there
should be a way to prioritize them. This is actually non-trivial. In
general, admins should trust more in the info sent by the relays over
that sent by the clients, as clients can spoof their data. Various
deployment specific characteristics may influence that as well. Once the
capabilities to extract MAC addresses grow, we will likely need to add a
configuration parameter to prioritize one way over another.
Once those tasks are completed, we will make MAC addresses accessible in
DHCPv6. The server will not be able to do anything useful with them on
its own, but it will be possible to write hooks that will use them.
Also, this will lay solid foundation for the next feature: host
reservation. I'll send out a mail about that soon.
Thoughts? Comments? Volunteers?
More information about the kea-dev