​How To Configure Junos Devices As DHCP Servers

We’re going to look at how to configure three types of devices to act as a DHCP server. Click here if you need a refresher on how DHCP works.

Although the configurations are done on the virtual edition, it will be the same for physical devices as well.

The configuration is basically the same across all the devices, with minor tweaks.

Configuring A vQFX As A DHCP Server

In this example, the QFX will supply DHCP to VLAN 20 via an IRB interface. IRB interfaces are similar to SVI interfaces on Cisco equipment.

We will need to configure the following:

  • VLAN 20
  • Create an IRB interface, and associate it with VLAN 20
  • An address assignment configuration
  • Configure the local DHCP server service and associate it with the IRB interface for VLAN 20.
  • If you have a lo0 filter in place, ensure it will allow DHCP traffic.

In addition to the above, we also set the following:

  • An excluded range for the address pool, so addresses .1 to .19 are not handed out via DHCP. Because we have not specified a range for the address pool, it assumes the entire network in the network statement is available.
  • A static reservation is set for the Linux-2 host.

The vQFX is running Junos 21.3R3.10.

{master:0}[edit]
lab@vQFX-1# show vlans 
default {
    vlan-id 1;
}
vlan20 {
    vlan-id 20;
    l3-interface irb.20;
}


{master:0}[edit]
lab@vQFX-1# show interfaces irb 
unit 20 {
    family inet {
        address 192.168.20.1/24;
    }
}

{master:0}[edit]
lab@vQFX-1# show access 
address-assignment {
    pool my-pool {
        family inet {
            network 192.168.20.0/24;
            dhcp-attributes {
                name-server {
                    8.8.8.8;
                }
                router {
                    192.168.20.1;
                }
            }
            host Linux-2 {
                hardware-address aa:aa:aa:00:00:02;
                ip-address 192.168.20.100;
            }
            excluded-range my-range {
                low 192.168.20.1;
                high 192.168.20.19;
            }
        }
    }
}
                                        
{master:0}[edit]
lab@vQFX-1# show system services 
ssh {
    root-login deny;
    connection-limit 5;
    rate-limit 5;
}
dhcp-local-server {
    group my-group {
        interface irb.20;
    }
}

{master:0}[edit]
lab@vQFX-1#

What happens if both a range and an excluded-range are set?

You can set both. The excluded range of addresses needs to be a subset of the included range. That is, you are excluding addresses from the range of available addresses. If the excluded range has addresses from outside those in the included range a commit error will occur.

lab@vQFX-1# show access 
address-assignment {
    pool my-pool {
        family inet {
            network 192.168.20.0/24;
            range my-include-range {
                low 192.168.20.50;
                high 192.168.20.150;
            }
            dhcp-attributes {
                name-server {
                    8.8.8.8;
                }
                router {
                    192.168.20.1;
                }
            }
            host Linux-2 {
                hardware-address aa:aa:aa:00:00:02;
                ip-address 192.168.20.100;
            }
            excluded-range my-range {
                low 192.168.20.1;
                high 192.168.20.19;
            }                           
        }
    }
}

{master:0}[edit]
lab@vQFX-1# commit check 
error: Exclude range is not contained within an existing range for pool 'my-pool'
error: configuration check-out failed

{master:0}[edit]
lab@vQFX-1#

What happens if a static reservation is outside the range set?

The following example works fine. Linux-2 received the correct address of 192.168.20.40.

{master:0}[edit]
lab@vQFX-1# show access 
address-assignment {
    pool my-pool {
        family inet {
            network 192.168.20.0/24;
            range my-include-range {
                low 192.168.20.50;
                high 192.168.20.150;
            }
            dhcp-attributes {
                name-server {
                    8.8.8.8;
                }
                router {
                    192.168.20.1;
                }
            }
            host Linux-2 {
                hardware-address aa:aa:aa:00:00:02;
                ip-address 192.168.20.40;
            }
        }
    }
}
                                        
{master:0}[edit]
lab@vQFX-1#

What happens if a static reservation is within the excluded range?

