Hacker News new | ask | show | jobs
by arkadiyt 2008 days ago
IPv6 has internal ranges defined just like IPv4 does - anything in an internal range should be blocked, and anything in an external range is safe to pass through.
1 comments

Since there is no NAT in an IPv6 deployment unsafe services you typically want to prevent access to look like non internal ranges. Whereas in your normal IPv4 deployment you might have your protected service on 192.168.4.111 with IPv6 it will just share the same prefix (potentially) as your host.
NAT was meant to work around IP exhaustion issues, not act as a security layer. By accident, it often happens to provide some additional security. By keep in mind those "internal" IP addresses may be routable in some cases, due to either accidental or deliberate mis-configuration.

IPv6, with end-to-end connectivity, is how the Internet is supposed to work. It's how it did work in the early 90's, even with IPv4.

If you want to secure your servers, use a firewall. Maybe it's a host-based firewall.

What are the practical reasons we should rearchitect our systems to remove NAT?

(I know the weaknesses of NAT but the cat’s out of the bag at this point...the question isn’t really “why should we use NAT”, it’s “why should we go through the pain of breaking it”.)

IPv6 does nothing to break NAT, you could deploy the exact same kind of NAT and it would have the exact same behaviour, if you really want to make your router use a bunch more memory/CPU and make it a pain for users to do anything that needs a direct connection. But you gain nothing from doing that.
It's nice that this is how the internet is "supposed to work". In practice not having a NAT makes "automatic" internal protection of web services hard to impossible.

> If you want to secure your servers, use a firewall. Maybe it's a host-based firewall.

Firewalls do not solve this problem because a you do want service to service communication. What you do not want is code that crawls to user supplied URLs to access your internal services. Do you need application level protections. With IPv6 you're basically forced to declare your CIDR explicitly whereas with IPv4 you could easily achieve a secure by default system.

In these situations, store your IPv6 prefixes in a config. This doesn’t sound like a hard problem to solve.
Which is a manual process and because it is one it leaves many systems unprotected.
Systems that crawl user provided URLs are in the minority. For most systems it is irrelevant.
> IPv6, ..., is how the Internet is supposed to work

No, the way the Internet is supposed to work is that you have one routable address space. If you need to expand it, the previous address space is imported as a subset of the new one.

https://cr.yp.to/djbdns/ipv6mess.html

I will never forgive the IPv6 for not making the 32-bit IPv4 space a subrange of the 128-bit IPv6 space. Years after winning the IPng wars they admitted their mistake and standardized NAT64, but it was too late. NAT64 should have been part of IPv6 from day one, and every IPv6 router acting as a default route gateway should have been mandatorily-required to offer NAT64.

Mandating that every router has to do stateful connection tracking would have been an enormous, wasteful burden. NAT64 is there for those who need it; 464XLAT setups with IPv6-only clients are quietly the reality on networks that don't have too much legacy infrastructure (mostly mobile).
And having two completely separate internets (IPv6 and IPv4) forever isn't a wasteful burden?

Not requiring backwards compatibility in IPv6 guaranteed that IPv4 would be around forever. IPv4 is never, ever going away because of this.

The only people who couldn't see this coming were from Bell System backgrounds where you could use centralized schemes like "Ma Bell says tomorrow is the Flag Day, flip the switch". In a decentralized system people don't stop using the old system until you give them a new system that is backwards compatible. Then you drop the backwards compatibility in a second, separate upgrade much later, on a timetable dictated by adoption, not flag days.

> And having two completely separate internets (IPv6 and IPv4) forever isn't a wasteful burden?

Your proposal would force maintaining IPv4 for longer and in more networks: every IPv6 router would have to have IPv4 connectivity and probably a routeable IPv4 address, so it wouldn't even solve the address exhaustion problem for long (perhaps not even at all).

> Not requiring backwards compatibility in IPv6 guaranteed that IPv4 would be around forever. IPv4 is never, ever going away because of this.

IPv4 has already been eliminated from newer edge networks, and for those networks the vast majority of upstream traffic is IPv6. No doubt those networks will have to maintain 464XLAT for a long time as the long tail of upstream sites that are only v4-accessible, but they'll be able to have a smaller and smaller pool of 464XLAT servers and outsource the v4 connectivity support further and further upstream (just as with Usenet), until eventually v4 connectivity becomes a paid add-on and then goes away entirely. Home routers for use with PCs will probably have to offer 4over6 for a long time, because it's hard for an ISP to be confident all their users are up to date, but that doesn't actually reduce the benefits that much (all your internal network management can still be v6, only the little home user LANs are v4), and organisations that manage all their endpoint devices don't even need that much.

Maybe I'm misunderstanding you, but one of the points of the article in that you can represent IPv4 addresses in IPv6. In other words, IPv4 is a subset of IPv6.

If I'm on an ipv6-only host and blast UDP at ::ffff:1.2.3.4, they should get delivered to 1.2.3.4, no?

The actual, real-world problem with 4 being a subrange of 6 is that 4-only hosts are blissfully unaware that the super-range exists, so have no mechanism to send packets there. This is of course where you're right about NAT64 and the state requirements.

> If I'm on an ipv6-only host and blast UDP at ::ffff:1.2.3.4, they should get delivered to 1.2.3.4, no?

No, it won't necessarily! That's precisely the problem. Until NAT64 was introduced it was in fact impossible for an IPv6 router to deliver your packet to the IPv4 host 1.2.3.4. NAT64 still isn't mandatory (and likely never will be), so if you're writing software you can't assume those packets will get through even if you have an IPv6 network connection with a default route.

NAT64 didn't come about until long after IPv6 was finalized, and NAT64 support from default-route IPv6 routers is still is not mandatory. That's why we have this mess with dual-stack hosts: you cannot safely assume that your IPv6 router is willing to deal with the IPv4 world on your behalf.

The ::ffff:1.2.3.4 address space does, in fact, date back to the early days of IPv6 (it came from RFC 2765, about one year after IPv6 was finalized), but it was not meant for letting IPv6 clients share a single IPv4 address -- it was only for servers which for some reason had their own IPv4 address but couldn't speak IPv4. Yeah, back in the early 2000s people thought this problem might happen.

The IPv6 committee was viciously hostile to NATs. The way they saw it, NATs were the problem that made IPv6 necessary, so no way were they going to allow any NATs to pollute their precious IPv6. If that meant that the whole world had to run two separate internets (IPv4 and IPv6) for the rest of eternity just to keep the IPv6 network puritanically NAT-free, then so be it!

It took them more than a decade to realize how stupid this mindset was.

Ah! T see what you mean. Thanks for clarifying and correcting me.

I possibly have some sympathy with the anti-NAT view taken at the time, even if it ended up being the wrong thing to do it hindsight. Adding more mandatory complexity to implementors would have harmed adoption rates, and I've seen some weird edge cases with NAT64 - it's not necessarily a trivial thing to implement correctly.

::ffff:0:0/96 is for representing v4 addresses in v6 APIs. If you tell the kernel you want to send a packet to ::ffff:1.2.3.4, you're actually telling it you want to send a (v4!) packet to 1.2.3.4, you're just doing it using an AF_INET6 socket rather than an AF_INET one.

Since packets aren't APIs, you should never see ::ffff:0:0/96 in packets on the wire. A v6-only host can't use this prefix to send v4 packets to v4 hosts.

(What would the source address of those packets even be?)

Isn't this what the fd/8 local addresses are for?