Skip to content

Commit

Permalink
baremetal: only respond to dhcp for control plane mac's
Browse files Browse the repository at this point in the history
The bootstrap can now co-exist with machine-api being online. That
means there could be an instance of Ironic, dnsmasq, etc running in
both the cluster and the bootstrap. This causes problems, as it's not
deterministic which dnsmasq instance the worker provisioned by the
machine-api will use. If it uses the bootstrap, then the worker will not
come online.

This is causing a percentage of baremetal installs to fail, with the
worker being offline, ingress and other operators never come up.

This change blocks dhcp requests from anything but control plane hosts,
using iptables. DHCPv6 relies on DUID's instead which makes things more
complicated to use dnsmasq's dhcp-host abilities, which prefers DUIDS
for IPv6.
  • Loading branch information
stbenjam authored and openshift-cherrypick-robot committed Feb 19, 2020
1 parent 4ed0d38 commit b342995
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
Expand Up @@ -94,7 +94,24 @@ for port in 80 5050 6385 ; do
fi
done

# It is possible machine-api-operator comes up while the bootstrap is
# online, meaning there could be two DHCP servers on the network. To
# avoid bootstrap responding to a worker, which would cause a failed
# deployment, we filter out requests from anyone else than the control
# plane. We are using iptables instead of dnsmasq's dhcp-host because
# DHCPv6 wants to use DUID's instead of mac addresses.
{{if .PlatformData.BareMetal.ProvisioningDHCPAllowList}}
$IPTABLES -t raw -N DHCP
$IPTABLES -t raw -A PREROUTING -p udp --dport 67 -j DHCP
$IPTABLES -t raw -A PREROUTING -p udp --dport 546 -j DHCP

for mac in {{.PlatformData.BareMetal.ProvisioningDHCPAllowList}}
do
$IPTABLES -t raw -A DHCP -m mac --mac-source "$mac" -j ACCEPT
done

$IPTABLES -t raw -A DHCP -j DROP
{{end}}

# Wait for images to be downloaded/ready
podman wait -i 1000 ipa-downloader
Expand Down
13 changes: 13 additions & 0 deletions pkg/asset/ignition/bootstrap/baremetal/template.go
Expand Up @@ -2,6 +2,7 @@ package baremetal

import (
"github.com/openshift/installer/pkg/types/baremetal"
"strings"
)

// TemplateData holds data specific to templates used for the baremetal platform.
Expand All @@ -18,6 +19,10 @@ type TemplateData struct {
// ProvisioningDHCPRange has the DHCP range, if DHCP is not external. Otherwise it
// should be blank.
ProvisioningDHCPRange string

// ProvisioningDHCPAllowList contains a space-separated list of all of the control plane's boot
// MAC addresses. Requests to bootstrap DHCP from other hosts will be ignored.
ProvisioningDHCPAllowList string
}

// GetTemplateData returns platform-specific data for bootstrap templates.
Expand All @@ -33,6 +38,14 @@ func GetTemplateData(config *baremetal.Platform) *TemplateData {

if !config.ProvisioningDHCPExternal {
templateData.ProvisioningDHCPRange = config.ProvisioningDHCPRange

var dhcpAllowList []string
for _, host := range config.Hosts {
if host.Role == "master" {
dhcpAllowList = append(dhcpAllowList, host.BootMACAddress)
}
}
templateData.ProvisioningDHCPAllowList = strings.Join(dhcpAllowList, " ")
}

return &templateData
Expand Down
20 changes: 20 additions & 0 deletions pkg/asset/ignition/bootstrap/baremetal/template_test.go
Expand Up @@ -13,6 +13,24 @@ func TestTemplatingIPv4(t *testing.T) {
BootstrapProvisioningIP: "172.22.0.2",
ProvisioningDHCPExternal: false,
ProvisioningDHCPRange: "172.22.0.10,172.22.0.100",
Hosts: []*baremetal.Host{
{
Role: "master",
BootMACAddress: "c0:ff:ee:ca:fe:00",
},
{
Role: "master",
BootMACAddress: "c0:ff:ee:ca:fe:01",
},
{
Role: "master",
BootMACAddress: "c0:ff:ee:ca:fe:02",
},
{
Role: "worker",
BootMACAddress: "c0:ff:ee:ca:fe:03",
},
},
}

result := GetTemplateData(&bareMetalConfig)
Expand All @@ -21,6 +39,7 @@ func TestTemplatingIPv4(t *testing.T) {
assert.Equal(t, result.ProvisioningCIDR, 24)
assert.Equal(t, result.ProvisioningIPv6, false)
assert.Equal(t, result.ProvisioningIP, "172.22.0.2")
assert.Equal(t, result.ProvisioningDHCPAllowList, "c0:ff:ee:ca:fe:00 c0:ff:ee:ca:fe:01 c0:ff:ee:ca:fe:02")
}

func TestTemplatingIPv6(t *testing.T) {
Expand All @@ -36,4 +55,5 @@ func TestTemplatingIPv6(t *testing.T) {
assert.Equal(t, result.ProvisioningCIDR, 64)
assert.Equal(t, result.ProvisioningIPv6, true)
assert.Equal(t, result.ProvisioningIP, "fd2e:6f44:5dd8:b856::2")
assert.Equal(t, result.ProvisioningDHCPAllowList, "")
}

0 comments on commit b342995

Please sign in to comment.