In this case, we have now added an excluded range of addresses and configured Linux-2 to use one of these.

This does not commit.

lab@vQFX-1# show access   
address-assignment {
    pool my-pool {
        family inet {
            network 192.168.20.0/24;
            range my-include-range {
                low 192.168.20.50;
                high 192.168.20.150;
            }
            dhcp-attributes {
                name-server {
                    8.8.8.8;
                }
                router {
                    192.168.20.1;
                }
            }
            host Linux-2 {
                hardware-address aa:aa:aa:00:00:02;
                ip-address 192.168.20.141;
            }
            excluded-range my-exclude-range {
                low 192.168.20.140;
                high 192.168.20.150;
            }                           
        }
    }
}

{master:0}[edit]
lab@vQFX-1# commit 
error: pool config error excluded-address (Address 192.168.20.141 conflict with static host 'Linux-2')
error: configuration check-out failed

{master:0}[edit]
lab@vQFX-1#

DHCP Verification

To verify that DHCP is working we can look at the statistics and bindings. We want to ensure that there are bindings or leases, which show clients are getting addresses. We also want to make sure that we are receiving and sending DHCP messages.

{master:0}
lab@vQFX-1> show dhcp server binding   
IP address        Session Id  Hardware address   Expires     State      Interface
192.168.20.51     7           aa:aa:aa:00:00:01  86317       BOUND      irb.20              
192.168.20.100    8           aa:aa:aa:00:00:02  86320       BOUND      irb.20              

{master:0}
lab@vQFX-1> show dhcp server statistics 
Packets dropped:
    Total                      1
    No binding found           1

Offer Delay:
    DELAYED                    0
    INPROGRESS                 0
    TOTAL                      0

Messages received:
    BOOTREQUEST                28
    DHCPDECLINE                0
    DHCPDISCOVER               17
    DHCPINFORM                 0
    DHCPRELEASE                3
    DHCPREQUEST                8
    DHCPLEASEQUERY             0
    DHCPBULKLEASEQUERY         0
    DHCPACTIVELEASEQUERY       0

Messages sent:
    BOOTREPLY                  19
    DHCPOFFER                  11
    DHCPACK                    8        
    DHCPNAK                    0
    DHCPFORCERENEW             0
    DHCPLEASEUNASSIGNED        0
    DHCPLEASEUNKNOWN           0
    DHCPLEASEACTIVE            0
    DHCPLEASEQUERYDONE         0

{master:0}
lab@vQFX-1> 

Another thing to look at is the route table. There will be access-internal routes for the clients.

lab@vQFX-1> show route table inet.0  

inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

10.0.0.0/24        *[Direct/0] 03:52:47
                    >  via em0.0
10.0.0.20/32       *[Local/0] 03:52:47
                       Local via em0.0
169.254.0.0/24     *[Direct/0] 03:52:47
                    >  via em1.0
169.254.0.2/32     *[Local/0] 03:52:47
                       Local via em1.0
192.168.20.0/24    *[Direct/0] 03:47:32
                    >  via irb.20
192.168.20.1/32    *[Local/0] 03:47:32
                       Local via irb.20
192.168.20.51/32   *[Access-internal/12] 00:02:26
                    >  to 192.168.20.1 via irb.20
192.168.20.100/32  *[Access-internal/12] 00:02:22
                    >  to 192.168.20.1 via irb.20

{master:0}
lab@vQFX-1>

On the Linux devices, we can also check what DNS server(s) have been set.

eve@Linux-1:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (ens3)
Current Scopes: none
     Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Link 3 (ens4)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8
       DNS Servers: 8.8.8.8
eve@Linux-1:~$

Stopping The DHCP Service

To stop the DHCP service, we can simply deactivate or delete the system services dhcp-local-server configuration. In some cases, you may need to clear the DHCP clients first with a ‘clear dhcp server binding all’.

{master:0}[edit]
lab@vQFX-1# deactivate system services dhcp-local-server 

{master:0}[edit]
lab@vQFX-1# show system services 
ssh {
    root-login deny;
    connection-limit 5;
    rate-limit 5;
}
inactive: dhcp-local-server {
    group my-group {
        interface irb.20;
    }
}

