Setting NTP Timezone using VyoS dhcp-server

I have been setting up the dhcp-server on VyOS to deliver NTP server and timezone information.

I have tested with a couple of different clients and both are receiving the NTP server address. I am not sure if either are receiving the timezone information.

Has anyone done this and can confirm my configuration is valid and should work please? TIA

Relevant Config

service {
    dhcp-server {
        global-parameters "option PCode code 100 = text;"
        global-parameters "option TCode code 101 = text;"
        shared-network-name internalLan {
            subnet 10.20.31.128/26 {
                default-router 10.20.31.129
                domain-name local
                lease 86400
                name-server 10.20.30.1
                ntp-server 10.20.30.1
                range 0 {
                    start 10.20.31.160
                    stop 10.20.31.190
                }
                subnet-parameters "option PCode "NZST-12NZDT,M9.5.0/2,M4.1.0/3";"
                subnet-parameters "option TCode "Pacific/Auckland";"
                time-offset 28800
            }
        }
    }
}

Output from two different Linux guests - both show the NTP server

from /run/NetworkManager/devices/*
[dhcp4]
dhcp4.dhcp_client_identifier=01:52:54:00:12:c0:94
dhcp4.dhcp_lease_time=82813
dhcp4.dhcp_server_identifier=10.20.31.129
dhcp4.domain_name=local
dhcp4.domain_name_servers=10.20.30.1
dhcp4.expiry=1696203086
dhcp4.ip_address=10.20.31.160
dhcp4.ntp_servers=10.20.30.1
dhcp4.routers=10.20.31.129
dhcp4.subnet_mask=255.255.255.192
from /run/ntp.conf.dhcp
# NTP server entries received from DHCP server
server 10.20.30.1 iburst

Relevant Config (as above but as commands)

set service dhcp-server global-parameters 'option PCode code 100 = text;'
set service dhcp-server global-parameters 'option TCode code 101 = text;'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 default-router '10.20.31.129'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 domain-name 'local'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 lease '86400'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 name-server '10.20.30.1'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 ntp-server '10.20.30.1'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 range 0 start '10.20.31.160'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 range 0 stop '10.20.31.190'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 subnet-parameters 'option PCode "NZST-12NZDT,M9.5.0/2,M4.1.0/3";'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 subnet-parameters 'option TCode "Pacific/Auckland";'
set service dhcp-server shared-network-name internalLan subnet 10.20.31.128/26 time-offset '28800'

Version: VyOS 1.3-rolling-202309140800

Who is the client, another VyOS or a regular lets say Linux or Windows client?

Output of generated /run/dhcp-server.conf (or what it might be called)?

When running dhclient with debug on the client, whats the output there?

Update : I can confirm that if the clients are requesting PCode and TCode in their DHCP request, that the VyOS router is returning the configured information. :+1:

I have seen the REQ and ACK packets containing the information in Wireshark.

I presume my issues are therefore either purely client related or that they are client related and I have incorrectly formatted the options lines above. Just a little bit of chicken and egg. Will update more as I get it.

In answer to your questions:

The clients I am using are various linux distros. As there seems to be some incompatibility between the ntp client, the dhcp client and the glue that joins them together, I have been trying a variety of flavours and versions but NixOS and Mint have been my main areas of testing.

By /run/dhcp-server.conf did you mean /run/dhcp-server/dhcpd.conf on the VyOS router?

If so, that looks ok - double quotes where I expected etc.

Not actually sure if I need to define PCode and TCode in the global section. I have left it in there but I will check later on with and without.

# The following 2 line(s) have been added as
# global-parameters in the CLI and have not been validated !!!
option PCode code 100 = text;
option TCode code 101 = text;

# Shared network configration(s)

shared-network internalLan {
    subnet 10.20.31.128 netmask 255.255.255.192 {
        option ntp-servers 10.20.30.1;
        # The following 2 line(s) were added as
        # subnet-parameters in the CLI and have not been validated!!!
        option PCode "NZST-12NZDT,M9.5.0/2,M4.1.0/3";
        option TCode "Pacific/Auckland";
        option time-offset 28800;
    }
}

I will try the debug options on dhclient and get back to you. Thanks.

Yes, it was the /run/dhcp-server/dhcpd.conf I was thinking of (didnt have any DHCP-server configured in my VyOS so I didnt know where its config would end up in /run).

You could test to move around so either you put all 4 lines together in the global section or you put all 4 lines together in the shared section and see if that gives any difference.

Could also be as you already observed if the client doesnt request the particular options then the DHCP-server wont provide them. As in this is a client issue where you might need to specify how dhclient requests to get the answer you like.

It seems like you might need to force the dhclient to request the options 100 and 101 by adding “option dhcp-parameter-request-list” to the dhclient.conf:

https://manpages.debian.org/bookworm/isc-dhcp-common/dhcp-options.5.en.html

Might be helpful?

https://wiki.orgamon.org/index.php?title=Raspberrypi.dhcp

Global options DHCP-server:

option ntp-servers 192.53.103.108;

option pcode code 100 = text;
option tcode code 101 = text;

option pcode "GMT+01:00";
option tcode "Europe/Amsterdam";

Settings DHCP-client (/etc/dhcpcd.conf)

# Most distributions have NTP support.
option ntp_servers, posix_timezone, tzdb_timezone

All four lines above seem to be required in order to make to options available for request.

Each option seems to require a global definition that has 3 parts; a LABEL, the code number and the format of the data. The LABEL seems to only be used within the DHCP server and VyOS doesn’t seem to care what it is, preferring I guess the actual code numbers.

Once the format of the data is defined, each individual subnet can have a different value for the same type of option. Doesn’t really make sense using the timezone label in my example, but hey-ho! :stuck_out_tongue:

service {
    dhcp-server {
        global-parameters "option LABEL1 code 100 = text;"
        shared-network-name internalLan1 {
            subnet 10.20.31.0/26 {
                subnet-parameters "option LABEL1 "Pacific/Auckland";"
            }
        }
        shared-network-name internalLan2 {
            subnet 10.20.31.128/26 {
                subnet-parameters "option LABEL1 "Pacific/Tahiti";"
            }
        }
    }
}

All that is left now is for the client to request the options it wants, which is configured on the client. I successfully configured NetworkManager (using dhclient or dhcpcd) to request both the options above and the VyOS router (as a DHCP server) replied perfectly. I was able to see the relevant data in both the Request and the Acks using Wireshark and also the data after it arrived on the client using nmcli. :+1:

Any issues that I have now, are all on the client, making sure the data the server sends can be used. Thanks for the thoughts and links, they helped. :pray:

A drawback using this method to set timezone is from security point of view.

DHCP responses are not authenticated meaning anyone with access to the L2 network could potentially inject bad timezone to the clients.

But this comes with the regular problems of rogue DHCP-servers and the same countermeasures should be applied as in:

  • Protected VLAN (defines that downlink interfaces on a L2-switch cannot talk to each other - they can only talk to the uplink interface(s)).

  • DHCP-snooping (defines from where a dhcp response is trusted interface wise).

  • DHCP-relay (forces forward of DHCP request to a dedicated DHCP-server as unicast).

And while you have DHCP-snooping and DHCP-relay setup a big bonus is to also implement Option82 to get semi static IP assignment.

That is whatever you connect to lets say SW2 INT4 always gets the same IP address assigned through DHCP (for example 192.168.102.4/24). This gives that you no longer need to deal with DUID/MAC-addresses to set “static” IP when DHCP is being used by the client(s).

However I havent figured out how to properly configure the DHCP-server in VyOS to hand out IP-addresses based on Option82 - if anyone in here already did so then please enlight me with some config examples :slight_smile: