Re: Prefix Delegation Hook Script
Roy Marples
Tue Jan 22 16:16:48 2019
On 22/01/2019 01:45, Timo Sigurdsson wrote:
Hi Roy,
Hey List,
I finally found some time to clean up my prefix delegation hook script and test it in different environments/setups, so I feel confident enough it might actually be useful for someone else than me ;) You can find the script attached.
Motivation:
Just as a reminder, the motivation behind my script was, that I need to track changes of a dynamically assigned IPv6 prefix and all of its derived subnets which dhcpcd assigns to downstream interfaces in order to make configuration changes and restart services that depend on the IPv6 addressing information. While dhcpcd-run-hooks provides this information, it's not "in one place" or during a single event. You'd rather need to handle multiple sequential events (BOUND6, DELEGATED6, etc.) which means that you might end up restarting services multiple times in a row (depending on the number of subnets you assign). My script tries to optimize that, i.e. avoid restarting services repeatedly, if possible.
How it works:
Basically, when a prefix is obtained and dhcpcd-run-hooks executes with the reason BOUND6, dhcpcd will have configured all the subnet interfaces already (i.e. before the DELEGATED6 event is triggered for each interface). Therefore, the hook script does the following:
1) Check if the prefix is actually new (when the prefix is simply renewed and was already configured before, it does nothing).
2) If the prefix is new, it iterates over all the other network interfaces and checks whether the interface has an IPv6 addresses that belongs to the new prefix. If yes, it will write it to a lease file to keep track of it.
3) For each new prefix and for each subnet address that was identified, it allows to run user-defined configuration actions, e.g. adding a firewall rule for the new prefix or add a new subnet to the configuration of the RA daemon, etc.
4) After the prefix has been processed it will restart or reload user-defined services, such as the firewall, etc.
5) When dhcpcd-run-hooks runs with the reason DELEGATED6, the script will check whether it has seen this subnet before by checking the lease file. In most cases, it will do nothing, because the subnet address is already in the lease file. This means the prefix and all interface addresses were processed in one go and services are restarted once only.
6) As with every "rule", there's an exception: If one of the subnet interfaces wasn't ready at the time the prefix was obtained (e.g. no cable plugged in), then dhcpcd skips the configuration of this interface and triggers the configuration of the interface at a later point when the interface comes up. So, when dhcpcd-run-hooks is executed with reason DELEGATED6 and the script finds a subnet address it hasn't seen before, it will perform the user-defined configuration action for this subnet and restart the user-defined services. So, even this corner case isn't missed.
7) When a prefix expires, the script will look at the lease files and check which subnet addresses belong to that prefix and run user-defined configuration actions for the prefix and each subnet address, e.g. removing a firewall rule, etc. Then the user-defined services are restarted/reloaded again and the prefix and subnets are removed from the lease files.
A few more remarks:
First, don't be put off by the size/length of the script. It seems long, but a lot of it is just comments. The extensive comments should also make it easier to understand and customize the script. After all, it's up to the user to decide which services need to be restarted, etc. The customizable part is all in the top, so it's not necessary to read through the actual code if you "just want to use" the hook. The code itself also deals with a few corner cases which make it larger. But I prefer reliability over simplicity and size. I also tried to avoid external dependencies wherever it seemed reasonable to me, which is why I wrote some functions that could as well be provided by external tools (e.g. a function to test if an IPv6 address is in the range of a prefix). The few requirements are listed in the header of the script.
There are a few technical limitations that are mentioned in the header of the script as well, but in real operation, they should rarely come into play or be really limiting.
@Roy: I still have two questions regarding cases where I'm not sure if the script could or should be improved:
a) The script currently checks for new prefixes during the BOUND6, RENEW6, REBIND6 and REBOOT6 run reasons. But is it actually possible to get a different prefix during RENEW6 or REBIND6? If not, these two reasons could be dropped from the case statement.
b) Currently, The scripts checks the variables new_dhcp6_ia_pd1_prefix1 to new_dhcp6_ia_pd1_prefix5. But is it possible that the part _pd1_ can also change to _pd2_ and so on? During my testing with different servers, even two DHCPv6 servers on the same network, I never managed to get anything else than _pd1_. But if that is actually variable, I'd change the script to check variations of this, too. It would be very simple to to, as it's just another loop around the current code.
Wow, that's a really good script and looks quite portable as well!
Some answers
a) Unlikely, but technically possible.
b) Yes, this is possible as well. The ordinals are as they appear in the
DHCP message so this is entirely at the behest of the DHCP server always
getting them in the same order.
I'm not sure whether to start packing stuff like this in the dhcpcd
distribution or not. It's of no use to me personally and parts of it
maybe reliant on bash or some other tool that's not found in all my
supported OS's, but this is the second or third time someone's submitted
a hook script of kinds and storing them just in an email archive
probably isn't the best idea.
Roy
Archive administrator: postmaster@marples.name