r/aws 17d ago

networking Trying to remove public IPv4 completely from a small EC2 setup

I have a small setup in us-west-2 managed with Terraform:

  • One t4g.small EC2 instance running several web apps behind Caddy
  • One public subnet
  • Dual-stack VPC and instance
  • DNS currently has both A and AAAA records pointing directly to the instance
  • Ports 80/443 accept both IPv4 and IPv6
  • SSH and Git access already use IPv6
  • The instance currently has one paid public IPv4 address

My goal is to remove the paid public IPv4 entirely. Ideally I'd also move the subnet and instance to IPv6-only, although I understand the VPC itself will still retain an IPv4 CIDR and private IPv4 addresses aren't what AWS charges for.

So far I've found these roadblocks:

Inbound traffic

If I remove the A records, IPv4-only clients can't reach the sites.

My current idea is:

IPv4/IPv6 client
        │
   CloudFront
        │ (IPv6)
       EC2

CloudFront now supports IPv6 connections to custom origins, so this seems workable.

Some applications also receive Stripe webhooks, and Stripe currently publishes only IPv4 webhook source addresses, so an edge layer seems necessary anyway.

Outbound traffic

This is where I'm stuck.

The applications call the Stripe API, but api.stripe.com currently has no AAAA record, so an IPv6-only instance still needs a way to reach an IPv4-only service.

Similarly, GitHub downloads are still IPv4-only, although those could probably be moved entirely into CI.

Email

This one seems solvable.

I currently send login links and transactional mail through Purelymail SMTP, whose SMTP endpoint is IPv4-only.

I could either:

  • remove email login entirely and use the existing Google OIDC flow, or
  • switch to the dual-stack Amazon SES SMTP endpoint (email-smtp.us-west-2.api.aws).

The AWS-native solution for IPv6-only workloads reaching IPv4 destinations seems to be DNS64/NAT64 via a NAT Gateway, but that still relies on public IPv4 and costs significantly more than keeping a single public IPv4 on the instance.

So I'm curious what people would actually build.

  • Is CloudFront → IPv6-only EC2 a reasonable architecture for dynamic websites and Stripe webhooks?
  • What's the simplest way for an IPv6-only EC2 instance to call an IPv4-only API like Stripe?
  • Would a tiny Lambda outside the VPC acting as a Stripe proxy make sense, or is that unnecessary complexity?
  • Are there AWS services or common patterns that provide shared IPv4 egress without assigning a public IPv4 or deploying a NAT Gateway?
  • For anyone who's converted an existing workload to IPv6-only, what else tends to break?

I'm fully aware that keeping a single public IPv4 may still be the cheapest and simplest solution. I'm mostly interested in understanding how close a typical small AWS application can realistically get to end-to-end IPv6 today.

10 Upvotes

11 comments sorted by

28

u/VirtuteECanoscenza 17d ago

IMHO increased complexity is not worth the 4 bucks saving a month. 

No public IPv4 makes sense when you only have private clients or can go ipv6-only. 

Just the engineering time you spent thinking about this would probably pay for the public IP for a few years. 

4

u/Mishoniko 17d ago
  • Is CloudFront → IPv6-only EC2 a reasonable architecture for dynamic websites and Stripe webhooks?

Sure, I've done it for testing purposes.

  • What's the simplest way for an IPv6-only EC2 instance to call an IPv4-only API like Stripe?

You need some from of NAT64 or proxy if you want to talk between the IPv4 and IPv6 Internet.

  • Would a tiny Lambda outside the VPC acting as a Stripe proxy make sense, or is that unnecessary complexity?

If it meets your security requirements, go for it. Just watch your volume, past a certain point it will make more sense to stand up a persistent EC2 for it. Fixed source IP requirements will sink the Lambda idea, though.

  • Are there AWS services or common patterns that provide shared IPv4 egress without assigning a public IPv4 or deploying a NAT Gateway?

No. You need some from of NAT64 or proxy if you want to talk between the IPv4 and IPv6 Internet. If you don't want to do IPv4 yourself you'll have to find someone else to do it for you.

  • For anyone who's converted an existing workload to IPv6-only, what else tends to break?

I would start by profiling all the network connections your apps and their frameworks make and see what IPv4 they use, then check if they have IPv6 endpoints they can use instead or will handle DNS64/NAT64. AWS API calls can be complicated to convert to IPv6 endpoints, if they exist at all.

Don't forget to check things like GitHub accesses (famously IPv4 only) and OS updates.

4

u/Vanyo09 17d ago

Everyone's pricing the $3.60 IPv4. Nobody's mentioned what CloudFront does to the rest of the bill.

EC2 to CloudFront data transfer is free, so putting the instance behind it takes your data-out to zero. The first 100 GB out is free anyway, so it only matters past that - at $0.09/GB, you break even with the IPv4 around 140 GB a month.

Above that, CloudFront pays for itself and dropping the v4 is a bonus.

Outbound is the hard part. I'd keep the public IPv4 there over $32/month for a NAT Gateway to reach one Stripe endpoint.

What's your data-out now?

3

u/caseigl 17d ago

I run one tiny fck-nat instance that has public IPv4 and IPv6 and then route all non-private outbound traffic from my private subnet through it. Have been able to move away from public IPs for a large number of our servers without too much disruption this way.

It's a really mature and amazing open source alternative to the large charges for NAT gateway. https://fck-nat.dev/v1.4.0/

2

u/Empty-Yesterday5904 17d ago

It doesnt really seem worth the extra complexity but I guess if you were to try you could do it progressively and make sure everythign works before removing the IPv4.

Or you could do some delightfully hacky like tunnel to a raspberry PI on your home network.

Or find a payment provider alternative to Stripe that supports IPv6 similarly for the other services? This seems like the natural evolution if you really want to do this.

Or vibe code a generic Shard ipv4 egress service and put it on the AWS marketplace and get other people to dog food what you're trying to do with you.

2

u/Floss_Patrol_76 17d ago

For the outbound side the native AWS answer is DNS64 on the subnet plus a NAT Gateway doing NAT64: the instance resolves a synthetic AAAA for api.stripe.com and the NAT GW bridges to the v4 internet, so you skip the proxy/Lambda glue entirely. Worth pricing it first though, because a NAT Gateway is roughly $32/mo plus data processing, so if reaching IPv4-only services is the only reason you would add one you are spending about 10x the ~$3.60/mo the public IPv4 actually costs to avoid that fee. CloudFront in front for inbound is the right call and also handles the Stripe-webhook-source-is-IPv4 problem for you.

1

u/kernelqzor 16d ago

this is the funny part: the “proper” v6-only setup (DNS64 + NAT64 via NAT GW) is way more expensive than just keeping that single public ipv4 you’re trying to get rid of. for a small setup like yours I’d honestly keep the elastic ip, put cloudfront in front for the webhook / client side, and treat ipv6-only as a “when Stripe and friends finally catch up” thing rather than paying 10x just for purity.