I'm currently preparing a virtualised 'lab' to experiment with VoIP (Voice over IP), networking, and potentially some DMR network (radio) stuff in the future. I will be using GNS3, a program that was created to emulate networking devices but now also does a great job of emulating servers and their associated network topology.
Historically when using GNS3 I've configured each 'node' manually, however its 2017, dev-ops is hot, and manual configuration is not. Enter puppet, a configuration management tool that treats configuration more like code. You create a 'manifest' that contains instructions and templates on how to configure a device, and then an agent will then pull the configuration from the puppet master and apply the changes. Simple.
As far as I can tell (It's early days), puppet relies heavily on using hostnames to figure out which device needs which configuration. However, virtualised nodes within GNS3 are usually built from a template, and will share the same hostname when first configured. Additionally when a node is created, I don't know its MAC address, UUID, or any other identifier until its created. GNS3 will allow you to configure a hostname 'label' however this isn't communicated with the node out the box.
So, the plan? Create a script that will run on each node, query the GNS3 API and discover its own hostname, update it, and then puppet can do its thing and pull the correct configuration. BUT. How will the node know the IP that the API is running on?
I figured I could use DHCP options to send the IP of the API to the node, so it could then query the GNS3 API and grab it's hostname. I did the research and leg work, and then had an epiphany - what if someone had already invented a service that allows a device to find the IP address of a service... like... the Domain... Name... System. DNS.... Already invented.
I initially looked at the dhclient dhcp-options documentation but I was getting the syntax wrong and not having much luck. I then found Matt Fischers excellent blog post on the subject.
The following assumes you're using a dhclient, more than likely on *nix and you're logged in as root, or you're prefixing each command with sudo. It also assumes you're not using network manager. If you are, I suggest looking at Matt Fischers post instead.
Configure your DHCP server to send DHCP options
This varies from server to server so you will have to look it up. Sorry!
Configuring dhclient to request a DHCP option
First of all you will need to configure dhclient to request the custom option. To do so, open the dhclient.conf file-
They syntax for adding a custom option is-
option [name] code [code] = [type];
The name is for identification. It's not sent to server as part of the request. To keep to the convention is should contain no whitespace, but may contain dots and dashes.
The code should be a number between 1-254. I'd suggest you don't use one that's commonly used.
The type is they type of data the response will contain. This can be an ip-address, a string, or several other types listed in the documentation here (Hint: Ctrl + F 'The following simple option type definitions are supported')
This is what my entry looks like-
You will then need to add the new option to the 'request' block in the configuration. Once done, it should look something like this-
You can then save and exit the file.
At this stage it should just work, or you may need to restart DHCPD using the command below assuming your using a similar operating system-
For whatever reason I had to reboot to get things working properly, which seems a little heavy handed. Probably user error.
Doing something with the DHCP option
Now dhclient is requesting the DHCP option, you probably want to do something with it. You can do this with a hook script.
Create and open a new hook script-
Enter the following to save the new option in a file in /tmp/foo-
Renew your DHCP lease-
And check if the new option value has been written to the file.
All being well you should see the value. Its worth noting that the hooks must be bash scripts, and you should probably add some additional validation etc to your hook script.
Matt Fischer - Provided the examples and original tutorial.