I can't find any mention of "bad actors" or "freezing out" anybody or anything so I'm going to guess you meant just generally which middle boxes are "bad" and the answer is all of them, almost by definition.
The specifications we're dealing with here don't (and in modern protocols, this is quite deliberate) allow for any middleboxes. The only, minimal way to implement such a thing correctly in the face of that situation is to act as a full proxy, which is going to _suck_ for performance and your customers aren't going to pay for a product that throttles their connectivity badly nor for the hardware that would let you run a line speed proxy.
So, they don't, they try to make an end run around the protocol compliance, typically the idea goes something like this:
During connection setup we'll inspect everything and implement whatever rules are key to our product, but mostly we'll pass things between the real client and server transparently, only intervening as necessary for our role
Then, we can "whitelist" most connections, and let them continue at line speed without actually being inspected further.
Unlike a full proxy this design breaks, messily, when optional protocol features are understood by the client and server but not the middlebox. This is because either the middlebox pretends to understand when it doens't (so client and server seem to get their mutually agreed new feature, but if it has any impact on how the protocol is used it breaks mysteriously since the middlebox didn't know) or the middlebox squashes everything it doesn't understand then steps out of the way and expects that to work out OK even though the client and server now misunderstand each other's situation.
> generally which middle boxes are "bad" and the answer is all of them, almost by definition.
NATs and firewalls are the first two classes of middleboxes that come to mind, and I wouldn't consider either of them inherently "bad".
As pointed out in the article, NATs suffer from the shortcoming that without visibility into stream semantics (e.g. SYNs / RSTs / FINs), they often fall back to using arbitrarily set timeouts that can sever long-lived connections (e.g. an idle SSH session, where messages might be infrequent).
In my view, "bad" middleboxes are those that lead to protocol ossification -- TLS 1.3 (also from the article) is a good example of that. With encrypted control state, middleboxes (without cooperation by one of the endhosts) are forced to treat QUIC packets as opaque UDP blobs.
Part of the problem is that some middleboxes don't actually follow the robustness principle, and will in fact strip unrecognized protocol options or drop the packets entirely.
That's not inherent to the provided functionality, but rather an implementation detail of existing boxes.
There are objectively bad NATs, yes, but extending the lifetime of IPv4 by 20 years and providing isolation between internal and external networks are not inherently bad.
NA(P)T is fundamentally incompatible with the guarantees set out by the IP standards that specify packets to be transmitted unmodified end-to-end. Their entire idea is to change the IP address and higher-level protocol identifiers such as ports.
A basic case that they break is when applications embed IP addresses in the data. The "timeout" problem in the article is also impossible to avoid in a guaranteed-correct way, since the NA(P)T can not know when a flow is finished and the mapping is safe to recycle.
Since these things are basically forbidden by the standards, their functionality has never been standardized. Hence the wild west of varying timeouts, heuristics, and various more-or-less broken attempts to munge application-level data (ALG).
> NA(P)T is fundamentally incompatible with the guarantees set out by the IP standards that specify packets to be transmitted unmodified end-to-end.
A small nitpick, but some fields of the IP packet are meant to be modified in transit. For instance, the TTL, the ECN marking bit, and the fragment fields. The checksum field is defined so it can be updated (without being recomputed) to match these changes.
But yeah, other than these fields in the IP header, and a few hop-by-hop headers or options, packets are not meant to be modified in transit (other than fragmentation, but this applies once the packet fragments are put together).
> extending the lifetime of IPv4 by 20 years and providing isolation between internal and external networks are not inherently bad.
It's hard to see how things would be worse in the alternative history without NAT. IPv6 deployment would have come much sooner - it's been ready for so long even in our current timeline.
Ambiguous addresses (RFC1918) aren't good for isolation, firewalls are. It's a common security problem that people end up joining different RFC1918 networks, and then don't know what the ACLs mean anymore. Isolation is provided by firewalls, not NATs after all. A NAT's job is to try to proxy traffic back and forth, not block it.
If you require any type of IP Helper/NAT_* module you are going to have problems with it at some point, and those problems will be very opaque to the end user, and even possibly the administrator.
For example, all VOIP and online gaming would be in a better place if IPv4 was taken out and shot years ago. The lost of 1:1 mapping between the server and client ports makes everything worse.
NAT is a minor nuisance for protocol design and most games have exactly zero problems with NATs. I think games are actually one of those things where NATs are really not a big issue, because the high packet rate will never produce timeout issues.
SIP is a different story, but SIP (and it seems all other VoIP stacks as well) are mindboggingly problematic in every way imagineable, so NAT is a problem but NAT is definitely not your only problem with VoIP.
(I consider VoIP hugely impressive for turning what literally was "connect two wires, polarity doesn't really matter" with a debugging experience of "if you don't hear the tone, the wire is broken" and a reliability of "it works" into "well you need a fully-loaded computer connected to the internet running an insane software stack with more compatibility hacks than your unsightly mother" with a debugging experience of "well f---" and a reliability of "I'm just going to use my cellphone, whose battery life is literally less than one day")
NAT prevented the deployment of SCTP, which was envisioned to be a better TCP, just to name one example. And stopped countless protocol ideas from getting off the drawing board.
The specifications we're dealing with here don't (and in modern protocols, this is quite deliberate) allow for any middleboxes. The only, minimal way to implement such a thing correctly in the face of that situation is to act as a full proxy, which is going to _suck_ for performance and your customers aren't going to pay for a product that throttles their connectivity badly nor for the hardware that would let you run a line speed proxy.
So, they don't, they try to make an end run around the protocol compliance, typically the idea goes something like this:
During connection setup we'll inspect everything and implement whatever rules are key to our product, but mostly we'll pass things between the real client and server transparently, only intervening as necessary for our role
Then, we can "whitelist" most connections, and let them continue at line speed without actually being inspected further.
Unlike a full proxy this design breaks, messily, when optional protocol features are understood by the client and server but not the middlebox. This is because either the middlebox pretends to understand when it doens't (so client and server seem to get their mutually agreed new feature, but if it has any impact on how the protocol is used it breaks mysteriously since the middlebox didn't know) or the middlebox squashes everything it doesn't understand then steps out of the way and expects that to work out OK even though the client and server now misunderstand each other's situation.