{master:0}[edit]
lab@vQFX-1# commit 
configuration check succeeds
commit complete

{master:0}[edit]
lab@vQFX-1#

Configuring A vMX As A DHCP Server

When using a vMX as a DHCP server you will need a license for Junos versions 19 and later.

If you configure the DHCP server without a license, you may see an error in the messages log similar to the following:

Jan  8 01:54:50  vMX-1 jdhcpd: LIBSDB_LICENSE_CHECK_FAILED: License check failed. Feature LICBNG_FEAT_DHCP require vBNG-Preferred-Tier license

Looking at show dhcp server statistics you may see incrementing counters for bootrequest or dhcpdiscover messages, but not see any dhcpoffer messages sent.

The following example is from a vMX running Junos 17.4R2

We will need to configure the following:

  • Configure an interface facing the LAN we want to run DHCP for
  • An address assignment configuration
  • Configure the local DHCP server service and associate it with the IRB interface for VLAN 20.
  • If you have a lo0 filter in place, ensure it will allow DHCP traffic.
[edit]
lab@vMX-4-test# show interfaces ge-0/0/2 
unit 0 {
    family inet {
        address 192.168.10.1/24;
    }
}

[edit]
lab@vMX-4-test# show system services 
dhcp-local-server {
    group my-group {
        interface ge-0/0/2.0;
    }
}

[edit]
lab@vMX-4-test# show access 
address-assignment {
    pool my-pool {
        family inet {
            network 192.168.10.0/24;
            range new-range {
                low 192.168.10.20;
                high 192.168.10.150;
            }
            dhcp-attributes {
                name-server {
                    8.8.8.8;
                }
                router {
                    192.168.10.1;
                }
            }
            host Linux-2 {
                hardware-address aa:aa:aa:00:00:02;
                ip-address 192.168.10.32;
            }
        }
    }
}
                                        
[edit]
lab@vMX-4-test#

The verification is the same, we can look at the DHCP bindings and statistics.

lab@vMX-4-test> show dhcp server binding 
IP address        Session Id  Hardware address   Expires     State      Interface
192.168.10.20     1           aa:aa:aa:00:00:01  86138       BOUND      ge-0/0/2.0          
192.168.10.32     2           aa:aa:aa:00:00:02  86160       BOUND      ge-0/0/2.0          

lab@vMX-4-test> show dhcp server statistics 
Packets dropped:
    Total                      0

Offer Delay:
    DELAYED                    0
    INPROGRESS                 0
    TOTAL                      0

Messages received:
    BOOTREQUEST                6
    DHCPDECLINE                0
    DHCPDISCOVER               4
    DHCPINFORM                 0
    DHCPRELEASE                0
    DHCPREQUEST                2
    DHCPLEASEQUERY             0
    DHCPBULKLEASEQUERY         0

Messages sent:
    BOOTREPLY                  5
    DHCPOFFER                  3
    DHCPACK                    2
    DHCPNAK                    0
    DHCPFORCERENEW             0        
    DHCPLEASEUNASSIGNED        0
    DHCPLEASEUNKNOWN           0
    DHCPLEASEACTIVE            0
    DHCPLEASEQUERYDONE         0

lab@vMX-4-test> 

Checking the route table, we see the access internal routes for the DHCP clients.

lab@vMX-4-test> show route table inet.0 

inet.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

192.168.10.0/24    *[Direct/0] 00:09:15
                    > via ge-0/0/2.0
192.168.10.1/32    *[Local/0] 00:09:15
                      Local via ge-0/0/2.0
192.168.10.20/32   *[Access-internal/12] 00:09:09
                    > to 192.168.10.1 via ge-0/0/2.0
192.168.10.32/32   *[Access-internal/12] 00:08:47
                    > to 192.168.10.1 via ge-0/0/2.0

lab@vMX-4-test>

We can also check a client and confirm we are getting the right DHCP attributes. Here we check we get the right nameserver.

