Skip to content

Commit 78cb9d4

Browse files
committed
subnets: only enable DNS64 for IPv6-only subnets
NAT64/DNS64 is meant to be enabled for IPv6-only subnets, in which instances do not have IPv4 [0]. If we enable DNS64 for dualstack subnets, instances will receive both A/AAAA records for IPv4-only services. In most cases, OS-level settings will prefer IPv6, leading to traffic to flow via NAT gateway instead of using IPv4 directly. Reference [0] https://aws.amazon.com/blogs/networking-and-content-delivery/dual-stack-architectures-for-aws-and-hybrid-networks-part-2/
1 parent 3292f75 commit 78cb9d4

File tree

3 files changed

+7
-37
lines changed

3 files changed

+7
-37
lines changed

pkg/cloud/services/network/routetables.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,11 @@ func (s *Service) getRoutesToPrivateSubnet(sn *infrav1.SubnetSpec) (routes []*ec
422422

423423
routes = append(routes, s.getNatGatewayPrivateRoute(natGatewayID))
424424
if sn.IsIPv6 {
425-
routes = append(routes, s.getNat64PrivateRoute(natGatewayID))
425+
// We add the NAT64 route only if DNS64 is enabled for the subnet
426+
// That is when the subnet is private and IPv6-only.
427+
if sn.CidrBlock == "" {
428+
routes = append(routes, s.getNat64PrivateRoute(natGatewayID))
429+
}
426430
if !s.scope.VPC().IsIPv6Enabled() {
427431
// Safety net because EgressOnlyInternetGateway needs the ID from the ipv6 block.
428432
// if, for whatever reason by this point that is not available, we don't want to

pkg/cloud/services/network/subnets.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,8 @@ func (s *Service) createSubnet(sn *infrav1.SubnetSpec) (*infrav1.SubnetSpec, err
641641
// Enable DNS64 so that the Route 53 Resolver returns DNS records for IPv4-only services
642642
// containing a synthesized IPv6 address prefixed 64:ff9b::/96.
643643
// This is needed alongside NAT64 to allow IPv6-only workloads to reach IPv4-only services.
644-
// We only need to enable on private subnets.
645-
if !sn.IsPublic {
644+
// We only need to enable on IPv6-only private subnets as dualstack nodes can use communicate over IPv4.
645+
if !sn.IsPublic && sn.CidrBlock == "" {
646646
if err := wait.WaitForWithRetryable(wait.NewBackoff(), func() (bool, error) {
647647
if _, err := s.EC2Client.ModifySubnetAttribute(context.TODO(), &ec2.ModifySubnetAttributeInput{
648648
SubnetId: out.Subnet.SubnetId,

pkg/cloud/services/network/subnets_test.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,14 +1865,6 @@ func TestReconcileSubnets(t *testing.T) {
18651865
}).Return(&ec2.ModifySubnetAttributeOutput{}, nil).
18661866
After(secondSubnet)
18671867

1868-
m.ModifySubnetAttribute(context.TODO(), &ec2.ModifySubnetAttributeInput{
1869-
EnableDns64: &types.AttributeBooleanValue{
1870-
Value: aws.Bool(true),
1871-
},
1872-
SubnetId: aws.String("subnet-2"),
1873-
}).Return(&ec2.ModifySubnetAttributeOutput{}, nil).
1874-
After(secondSubnet)
1875-
18761868
m.DescribeAvailabilityZones(context.TODO(), gomock.Any()).
18771869
Return(&ec2.DescribeAvailabilityZonesOutput{
18781870
AvailabilityZones: []types.AvailabilityZone{
@@ -3748,14 +3740,6 @@ func TestReconcileSubnets(t *testing.T) {
37483740
}).Return(&ec2.ModifySubnetAttributeOutput{}, nil).
37493741
After(secondSubnet)
37503742

3751-
m.ModifySubnetAttribute(context.TODO(), &ec2.ModifySubnetAttributeInput{
3752-
EnableDns64: &types.AttributeBooleanValue{
3753-
Value: aws.Bool(true),
3754-
},
3755-
SubnetId: aws.String("subnet-2"),
3756-
}).Return(&ec2.ModifySubnetAttributeOutput{}, nil).
3757-
After(secondSubnet)
3758-
37593743
m.DescribeAvailabilityZones(context.TODO(), gomock.Any()).
37603744
Return(&ec2.DescribeAvailabilityZonesOutput{
37613745
AvailabilityZones: []types.AvailabilityZone{
@@ -4003,15 +3987,6 @@ func TestReconcileSubnets(t *testing.T) {
40033987
Return(&ec2.ModifySubnetAttributeOutput{}, nil).
40043988
After(zone1PrivateSubnet)
40053989

4006-
m.ModifySubnetAttribute(context.TODO(), &ec2.ModifySubnetAttributeInput{
4007-
EnableDns64: &types.AttributeBooleanValue{
4008-
Value: aws.Bool(true),
4009-
},
4010-
SubnetId: aws.String("subnet-2"),
4011-
}).
4012-
Return(&ec2.ModifySubnetAttributeOutput{}, nil).
4013-
After(zone1PrivateSubnet)
4014-
40153990
// zone 2
40163991
m.DescribeAvailabilityZones(context.TODO(), &ec2.DescribeAvailabilityZonesInput{
40173992
ZoneNames: []string{"us-east-1c"},
@@ -4185,15 +4160,6 @@ func TestReconcileSubnets(t *testing.T) {
41854160
}).
41864161
Return(&ec2.ModifySubnetAttributeOutput{}, nil).
41874162
After(zone2PrivateSubnet)
4188-
4189-
m.ModifySubnetAttribute(context.TODO(), &ec2.ModifySubnetAttributeInput{
4190-
EnableDns64: &types.AttributeBooleanValue{
4191-
Value: aws.Bool(true),
4192-
},
4193-
SubnetId: aws.String("subnet-2"),
4194-
}).
4195-
Return(&ec2.ModifySubnetAttributeOutput{}, nil).
4196-
After(zone2PrivateSubnet)
41974163
},
41984164
},
41994165
}

0 commit comments

Comments
 (0)