Categories
SysOps

How to ensure that every Ubuntu virtual machine get its own IP address

Ensure that every Ubuntu virtual machine from the same template get its own IP address.

The issue

I am using multiple Ubuntu virtual machines inside Proxmox environment, so I experienced an unexpected issue with DHCP server as these machines get the same IP address.

dhcpd$ tail -f /var/log/dhcpd.log
[...]
Jul  3 18:43:59 scylla dhcpd[534]: DHCPDISCOVER from 46:63:81:7b:1c:b7 via eth0
Jul  3 18:44:00 scylla dhcpd[534]: DHCPOFFER on 172.16.151.113 to 46:63:81:7b:1c:b7 (jammy) via eth0
Jul  3 18:44:00 scylla dhcpd[534]: DHCPREQUEST for 172.16.151.113 (172.16.151.254) from 46:63:81:7b:1c:b7 (jammy) via eth0
Jul  3 18:44:00 scylla dhcpd[534]: DHCPACK on 172.16.151.113 to 46:63:81:7b:1c:b7 (jammy) via eth0
[...]
Jul  3 18:44:07 scylla dhcpd[534]: DHCPDISCOVER from 22:01:c9:af:a6:6a (jammy) via eth0
Jul  3 18:44:07 scylla dhcpd[534]: DHCPOFFER on 172.16.151.113 to 22:01:c9:af:a6:6a (jammy) via eth0
Jul  3 18:44:07 scylla dhcpd[534]: DHCPREQUEST for 172.16.151.113 (172.16.151.254) from 22:01:c9:af:a6:6a (jammy) via eth0
Jul  3 18:44:07 scylla dhcpd[534]: DHCPACK on 172.16.151.113 to 22:01:c9:af:a6:6a (jammy) via eth0
[...]

Use tcpdump, a powerful command-line packet analyzer to see what is going on and notice that Client-ID field is the same in both cases.

18:43:59.365889 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 317)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 46:63:81:7b:1c:b7 (oui Unknown), length 289, xid 0xaa444f11, secs 1, Flags [none]
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Discover
	    Client-ID (61), length 19: hardware-type 255, ca:53:09:5a:00:02:00:00:ab:11:2b:de:66:83:43:ae:3d:11
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Hostname (12), length 5: "jammy"
18:44:00.367401 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.113.bootpc: BOOTP/DHCP, Reply, length 300, xid 0xaa444f11, secs 1, Flags [none]
	  Your-IP 172.16.151.113
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Offer
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla
18:44:00.368060 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 329)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 46:63:81:7b:1c:b7 (oui Unknown), length 301, xid 0xaa444f11, secs 1, Flags [none]
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Request
	    Client-ID (61), length 19: hardware-type 255, ca:53:09:5a:00:02:00:00:ab:11:2b:de:66:83:43:ae:3d:11
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Server-ID (54), length 4: scylla
	    Requested-IP (50), length 4: 172.16.151.113
	    Hostname (12), length 5: "jammy"
18:44:00.376759 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.113.bootpc: BOOTP/DHCP, Reply, length 300, xid 0xaa444f11, secs 1, Flags [none]
	  Your-IP 172.16.151.113
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: ACK
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla
18:44:07.493920 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 317)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 22:01:c9:af:a6:6a (oui Unknown), length 289, xid 0x70c2db85, secs 1, Flags [none]
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Discover
	    Client-ID (61), length 19: hardware-type 255, ca:53:09:5a:00:02:00:00:ab:11:2b:de:66:83:43:ae:3d:11
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Hostname (12), length 5: "jammy"
18:44:07.494752 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.113.bootpc: BOOTP/DHCP, Reply, length 300, xid 0x70c2db85, secs 1, Flags [none]
	  Your-IP 172.16.151.113
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Offer
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla
18:44:07.495327 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 329)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 22:01:c9:af:a6:6a (oui Unknown), length 301, xid 0x70c2db85, secs 1, Flags [none]
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Request
	    Client-ID (61), length 19: hardware-type 255, ca:53:09:5a:00:02:00:00:ab:11:2b:de:66:83:43:ae:3d:11
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Server-ID (54), length 4: scylla
	    Requested-IP (50), length 4: 172.16.151.113
	    Hostname (12), length 5: "jammy"
