Subject: [Masque] Comments on draft-age-masque-connect-ip-01

From: Eric Rescorla <[email-masked]>
Date: Sun, 7 Nov 2021 15:12:08 -0800

This document seems like a reasonable starting point. Good to see
the authors converging. Some technical comments below.

Overall, I wonder if we should actually forbid the client from
using IP addresses in packets when the target is specified.
That would avoid goofy situations in which the client does

   CONNECT 192.0.2.1

And then sends to 192.0.2.2.

S 4.1.

   target:  The variable "target" contains a hostname or IP address of a
      specific host to which the client wants to proxy packets.  If the
      "target" variable is not specified, the client is requesting to
      communicate with any allowable host.  If the target is an IP
      address, the request will only support a single IP version.  If
      the target is a hostname, the server is expected to perform DNS
      resolution to determine which route(s) to advertise to the client.
      The server SHOULD send a ROUTE_ADVERTISEMENT capsule that includes
      routes for all usable resolved addresses for the requested
      hostname.

This treatment of DNS names seems like it's going to create a lot of
additional complexity: for instance, how does the client know which IP
to put in the dst field. You don't specify that the
ROUTE_ADVERTISEMENT MUST *only* include valid addresses. For instance,
suppose that the DNS name resolves to

  192.0.2.1
  192.0.2.2
  192.0.2.4 <-- No 192.0.2.3!
  192.0.2.5
  192.0.2.6
  192.0.2.7

and the server advertises 192.0.2.1-192.0.2.7.

Given that this is an IP layer mechanism, I would simply remove the
DNS option; clients can always do DNS over the tunnel.

S 4.2.
Is the server required to send ADDRESS_ASSIGN? If not, what is the
client supposed to use as it's source address? Also, what happens
if you only get a v6 address but need to talk to a v4 endpoint,
or vice versa.

S 4.2.3.
You should probably say something here about how in many cases
you shouldn't trust a ROUTE_ADVERTISEMENT. For instance, it's
incoherent for an ordinary consumer VPN client to start
advertising routes.

---

From: Tommy Pauly <[email-masked]>
Date: Mon, 08 Nov 2021 07:51:58 -0800

> On Nov 7, 2021, at 3:12 PM, Eric Rescorla <[email-masked]> wrote:
> 

Thanks for the comments!
> And then sends to 192.0.2.2.

I think it’s more consistent to define the behavior of what error the sender receives when it sends a packet for which it didn’t have an assigned source address or a valid destination route. Is this cause for dropping the packet silently, sending an error capsule, or closing the request stream with an error?

I filed this to discuss: https://github.com/tfpauly/draft-age-masque-connect-ip/issues/43 <https://github.com/tfpauly/draft-age-masque-connect-ip/issues/43>
> DNS option; clients can always do DNS over the tunnel.

I can see this either way.

For cases where I don’t want a full tunnel, but just want to talk to one host, I would need to open an IP flow for a DNS server. I could of course open one, and then open a proxied flow to each target address, and request the same local address I got on the first.

This would work, but is more back-and-forth, and also doesn’t give me a way to just ask the proxy to use it’s own DNS cache. For cases like CONNECT and CONNECT-UDP, we’ve found it very useful for latency to have the DNS cache run on the proxy, so that we benefit from all clients going through the proxy sharing the same cache, and not needing a round trip back to the client. To that end, I’d like to at least allow connecting by a hostname in the protocol (even if some proxies wouldn’t choose to support that).

> if you only get a v6 address but need to talk to a v4 endpoint,

https://github.com/tfpauly/draft-age-masque-connect-ip/issues/42 <https://github.com/tfpauly/draft-age-masque-connect-ip/issues/42>

Probably the best thing to say is that any peer that can send packets MUST first have received an ADDRESS_ASSIGN capsule.

Regarding v4 and v6, yes, you do need the right family assigned.

> incoherent for an ordinary consumer VPN client to start

A full-tunnel VPN server may not have a complex routing table, but it’s still possible to have some “excluded” routes that won’t be allowed (private subnets, etc). Traditionally, most VPN protocols do always include the route information. The “trust” here is just about what the endpoint is willing to route/forward.

What kind of warning were you imagining?

Best,
Tommy

> 
> 
> 
> 
> -- 
> Masque mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/masque

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 8 Nov 2021 08:43:33 -0800

On Mon, Nov 8, 2021 at 7:52 AM Tommy Pauly <[email-masked]> wrote:

> I think it’s more consistent to define the behavior of what error the
> sender receives when it sends a packet for which it didn’t have an assigned
> source address or a valid destination route. Is this cause for dropping the
> packet silently, sending an error capsule, or closing the request stream
> with an error?
>
> I filed this to discuss:
> https://github.com/tfpauly/draft-age-masque-connect-ip/issues/43
>

I could live with that, though I do like to make it impossible to do bad
things.