eve@Linux-1:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (ens3)
Current Scopes: none
     Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Link 3 (ens4)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8
       DNS Servers: 8.8.8.8

Configuring A vSRX As A DHCP Server

The configuration for a vSRX is almost the same as for any other Junos device.

We will need to configure the following:

  • An interface facing the DHCP clients
  • An address assignment configuration
  • Configure the local DHCP server service and associate it with the interface facing the clients
  • Ensure we update host-inbound-traffic settings to include system services dhcp

In addition to the above, we also set the following:

  • An excluded range for the address pool, so addresses .1 to .19 are not handed out via DHCP. Because we have not specified a range for the address pool, it assumes the entire network in the network statement is available.
  • A static reservation is set for the Linux-2 host.

The vSRX is running Junos 22.2R1.9. Here is the relevant configuration:

system {
    services {
        dhcp-local-server {
            group my-group {
                interface ge-0/0/1.0;
            }                           
        }

    }

}
security {
    zones {
        security-zone trust {
            tcp-rst;
            interfaces {
                ge-0/0/1.0 {
                    host-inbound-traffic {
                        system-services {
                            dhcp;
                            ping;
                        }               
                    }
                }
            }
        }
    }
}
interfaces {
    ge-0/0/1 {
        unit 0 {
            family inet {
                address 192.168.30.1/24;
            }
        }
    }
}
access {
    address-assignment {
        pool my-pool {
            family inet {
                network 192.168.30.0/24;
                dhcp-attributes {
                    name-server {
                        8.8.8.8;
                    }
                    router {
                        192.168.30.1;
                    }
                }
                host Linux-2 {
                    hardware-address aa:aa:aa:00:00:02;
                    ip-address 192.168.30.32;
                }
                excluded-range my-range {
                    low 192.168.30.1;
                    high 192.168.30.19;
                }                       
            }
        }
    }
}

We can again run the show dhcp server and show route commands to see active clients and that Linux-2 has been given the reserved address.

lab@vSRX-1> show dhcp server binding    
IP address        Session Id  Hardware address   Expires     State      Interface
192.168.30.22     3           aa:aa:aa:00:00:01  86090       BOUND      ge-0/0/1.0          
192.168.30.32     4           aa:aa:aa:00:00:02  86097       BOUND      ge-0/0/1.0          

lab@vSRX-1> show dhcp server statistics 
Packets dropped:
    Total                      0

Offer Delay:
    DELAYED                    0
    INPROGRESS                 0
    TOTAL                      0

Messages received:
    BOOTREQUEST                6
    DHCPDECLINE                0
    DHCPDISCOVER               4
    DHCPINFORM                 0
    DHCPRELEASE                0
    DHCPREQUEST                2
    DHCPLEASEQUERY             0
    DHCPBULKLEASEQUERY         0
    DHCPACTIVELEASEQUERY       0

Messages sent:
    BOOTREPLY                  6
    DHCPOFFER                  4
    DHCPACK                    2
    DHCPNAK                    0        
    DHCPFORCERENEW             0
    DHCPLEASEUNASSIGNED        0
    DHCPLEASEUNKNOWN           0
    DHCPLEASEACTIVE            0
    DHCPLEASEQUERYDONE         0

lab@vSRX-1> show route table inet.0 

inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

10.0.0.0/24        *[Direct/0] 04:02:57
                    >  via fxp0.0
10.0.0.15/32       *[Local/0] 04:02:57
                       Local via fxp0.0
192.168.30.0/24    *[Direct/0] 04:02:18
                    >  via ge-0/0/1.0
192.168.30.1/32    *[Local/0] 04:02:18
                       Local via ge-0/0/1.0
192.168.30.22/32   *[Access-internal/12] 00:05:20
                    >  to 192.168.30.1 via ge-0/0/1.0
192.168.30.32/32   *[Access-internal/12] 00:05:13
                    >  to 192.168.30.1 via ge-0/0/1.0

lab@vSRX-1>

SRX With DHCP Setting Propagation