18:44:07.506164 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.113.bootpc: BOOTP/DHCP, Reply, length 300, xid 0x70c2db85, secs 1, Flags [none]
	  Your-IP 172.16.151.113
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: ACK
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla

The solution using MAC address as client identifier

Inspect default netplan configuration.

$ cat /etc/netplan/00-installer-config.yaml 
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens18:
      dhcp4: true
  version: 2

Use MAC address as client identifier.

$ sudo tee /etc/netplan/00-installer-config.yaml << EOF
network:
  ethernets:
    ens18:
      dhcp4: true
      dhcp-identifier: mac
  version: 2
EOF
network:
  ethernets:
    ens18:
      dhcp4: true
      dhcp-identifier: mac
  version: 2

Apply configuration.

$ sudo netplan apply

Inspect client identifier.

$ netplan ip leases ens18 
# This is private data. Do not parse.
ADDRESS=172.16.151.110
NETMASK=255.255.248.0
ROUTER=172.16.144.1
SERVER_ADDRESS=172.16.151.254
T1=43200
T2=75600
LIFETIME=86400
DNS=172.16.151.253
NTP=172.16.151.254
DOMAINNAME=octocat.cloud
CLIENTID=014663817b1cb7

DHCP server logs and network packets.

dhcpd$ tail -f /var/log/dhcpd.log
Jul  3 19:04:47 scylla dhcpd[534]: DHCPDISCOVER from 46:63:81:7b:1c:b7 via eth0
Jul  3 19:04:48 scylla dhcpd[534]: DHCPOFFER on 172.16.151.110 to 46:63:81:7b:1c:b7 (jammy) via eth0
Jul  3 19:04:48 scylla dhcpd[534]: DHCPREQUEST for 172.16.151.110 (172.16.151.254) from 46:63:81:7b:1c:b7 (jammy) via eth0
Jul  3 19:04:48 scylla dhcpd[534]: DHCPACK on 172.16.151.110 to 46:63:81:7b:1c:b7 (jammy) via eth0
dhcpd$ sudo tcpdump -v udp port 67
19:04:47.771070 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 305)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 46:63:81:7b:1c:b7 (oui Unknown), length 277, xid 0xc88446c4, secs 1, Flags [none]
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Discover
	    Client-ID (61), length 7: ether 46:63:81:7b:1c:b7
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Hostname (12), length 5: "jammy"
19:04:48.772552 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.110.bootpc: BOOTP/DHCP, Reply, length 300, xid 0xc88446c4, secs 1, Flags [none]
	  Your-IP 172.16.151.110
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Offer
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla
19:04:48.773346 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 317)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 46:63:81:7b:1c:b7 (oui Unknown), length 289, xid 0xc88446c4, secs 1, Flags [none]
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Request
	    Client-ID (61), length 7: ether 46:63:81:7b:1c:b7
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Server-ID (54), length 4: scylla
	    Requested-IP (50), length 4: 172.16.151.110
	    Hostname (12), length 5: "jammy"
19:04:48.782143 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.110.bootpc: BOOTP/DHCP, Reply, length 300, xid 0xc88446c4, secs 1, Flags [none]
	  Your-IP 172.16.151.110
	  Client-Ethernet-Address 46:63:81:7b:1c:b7 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: ACK
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla

This solution requires altering netplan configuration inside Ubuntu template.

The solution using RFC4361-compliant client identifier

Inspect current machine ID.

$ systemd-machine-id-setup --print

81c373c413d14926b1e6845429fd7772