> For cases where I don’t want a full tunnel, but just want to talk to one
> host, I would need to open an IP flow for a DNS server. I could of course
> open one, and then open a proxied flow to each target address, and request
> the same local address I got on the first.
>
> This would work, but is more back-and-forth, and also doesn’t give me a
> way to just ask the proxy to use it’s own DNS cache. For cases like CONNECT
> and CONNECT-UDP, we’ve found it very useful for latency to have the DNS
> cache run on the proxy, so that we benefit from all clients going through
> the proxy sharing the same cache, and not needing a round trip back to the
> client. To that end, I’d like to at least *allow* connecting by a
> hostname in the protocol (even if some proxies wouldn’t choose to support
> that).
>

I would make several points here.

First, while it's desirable to be able to use the proxy's DNS cache, it's
increasingly insufficient to simply get the A/AAAA records, for reasons
such as SVCB. For instance, you wouldn't be able to do ECH using the DNS
version alone because you would need to look up the SVCB. So, while it does
incur a round trip, it seems like you are going to need to do a DNS
resolution for this case.

Second, even taken on its own terms, if I understand this mechanism
correctly, I think it's still broken for the reason I mentioned above. The
problem is that you are using the ROUTE_ADVERTISEMENT as an implicit DNS
resolution--to tell you what to put in the dst-addr. If that's true, then I
think you need to require that the ROUTE_ADVERTISEMENT to be strict.

> https://github.com/tfpauly/draft-age-masque-connect-ip/issues/42
>
> Probably the best thing to say is that any peer that can send packets MUST
> first have received an ADDRESS_ASSIGN capsule.
>
> A full-tunnel VPN server may not have a complex routing table, but it’s
> still possible to have some “excluded” routes that won’t be allowed
> (private subnets, etc). Traditionally, most VPN protocols do always include
> the route information. The “trust” here is just about what the endpoint is
> willing to route/forward.
>

"Note: peers MUST NOT blindly trust ROUTE_ADVERTISEMENT. They MUST filter
it through local policy"

-Ekr

---

From: Tommy Pauly <[email-masked]>
Date: Mon, 08 Nov 2021 10:03:45 -0800

> On Nov 8, 2021, at 8:43 AM, Eric Rescorla <[email-masked]> wrote:
> 
> 
> 
> On Mon, Nov 8, 2021 at 7:52 AM Tommy Pauly <[email-masked] <mailto:[email-masked]>> wrote:
> 
> 
>> On Nov 7, 2021, at 3:12 PM, Eric Rescorla <[email-masked] <mailto:[email-masked]>> wrote:
>> 
> I could live with that, though I do like to make it impossible to do bad things.

Okay, let’s discuss on the issue.
> First, while it's desirable to be able to use the proxy's DNS cache, it's increasingly insufficient to simply get the A/AAAA records, for reasons such as SVCB. For instance, you wouldn't be able to do ECH using the DNS version alone because you would need to look up the SVCB. So, while it does incur a round trip, it seems like you are going to need to do a DNS resolution for this case.

Yes, ECH does require doing a DNS lookup, but (a) ECH may not be applicable to the type of connection I’m doing with CONNECT-IP and (b) the records for A / AAAA / HTTPS / SVCB may have different TTLs and thus have different caching benefits.

> 
> Second, even taken on its own terms, if I understand this mechanism correctly, I think it's still broken for the reason I mentioned above. The problem is that you are using the ROUTE_ADVERTISEMENT as an implicit DNS resolution--to tell you what to put in the dst-addr. If that's true, then I think you need to require that the ROUTE_ADVERTISEMENT to be strict.

Yes, I agree that the route advertisement needs to be strict if this is allowed.
> "Note: peers MUST NOT blindly trust ROUTE_ADVERTISEMENT. They MUST filter it through local policy"

Hm, OK. What would “local policy” be here? I guess in the case of personal VPN, my client may expect a full tunnel, but if the server tells me I can’t route to a specific subnet (maybe it doesn’t allow 10.0.0/24, reasonably), my only recourse would be to fail the connection, not to try to send to addresses that are disallowed.

Tommy

> 
> -Ekr
> 
> 
> Best,
> Tommy
> 
>> 
>> 
>> 
>> 
>> -- 
>> Masque mailing list
>> [email-masked] <mailto:[email-masked]>
>> https://www.ietf.org/mailman/listinfo/masque <https://www.ietf.org/mailman/listinfo/masque>
> 
> -- 
> Masque mailing list
> [email-masked] <mailto:[email-masked]>
> https://www.ietf.org/mailman/listinfo/masque <https://www.ietf.org/mailman/listinfo/masque>

---

From: David Schinazi <[email-masked]>
Date: Mon, 8 Nov 2021 10:08:24 -0800

