Skip to content

Commit ddba0fc

Browse files
fix ipv6 support
1 parent be21c0a commit ddba0fc

3 files changed

Lines changed: 36 additions & 7 deletions

File tree

common/run_config.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -566,10 +566,10 @@ type RunConfig struct {
566566
Placement Placement `mapstructure:"placement" required:"false"`
567567
// Deprecated: Use Placement Tenancy instead.
568568
Tenancy string `mapstructure:"tenancy" required:"false"`
569-
// A list of IPv4 CIDR blocks to be authorized access to the instance, when
569+
// A list of IPv4/IPv6 CIDR blocks to be authorized access to the instance, when
570570
// packer is creating a temporary security group.
571571
//
572-
// The default is [`0.0.0.0/0`] (i.e., allow any IPv4 source).
572+
// The default is [`0.0.0.0/0`] (i.e., allow any IPv4 source) and if ssh_interface is set as "ipv6" the default is [`::/0`] (i.e., allow any IPv6 source).
573573
// Use `temporary_security_group_source_public_ip` to allow current host's
574574
// public IP instead of any IPv4 source.
575575
// This is only used when `security_group_id` or `security_group_ids` is not
@@ -650,7 +650,7 @@ type RunConfig struct {
650650
// Communicator settings
651651
Comm communicator.Config `mapstructure:",squash"`
652652

653-
// One of `public_ip`, `private_ip`, `public_dns`, `private_dns` or `session_manager`.
653+
// One of `public_ip`, `private_ip`, `public_dns`, `private_dns`, `ipv6` or `session_manager`.
654654
// If set, either the public IP address, private IP address, public DNS name
655655
// or private DNS name will be used as the host for SSH. The default behaviour
656656
// if inside a VPC is to use the public IP address if available, otherwise
@@ -662,6 +662,10 @@ type RunConfig struct {
662662
// `<region>.compute.internal` included in the `NO_PROXY` environment
663663
// variable.
664664
//
665+
// When using `ipv6` the VPC and subnet must be configured to support IPv6.
666+
// The default VPC and subnets do not have ipv6 configured by default.
667+
// Refer: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html
668+
//
665669
// When using `session_manager` the machine running Packer must have
666670
// the AWS Session Manager Plugin installed and within the users' system path.
667671
// Connectivity via the `session_manager` interface establishes a secure tunnel
@@ -777,6 +781,7 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
777781
c.SSHInterface != "private_ip" &&
778782
c.SSHInterface != "public_dns" &&
779783
c.SSHInterface != "private_dns" &&
784+
c.SSHInterface != "ipv6" &&
780785
c.SSHInterface != "session_manager" &&
781786
c.SSHInterface != "" {
782787
errs = append(errs, fmt.Errorf("Unknown interface type: %s", c.SSHInterface))
@@ -865,7 +870,11 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
865870
}
866871

867872
if len(c.TemporarySGSourceCidrs) == 0 && !c.TemporarySGSourcePublicIp {
868-
c.TemporarySGSourceCidrs = []string{"0.0.0.0/0"}
873+
if c.SSHInterface == "ipv6" {
874+
c.TemporarySGSourceCidrs = []string{"::/0"}
875+
} else {
876+
c.TemporarySGSourceCidrs = []string{"0.0.0.0/0"}
877+
}
869878
} else {
870879
for _, cidr := range c.TemporarySGSourceCidrs {
871880
if _, _, err := net.ParseCIDR(cidr); err != nil {

common/ssh.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ func SSHHost(ctx context.Context, e ec2Describer, sshInterface string, host stri
6060
if i.PrivateDnsName != nil {
6161
host = *i.PrivateDnsName
6262
}
63+
case "ipv6":
64+
if i.Ipv6Address != nil {
65+
host = *i.Ipv6Address
66+
}
6367
default:
6468
panic(fmt.Sprintf("Unknown interface type: %s", sshInterface))
6569
}

common/step_security_group.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"log"
10+
"net"
1011
"strings"
1112
"time"
1213

@@ -177,11 +178,25 @@ func (s *StepSecurityGroup) Run(ctx context.Context, state multistep.StateBag) m
177178
// map the list of temporary security group CIDRs bundled with config to
178179
// types expected by EC2.
179180
groupIpRanges := []ec2types.IpRange{}
181+
groupIpv6Ranges := []ec2types.Ipv6Range{}
180182
for _, cidr := range temporarySGSourceCidrs {
181-
ipRange := ec2types.IpRange{
182-
CidrIp: aws.String(cidr),
183+
_, ipNet, err := net.ParseCIDR(cidr)
184+
if err != nil {
185+
ui.Error(err.Error())
186+
state.Put("error", err)
187+
return multistep.ActionHalt
188+
}
189+
if ipNet.IP.To4() != nil {
190+
// IPv4 CIDR
191+
groupIpRanges = append(groupIpRanges, ec2types.IpRange{
192+
CidrIp: aws.String(cidr),
193+
})
194+
} else {
195+
// IPv6 CIDR
196+
groupIpv6Ranges = append(groupIpv6Ranges, ec2types.Ipv6Range{
197+
CidrIpv6: aws.String(cidr),
198+
})
183199
}
184-
groupIpRanges = append(groupIpRanges, ipRange)
185200
}
186201

187202
// Set some state data for use in future steps
@@ -199,6 +214,7 @@ func (s *StepSecurityGroup) Run(ctx context.Context, state multistep.StateBag) m
199214
{
200215
FromPort: aws.Int32(int32(port)),
201216
ToPort: aws.Int32(int32(port)),
217+
Ipv6Ranges: groupIpv6Ranges,
202218
IpRanges: groupIpRanges,
203219
IpProtocol: aws.String("tcp"),
204220
},

0 commit comments

Comments
 (0)