Some SRX have additional behavior that isn’t present on the other platforms. These include the SRX 300’s, the 550M, and SRX 1500 devices. It’s also available on the vSRX, so I can show it below.

These platforms can propagate DHCP settings they learn on one interface to their own DHCP clients. This is useful where the SRX is deployed as an Internet gateway and gets its external address via DHCP. The DNS and other settings supplied by the ISP over DHCP can be passed on.

It requires a couple of changes to the configuration.

  • We have to configure an interface as a DHCP client and add the update-server setting. This interface will have to allow inbound DHCP traffic.
  • We have to set propagate-settings under our dhcp attributes and specify what interface to copy the settings from.

In the following example, the upstream DHCP server is setting the name server to 9.9.9.9.

The configuration on the vSRX now looks as follows:

system {
    services {
        dhcp-local-server {
            group my-group {
                interface ge-0/0/1.0;
            }                           
        }
    }
}
security {
    zones {
        security-zone trust {
            tcp-rst;
            interfaces {
                ge-0/0/1.0 {
                    host-inbound-traffic {
                        system-services {
                            dhcp;
                            ping;
                        }               
                    }
                }
            }
        }
        security-zone untrust {
            screen untrust-screen;
            interfaces {
                ge-0/0/0.0 {
                    host-inbound-traffic {
                        system-services {
                            ping;
                            dhcp;
                        }
                    }
                }
            }
        }
    }
}
interfaces {
    ge-0/0/0 {
        unit 0 {
            family inet {               
                dhcp {
                    update-server;
                }
            }
        }
    }
    ge-0/0/1 {
        unit 0 {
            family inet {
                address 192.168.30.1/24;
            }
        }
    }
}
access {
    address-assignment {                
        pool my-pool {
            family inet {
                network 192.168.30.0/24;
                dhcp-attributes {
                    router {
                        192.168.30.1;
                    }
                    propagate-settings ge-0/0/0.0;
                }
                host Linux-2 {
                    hardware-address aa:aa:aa:00:00:02;
                    ip-address 192.168.30.32;
                }
                excluded-range my-range {
                    low 192.168.30.1;
                    high 192.168.30.19;
                }
            }
        }
    }
}

Notice how under the address assignment pool we haven’t specified what nameserver to use?

The verification steps are the same as per the previous examples. One slightly new thing is the route table, due to the SRX getting a DHCP address on ge-0/0/0. There is now a default route.

lab@vSRX-1> show route table inet.0 

inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

0.0.0.0/0          *[Access-internal/12] 02:11:43, metric 0
                    >  to 192.168.20.1 via ge-0/0/0.0
10.0.0.0/24        *[Direct/0] 06:43:14
                    >  via fxp0.0
10.0.0.15/32       *[Local/0] 06:43:14
                       Local via fxp0.0
192.168.20.0/24    *[Direct/0] 02:11:43
                    >  via ge-0/0/0.0
192.168.20.54/32   *[Local/0] 02:11:43
                       Local via ge-0/0/0.0
192.168.30.0/24    *[Direct/0] 06:42:35
                    >  via ge-0/0/1.0
192.168.30.1/32    *[Local/0] 06:42:35
                       Local via ge-0/0/1.0
192.168.30.27/32   *[Access-internal/12] 00:02:28
                    >  to 192.168.30.1 via ge-0/0/1.0
192.168.30.32/32   *[Access-internal/12] 02:11:20
                    >  to 192.168.30.1 via ge-0/0/1.0

lab@vSRX-1>

If we look at the client, we can see that nameserver details have propagated from what the SRX learned on interface ge-0/0/0.

eve@Linux-1:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (ens3)
Current Scopes: none
     Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported

Link 3 (ens4)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 9.9.9.9
       DNS Servers: 9.9.9.9
eve@Linux-1:~$

Conclusions

The configuration of a DHCP local server is similar across all Junos devices. The ability for certain models of SRX to propagate DHCP attributes is handy as well.

One issue I did come across whilst making this post was having duplicate client identifiers on the Linux machines. Something to be wary of in your own lab environment.

Leave a Comment

Your email address will not be published. Required fields are marked *