If I may jump in, Tommy I think you misunderstood EKR's point. EKR is
saying that in the common consumer VPN scenario it doesn't make sense for
the CLIENT to send routes to the SERVER. I think we can resolve EKR's
concern by taking this text from draft-cms-masque-connect-ip and copying it
to draft-age-masque-connect-ip:

   In theory, endpoints could use ROUTE_ADVERTISEMENT capsules to divert
   traffic from naive endpoints.  To avoid this, receivers of
   ROUTE_ADVERTISEMENT capsules MUST check their local policy before
   acting on such capsules, see Section 5.

https://datatracker.ietf.org/doc/html/draft-cms-masque-connect-ip-01#section-8

On Mon, Nov 8, 2021 at 10:04 AM Tommy Pauly <tpauly=
[email-masked]> wrote:

> Yes, ECH does require doing a DNS lookup, but (a) ECH may not be
> applicable to the type of connection I’m doing with CONNECT-IP and (b) the
> records for A / AAAA / HTTPS / SVCB may have different TTLs and thus have
> different caching benefits.
>
>
>> Probably the best thing to say is that any peer that can send packets
>> MUST first have received an ADDRESS_ASSIGN capsule.
>>
> Hm, OK. What would “local policy” be here? I guess in the case of personal
> VPN, my client may expect a full tunnel, but if the server tells me I can’t
> route to a specific subnet (maybe it doesn’t allow 10.0.0/24, reasonably),
> my only recourse would be to fail the connection, not to try to send to
> addresses that are disallowed.
>
> Tommy
>
>
> -Ekr
>
>
>> Best,
>> Tommy
>>
>>
>>
>>
>>
>> --
>> Masque mailing list
>> [email-masked]

---

From: Ben Schwartz <[email-masked]>
Date: Mon, 8 Nov 2021 13:25:57 -0500

On Mon, Nov 8, 2021 at 10:52 AM Tommy Pauly <tpauly=
[email-masked]> wrote:

> ...

> way to just ask the proxy to use it’s own DNS cache.
>

I think we need to be clear about what the alternatives are.  Suppose we
compare

A. CONNECT-IP supports DNS names. [current draft]
B. CONNECT-IP doesn't support hostnames but is co-located with a DoH server.

Then either way, the client benefits from a DNS cache at the proxy.

> For cases like CONNECT and CONNECT-UDP, we’ve found it very useful for
> latency to have the DNS cache run on the proxy, so that we benefit from all
> clients going through the proxy sharing the same cache, and not needing a
> round trip back to the client.
>

That benefit does not apply to CONNECT-IP, because the client must specify
an IP address, but it doesn't know what IP address to specify.  It
therefore has to wait the same full roundtrip anyway.  Compare

A.
 - [C->S] CONNECT-IP https://proxy.example/ip?target_host=target.example.com
 - [S->C] 200 OK, ROUTE_ADVERTISEMENT [192.0.2.1]
 - [C->S] IP Packet to 192.0.2.1

B.
 - [C->S] GET https://proxy.example/dns-query?dns=<target.example.com>
 - [S->C] 200 OK, <DNS Answer: 192.0.2.1>
 - [C->S] CONNECT-IP https://proxy.example/ip?target_host=192.0.2.1
 - [C->S] IP Packet to 192.0.2.1 (False Start)

CONNECT (TCP) and CONNECT-UDP are different.  TCP allows the server to act
on the resolved address without having to return it to the client.
CONNECT-UDP allows false-start with hostname targets (although CONNECT-UDP
with hostname targets is pretty crummy: it breaks failover, Happy Eyeballs,
etc.).

To that end, I’d like to at least *allow* connecting by a hostname in the
> protocol

I don't object to this functionality, but I don't think it is a performance
optimization.

> (even if some proxies wouldn’t choose to support that).
>

I don't think it can be optional.  If it's optional, it might as well not
be mentioned at all, since clients can't rely on it.

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 8 Nov 2021 10:31:28 -0800

> to draft-age-masque-connect-ip:

Yes, this is what I meant.

> https://datatracker.ietf.org/doc/html/draft-cms-masque-connect-ip-01#section-8

This seems reasonable.

-Ekr

>> Hm, OK. What would “local policy” be here? I guess in the case of
>> personal VPN, my client may expect a full tunnel, but if the server tells
>> me I can’t route to a specific subnet (maybe it doesn’t allow 10.0.0/24,
>> reasonably), my only recourse would be to fail the connection, not to try
>> to send to addresses that are disallowed.
>>
>> Tommy
>>
>>
>> -Ekr
>>
>>
>>> Best,
>>> Tommy
>>>
>>>
>>>
>>>
>>>
>>> --
>>> Masque mailing list
>>> [email-masked]

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 8 Nov 2021 10:33:03 -0800

On Mon, Nov 8, 2021 at 10:26 AM Ben Schwartz <[email-masked]> wrote:

>  - [C->S] CONNECT-IP
> https://proxy.example/ip?target_host=target.example.com
Ironically, because of Issue #43. If you were allowed to have
dst_addr=0.0.0.0 or something, then this would work.

-Ekr