Skip to content

Instantly share code, notes, and snippets.

@artizirk
Last active February 28, 2023 04:03
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 artizirk/a861db25d3462fe3bba0d96fd4347276 to your computer and use it in GitHub Desktop.
Save artizirk/a861db25d3462fe3bba0d96fd4347276 to your computer and use it in GitHub Desktop.
ISC dhclient IPv6 prefix delegation hook script https://wiki.wut.ee/en/sysadmin

ISC dhclient IPv6 prefix delegation hook script

Based on this https://gist.github.com/jayeye/689cb1de2275798659c58c62ab92cfaa

#!/usr/bin/env python3

import ipaddress
import os
import sys
import textwrap
from subprocess import run


def ip_from_subnet(subnet, index):
    ip = subnet[index].compressed + '/' + str(subnet.prefixlen)
    return ipaddress.IPv6Interface(ip)


reason = os.getenv('reason')
if reason not in ['BOUND6', 'REBIND6']:
  print('Reason was {}, exiting ip6 hook'.format(reason))
  sys.exit(0)
old_prefix = os.getenv('old_ip6_prefix')
new_prefix = os.getenv('new_ip6_prefix')
if reason == "REBIND6" and old_prefix != new_prefix:
    print("OLD AND NEW PREFIX ARE DIFFERENT!!!!!!")
    print("Old:", old_prefix)
    print("New:", new_prefix)

delegation = ipaddress.IPv6Network(new_prefix)
all_subnets = list(delegation.subnets(new_prefix=64))

br_int_subnet = all_subnets[0]
br_int_address = ip_from_subnet(br_int_subnet, 1)
args = ["ip", "address", "add", br_int_address.with_prefixlen, "dev", "br-int"]
print(args)
run(args)

Systemd service

[Unit]
Description=IPv6 Prefix Delegation client
After=network-online.target
Wants=network-online.target

[Service]
Environment=PYTHONUNBUFFERED=1
ExecStart=/usr/sbin/dhclient -6 -d -df /etc/dhcp/dhcp-client-duid -sf /etc/dhcp/dhclient-ipv6-hook.py --prefix-len-hint 60 -R -P br-zoo
Restart=always

[Install]
WantedBy=multi-user.target

dnsmasq conf

domain=host.example.com
no-poll # don't constanly poll /etc/resolv.conf
#resolv-file=/etc/resolv.conf
no-resolv
server=8.8.8.8
server=8.8.4.4
domain-needed
bogus-priv
#listen-address=192.19.18.1
interface=br-int
bind-dynamic
except-interface=lo
dhcp-range=192.19.18.100,192.19.18.200,255.255.255.0,12h

# IPv6
enable-ra
dhcp-range=::1:1,::2:0,constructor:br-int, slaac, ra-names

# When systemd-networkd or some other dhcp client requests for a ip address
# they will be given a address based on their hostname.
# This section can be moved to seperate file using dhcp-hostsfile option
dhcp-host=virt-machine,192.19.18.4,[::4]
dhcp-host=other,192.19.18.10,[::a]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment