scionproto / scion

SCION Internet Architecture
https://www.scion-architecture.net/
Apache License 2.0
369 stars 156 forks source link

NAT support via border routers #4517

Open tzaeschke opened 1 month ago

tzaeschke commented 1 month ago

In order to get SCION to work with home routers that do NAT, we need to be able to write the NAT's external address in to the source field of the SCION header.

EDIT: One particular problem here are ASes that are split into multiple subnets such that there may be NATs between endhost and border routers, and/or not all border are in the same subnet.

There are at least two ways of doing that:

  1. update router software to be SCION aware so it can rewrite the source address or at least tell an end host what the external address is (or will be).
  2. find a way to efficiently determine the external address without changing the router software.

Changing the router software seems like are hard thing to do, even though ISP should have control over most home routers in their network.

Proposal

I propose to extends border routers to respond to a "ping" (or similar) with a packet that contains the source address that the border router sees.

Why border routers?

Details

This could, for example, be implemented using an extension to the SCMP protocol.

We introduce two new SCMP types: "132 SCMP WhoAmI Request" and "133 SCMP WhoAmI Reply". When a border router receives a request, it records the originating address remoteAddress. It then sends a reply that contains the remoteAddress back to the originator (i.e. back to remoteAddress). The reply would contain the remoteAddress as payload. To prevent traffic amplification, the request should contain an empty payload of 16+2=18 bytes (IPv6+ port).

Attacks

Alternatives to extending SCMP:

Thoughts?

marcfrei commented 1 month ago

Regarding other possible protocol choices: STUN at its core does something very similar [0]. Tailscale, e.g., uses a subset of STUN for exactly this purpose [1], [2].

[0] https://en.wikipedia.org/wiki/STUN [1] https://tailscale.com/blog/how-nat-traversal-works [2] https://pkg.go.dev/tailscale.com/net/stun

jiceatscion commented 1 month ago

Finding one's public IP is a bit of a solved problem; dozens of sites will tell you what your IP is. I am guessing some ISPs do offer an http API themselves. I have not checked if there exists a remote API of some sort for every case, but I I am a bit skeptical that we need to add every SCion router to that set.

Am I missing something

J-C

On Tue, Apr 30, 2024 at 5:18 PM Tilmann @.***> wrote:

In order to get SCION to work with home routers that do NAT, we need to be able to write the NAT's external address in to the source field of the SCION header.

There are at least two ways of doing that:

  1. update router software to be SCION aware so it can rewrite the source address or at least tell an end host what the external address is (or will be).
  2. find a way to efficiently determine the external address without changing the router software.

Changing the router software seems like are hard thing to do, even though ISP should have control over most home routers in their network. Proposal

I propose to extends border routers to respond to a "ping" (or similar) with a packet that contains the source address that the border router sees.

Why border routers?

  • Compared to home routers: border router software seems much easier to change from our side than border router software
  • Compared to control servers: border routers are the ones who truly must, and will, know the external IP/port of the NAT when the NAT speaks to them. A control server may in theory be in a different subnet.
  • Compared to other services, not local to the AS: Being in a different AS or even further away means long roundtrip time which is not desirable.

Details

This could, for example, be implemented using an extension to the SCMP protocol.

We introduce two new SCMP types: "132 SCMP WhoAmI Request" and "133 SCMP WhoAmI Reply". When a border router receives a request, it records the originating address remoteAddress. It then sends a reply that contains the remoteAddress back to the originator (i.e. back to remoteAddress ). The reply would contain the remoteAddress as payload. To prevent traffic amplification, the request should contain an empty payload of 16+2=18 bytes (IPv6+ port).

Alternatives to extending SCMP:

  • Use gRPC. This seems undesirable as it adds quite a bit of overhead.
  • Use a separate new protocol. This may be a possibility, not least because the proposed feature can probably be removed once all home routers speak SCION or once we find a different solution.
  • "Bend" the current protocol. Since we communicate in a local ISD/AS we could abuse the ISD/AS and address fields in the SCION address header for our purposes. For example, we could store the remoteAddress into the DstHostAddr field of the SCION address header. The should work but seems undesirable because it "bends" the current specification.

Thoughts?

— Reply to this email directly, view it on GitHub https://github.com/scionproto/scion/issues/4517, or unsubscribe https://github.com/notifications/unsubscribe-auth/BBLEYOFWX5OWY2A33YBOQ5DY76Y3LAVCNFSM6AAAAABHAPORTCVHI2DSMVQWIX3LMV43ASLTON2WKOZSGI3TCNZZGM3TGMA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

--

JEAN-CHRISTOPHE HUGLY

Software Engineer

+41 79 455 68 69 @. @.> scion.org http://www.scion.org/ SCION Association https://www.linkedin.com/company/scion-association/

https://www.scion.org/

tzaeschke commented 1 month ago

Regarding other possible protocol choices: STUN at its core does something very similar [0]. Tailscale, e.g., uses a subset of STUN for exactly this purpose [1], [2].

@marcfrei Thanks, I will have a look!

Finding one's public IP is a bit of a solved problem; dozens of sites will tell you what your IP is. I am guessing some ISPs do offer an http API themselves. I have not checked if there exists a remote API of some sort for every case, but I I am a bit skeptical that we need to add every SCion router to that set.

@jiceatscion I think there are several problems with existing solutions:

marcfrei commented 1 month ago

They usually do not support SCION, at least not for some time (EDIT: why would they need to support SCION?)

Exactly, I would assume NAT support to be an AS-internal, IP-only feature.

oncilla commented 1 month ago

Just to clarify, because it is not mentioned explicitly. The concern is that the NAT happens inside of a SCION AS between the end host and the internal interface of the border router, correct?

tzaeschke commented 1 month ago

Just to clarify, because it is not mentioned explicitly. The concern is that the NAT happens inside of a SCION AS between the end host and the internal interface of the border router, correct?

@oncilla Yes exactly. I'll add something to the description.

matzf commented 1 month ago

If the NAT also rewrites the UDP port, which I believe is typical for NATs, discovering the host's NATed IP as seen from the border router is not enough. We'd also need to discover the NATed port. This makes things quite awkward.

One approach can be, the border router keeps a mapping of the NATed ports. This works for both the current, "traditional" underlay with fixed end host port and dispatcher, or with port dispatching in the router and the dispatcher-less end host stack. But maintaining such a port mapping in the router is an additional processing overhead, and bound to cause trouble as the NAT's port mappings change over time with opaque and device specific rules.

Alternatively, we could rely on the underlay port dispatching by the border router, with the dispatcherless-stack (#4344). This would require the application to discover the port mapping with such a "whoami" request before sending the first packet, and then use the NATed port in the SCION/UDP source port. The border router will then send reply packets to the "correct" NATed port.

Both approaches feel rather complicated to me, and the overhead of maintaining the mapping or discovering the NATed underlay address for each new socket seems non-negligible. I think we need to weigh carefully whether support for NATs is worth the additional complexity.

marcfrei commented 1 month ago

Alternatively, we could rely on the underlay port dispatching by the border router...

Yes, assuming that the dispatched_ports range can eventually be extended to the entire port range, this would certainly be the simplest case and it would probably simplify things to focus on this scenario as a first step.

I think we need to weigh carefully whether support for NATs is worth the additional complexity.

Absolutely. Asking AS operators to deploy a standard STUN server "close" to the border router would then allow libraries like snet/pan or jpan to start supporting simple residential and mobile NAT traversal without any changes in the core SCION infrastructure services.

matzf commented 1 month ago

Discussed in today's contributors call:

1: Note that this (different routers seeing different NATed addresses) can occur even with only a single NAT on the path, if the NAT uses the full 4 tuple (source IP/ port, dest IP/port) to determine the mapping. By STUN's and Wikipedia's classification this is a "symmetric NAT".