dhcpcd-discuss

Re: Prefix Delegation Hook Script

Timo Sigurdsson

Tue Jan 22 22:48:30 2019

Hi Roy,

thanks for your reply. See my comments below.

Roy Marples schrieb am 22.01.2019 17:16:

> 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.
Ok, in that case, I'd keep this part as it is.

> 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.
Good to know. Then I will add another loop around the current "for ia_pd_prefix_no in 1 2 3 4 5" loops in order to make this more reliable.

 
> I'm not sure whether to start packing stuff like this in the dhcpcd 
> distribution or not.
That is entirely up to you of course. I just wanted to send this so it is archived for reference somewhere and since I was just recently contacted off-list regarding the handling of prefix delegation which kind of motivated me to test this further so I could actually submit it.

I know such use cases are individual and hard to generalize, so I'd never put it in the default hook directory. But having such scripts either in some documentation folder with a disclaimer or even in a separate package or repository might help. Apparmor has a lot of application profiles that are unusable without some customization, but you can find them in the documentation folder, adjust and install them.

> 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.

As for my script, the only non-POSIX shell feature used is the "local" built-in, which even Busybox ash supports but it could easily removed or avoided. I'm also aware that the sed option -i (in-place) is not universally available in non-GNU sed variants. But this could easily worked around with by using temporary copies, if need be. The use of Perl-style regular expressions with grep (-P option) is likewise not supported in all variantes, but that could also be avoided. A few more adjustments would be required to not depend on the ip command. I'm not really experienced with any of the BSDs and have no system to test it on, so my inclination to make the script portable to that extent was next to zero. I just tried to use the tools that my distribution offers by default anyway and avoid the use of additional packages. 

Regards,

Timo

References:
Prefix Delegation Hook ScriptTimo Sigurdsson
Re: Prefix Delegation Hook ScriptRoy Marples
Archive administrator: postmaster@marples.name