Skip to content

Instantly share code, notes, and snippets.

@poggenpower
Last active August 27, 2022 19:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poggenpower/eff8ad13a9611bff8523e849a6aa4bfd to your computer and use it in GitHub Desktop.
Save poggenpower/eff8ad13a9611bff8523e849a6aa4bfd to your computer and use it in GitHub Desktop.
Convert default-duid from dhclient6.leases to hex for DHCP Server assigments

DUID reset and conversion

Using DHCPv6 in ipv6 you don't assign setting per MAC but per DUID. On many linux flavours you will find the DUID in the firtst line of /var/lib/dhcp/dhclient6.XXXX.leases as default-duid where XXXX is the name of the interface. e.g. default-duid "\000\001\000\001'\305H\356\016\265<\373[\372"; a string with octal escaped bytes if it is not a printable ACSI charakter.

converting the DUID

Almost all DHCPv6 servers expect the DUID in hex notation. Following python3 script will convert it:

duid = "\000\001\000\001'\305H\356\016\265<\373[\372"
print(":".join("{:02x}".format(ord(x)) for x in duid ))

reset DUID

if you have cloned your VM or Container is it likely that all of them have the same DUID, which is bad. To reset the DUID it is not enough to delete the dhclient6.XXXX.leases lease file, but also the one for ipv4 in the same directory dhclient.XXXX.leases otherwise it get copied over from there.

You may also need to ensure /etc/machine-id is unique in your environment.

Attached get_duid.py

a simple ansible module to get the DUID from a debian system

#!/usr/bin/python
from ansible.module_utils.basic import *
def get_duid(interface):
fl = next(open(f"/var/lib/dhcp/dhclient.{interface}.leases",'r'))
# extract duid from line and unescape backslash
duid=fl.split('"')[1::2][0].encode().decode('unicode_escape')
# convert octal into hex encoding
return ":".join("{:02x}".format(ord(x)) for x in duid)
def main():
fields = {
'interface': {"required": True, "type": "str"},
}
module = AnsibleModule(argument_spec=fields)
duid = get_duid(module.params['interface'])
facts = {
"duid": duid,
}
module.exit_json(changed=False, duid=duid, ansible_facts=facts)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment