Zero-Touch Provisioning for Juniper

Vincent Bernat

Ju­niper’s of­fi­cial doc­u­men­ta­tion on ZTP ex­plains how to con­fig­ure the ISC DHCP Server to au­to­mat­i­cally up­grade and con­fig­ure on first boot a Ju­niper de­vice. How­ever, the pro­posed con­fig­u­ra­tion could be a bit more el­e­gant. This note ex­plains how.

TL;DR

Do not re­de­fine op­tion 43. In­stead, spec­ify the ven­dor op­tion space to use to en­code pa­ram­e­ters with vendor-option-space.


When boot­ing for the first time, a Ju­niper de­vice re­quests its IP ad­dress through a DHCP dis­cover mes­sage, then re­quests ad­di­tional pa­ram­e­ters for au­to­con­fig­u­ra­tion through a DHCP re­quest message:

Dynamic Host Configuration Protocol (Request)
    Message type: Boot Request (1)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x44e3a7c9
    Seconds elapsed: 0
    Bootp flags: 0x8000, Broadcast flag (Broadcast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 0.0.0.0
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: 02:00:00:00:00:01 (02:00:00:00:00:01)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (54) DHCP Server Identifier (10.0.2.2)
    Option: (55) Parameter Request List
        Length: 14
        Parameter Request List Item: (3) Router
        Parameter Request List Item: (51) IP Address Lease Time
        Parameter Request List Item: (1) Subnet Mask
        Parameter Request List Item: (15) Domain Name
        Parameter Request List Item: (6) Domain Name Server
        Parameter Request List Item: (66) TFTP Server Name
        Parameter Request List Item: (67) Bootfile name
        Parameter Request List Item: (120) SIP Servers
        Parameter Request List Item: (44) NetBIOS over TCP/IP Name Server
        Parameter Request List Item: (43) Vendor-Specific Information
        Parameter Request List Item: (150) TFTP Server Address
        Parameter Request List Item: (12) Host Name
        Parameter Request List Item: (7) Log Server
        Parameter Request List Item: (42) Network Time Protocol Servers
    Option: (50) Requested IP Address (10.0.2.15)
    Option: (53) DHCP Message Type (Request)
    Option: (60) Vendor class identifier
        Length: 15
        Vendor class identifier: Juniper-mx10003
    Option: (51) IP Address Lease Time
    Option: (12) Host Name
    Option: (255) End
    Padding: 00

It re­quests sev­eral op­tions, in­clud­ing the TFTP server ad­dress op­tion 150, and the Ven­dor-Spe­cific In­for­ma­tion Op­tion 43—or VSIO. The DHCP server can use op­tion 60 to iden­tify the ven­dor-spe­cific in­for­ma­tion to send. For Ju­niper de­vices, op­tion 43 en­codes the im­age name and the con­fig­u­ra­tion file name. They are fetched from the IP ad­dress pro­vided in op­tion 150.

The of­fi­cial doc­u­men­ta­tion on ZTP pro­vides a valid con­fig­u­ra­tion to an­swer such a re­quest. How­ever, it does not lever­age the abil­ity of the ISC DHCP Server to sup­port sev­eral ven­dors and re­de­fines op­tion 43 to be Ju­niper-specific:

option NEW_OP-encapsulation code 43 = encapsulate NEW_OP;

In­stead, it is pos­si­ble to de­fine an op­tion space for Ju­niper, us­ing a self-de­scrip­tive name, with­out over­rid­ing option 43:

# Juniper vendor option space
option space juniper;
option juniper.image-file-name     code 0 = text;
option juniper.config-file-name    code 1 = text;
option juniper.image-file-type     code 2 = text;
option juniper.transfer-mode       code 3 = text;
option juniper.alt-image-file-name code 4 = text;
option juniper.http-port           code 5 = text;

Then, when you need to set these sub­op­tions, spec­ify the ven­dor op­tion space:

class "juniper-mx10003" {
  match if (option vendor-class-identifier = "Juniper-mx10003") {
  vendor-option-space juniper;
  option juniper.transfer-mode    "http";
  option juniper.image-file-name  "/images/junos-vmhost-install-mx-x86-64-19.3R2-S4.5.tgz";
  option juniper.config-file-name "/cfg/juniper-mx10003.txt";
}

This con­fig­u­ra­tion re­turns the fol­low­ing answer:1

Dynamic Host Configuration Protocol (ACK)
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x44e3a7c9
    Seconds elapsed: 0
    Bootp flags: 0x8000, Broadcast flag (Broadcast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 10.0.2.15
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: 02:00:00:00:00:01 (02:00:00:00:00:01)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (53) DHCP Message Type (ACK)
    Option: (54) DHCP Server Identifier (10.0.2.2)
    Option: (51) IP Address Lease Time
    Option: (1) Subnet Mask (255.255.255.0)
    Option: (3) Router
    Option: (6) Domain Name Server
    Option: (43) Vendor-Specific Information
        Length: 89
        Value: 00362f696d616765732f6a756e6f732d766d686f73742d69…
    Option: (150) TFTP Server Address
    Option: (255) End

Us­ing vendor-option-space di­rec­tive al­lows you to make dif­fer­ent ZTP im­ple­men­ta­tions co­ex­ist. For ex­am­ple, you can add the op­tion space for PXE:

option space PXE;
option PXE.mtftp-ip    code 1 = ip-address;
option PXE.mtftp-cport code 2 = unsigned integer 16;
option PXE.mtftp-sport code 3 = unsigned integer 16;
option PXE.mtftp-tmout code 4 = unsigned integer 8;
option PXE.mtftp-delay code 5 = unsigned integer 8;
option PXE.discovery-control    code 6  = unsigned integer 8;
option PXE.discovery-mcast-addr code 7  = ip-address;
option PXE.boot-server code 8  = { unsigned integer 16, unsigned integer 8, ip-address };
option PXE.boot-menu   code 9  = { unsigned integer 16, unsigned integer 8, text };
option PXE.menu-prompt code 10 = { unsigned integer 8, text };
option PXE.boot-item   code 71 = unsigned integer 32;

class "pxeclients" {
  match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
  vendor-option-space PXE;
  option PXE.mtftp-ip 10.0.2.2;
  # […]
}

On the same topic, do not over­ride op­tion 125 “VIVSO.” See “Zero-Touch Pro­vi­sion­ing for Cisco IOS.”