Remove /etc/machine-id file

$ sudo rm /etc/machine-id

Reinitialize machine ID to alter client identifier.

$ sudo systemd-machine-id-setup 
Initializng machine ID from VM UUID

Inspect new machine ID.

$ systemd-machine-id-setup --print
8487018747a0405dbfb862bcd8db7ce1

Apply configuration.

$ sudo netplan apply

Inspect client identifier.

$ sudo netplan  ip leases ens18 
# This is private data. Do not parse.
ADDRESS=172.16.151.112
NETMASK=255.255.248.0
ROUTER=172.16.144.1
SERVER_ADDRESS=172.16.151.254
T1=43200
T2=75600
LIFETIME=86400
DNS=172.16.151.253
NTP=172.16.151.254
DOMAINNAME=octocat.cloud
CLIENTID=ffca53095a00020000ab116155f4f73d4c7fe4

DHCP server logs and network packets.

dhcpd$ tail -f /var/log/dhcpd.log
Jul  3 18:56:45 scylla dhcpd[534]: DHCPDISCOVER from 22:01:c9:af:a6:6a via eth0
Jul  3 18:56:46 scylla dhcpd[534]: DHCPOFFER on 172.16.151.112 to 22:01:c9:af:a6:6a (jammy) via eth0
Jul  3 18:56:46 scylla dhcpd[534]: DHCPREQUEST for 172.16.151.112 (172.16.151.254) from 22:01:c9:af:a6:6a (jammy) via eth0
Jul  3 18:56:46 scylla dhcpd[534]: DHCPACK on 172.16.151.112 to 22:01:c9:af:a6:6a (jammy) via eth0
dhcpd$ sudo tcpdump -v udp port 67
18:56:45.164727 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 317)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 22:01:c9:af:a6:6a (oui Unknown), length 289, xid 0x2b4e1650, secs 1, Flags [none]
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Discover
	    Client-ID (61), length 19: hardware-type 255, ca:53:09:5a:00:02:00:00:ab:11:61:55:f4:f7:3d:4c:7f:e4
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Hostname (12), length 5: "jammy"
18:56:46.166341 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.112.bootpc: BOOTP/DHCP, Reply, length 300, xid 0x2b4e1650, secs 1, Flags [none]
	  Your-IP 172.16.151.112
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Offer
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla
18:56:46.167213 IP (tos 0xc0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 329)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 22:01:c9:af:a6:6a (oui Unknown), length 301, xid 0x2b4e1650, secs 1, Flags [none]
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Request
	    Client-ID (61), length 19: hardware-type 255, ca:53:09:5a:00:02:00:00:ab:11:61:55:f4:f7:3d:4c:7f:e4
	    Parameter-Request (55), length 11: 
	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
	      Domain-Name (15), MTU (26), Static-Route (33), NTP (42)
	      Unknown (119), Unknown (120), Classless-Static-Route (121)
	    MSZ (57), length 2: 576
	    Server-ID (54), length 4: scylla
	    Requested-IP (50), length 4: 172.16.151.112
	    Hostname (12), length 5: "jammy"
18:56:46.183976 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
    scylla.bootps > 172.16.151.112.bootpc: BOOTP/DHCP, Reply, length 300, xid 0x2b4e1650, secs 1, Flags [none]
	  Your-IP 172.16.151.112
	  Client-Ethernet-Address 22:01:c9:af:a6:6a (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: ACK
	    Server-ID (54), length 4: scylla
	    Lease-Time (51), length 4: 86400
	    Subnet-Mask (1), length 4: 255.255.248.0
	    Default-Gateway (3), length 4: router.octocat.cloud
	    Domain-Name-Server (6), length 4: dns.octocat.cloud
	    Domain-Name (15), length 13: "octocat.cloud"
	    NTP (42), length 4: scylla

This solution requires reinitializing machine ID in the /etc/machine-id file during first boot.