Subject: [TLS] TLS-in-TLS tunneling use cases (was: SNI Encryption)

From: Tony Arcieri <[email-masked]>
Date: Wed, 9 Aug 2017 22:54:46 -0700

As I look at draft-huitema-tls-sni-encryption[1], I really think it's
putting the cart before the horse. I really like the proposed TLS-in-TLS
tunneling mechanism, but I feel it is a generally useful mechanism, and
this draft relegates it to providing a point solution specifically for the
purposes of SNI encryption and considering only that use case.

One of the things I like the most about TLS 1.3 is how it has harmonized
the sort of chunky stew of ill-conceived features found in previous TLS
versions (with nebulous and overlapping responsibilities) into a smaller
set of clearly-defined parsimonious ones which cover a wide range of use
cases.

In considering the general problem of "SNI encryption", and particularly
within the context of TLS-in-TLS tunneling solution, I humbly ask that
other use cases which would benefit from a TLS-in-TLS tunneling mechanism
are considered. I think any draft about this should have TLS-in-TLS
tunneling itself as the centerpiece, and "SNI encryption" off to the side
as one potential use case.

So, what other use cases are worth considering? Egress proxies!

Consider: a gateway server acting as an external proxy which bridges an
internal network with the Internet, acting as a forward proxy to
authenticated clients (either human-driven apps/tools or backend services).

What I think is particularly interesting about this use case in the context
of the SNI encryption discussion is it is in fact almost entirely the same
problem from a technical perspective. Where it differs is largely in the
framing of the problem: instead of using the gateway to reach a hidden host
from the Internet, we are using the gateway to talk to the Internet from an
internal network which needs to go through a proxy host to reach the
Internet.

More tangibly, I would like the following as the administrator of an
internal network:

- All outbound traffic flows through centrally managed gateway hosts which
act as TCP proxies. Outbound connections to the Internet are otherwise NOT
allowed

- As we're fans of actually using TLS to provide end-to-end transport
security and not "SSL added and removed here ;-)", we want the resulting
connection to be encrypted end-to-end between the internal network TLS
client and the requested destination server. Also, all "setup"
communication to the gateway should also happen over TLS

- The gateway authenticates clients (using e.g. a TLS client certificate)
and authorizes the outbound hostnames against an ACL. This way we can
control which clients are allowed to reach which external endpoints.

There are a few additional things which are different between the cases
beyond some of what I've just mentioned. Ideally the client verifies the
gateway's server cert against an internal-only CA bundle, then verifies the
tunneled destination host against a public CA bundle. We might want a
client to present an internal client certificate to the gateway, but
present no cert/a different cert to the destination host. That said, aside
from minutia like that, the machinery seems largely the same.

What are the real-world "rough consensus and running code" solutions to
this sort of problem in place today? There are all sorts of options that
are sort-of-not-quite like what I just described, e.g. a SOCKS proxy. But
the one I'm thinking of as I write this is CONNECT tunnels:

https://wiki.squid-cache.org/Features/HTTPS

These sorts of tunnels (ab)use a HTTP(S) forward-proxy to establish
outbound TCP connections (which, if you care about security, will carry TLS
encrypted traffic).

This approach is partly described in RFC 2817[2], but to tick all of the
checkboxes on the points I mentioned earlier using this method, you need to
implement features in draft-luotonen-web-proxy-tunneling-01[3], which has
never received an RFC and, as far as I can tell, is only properly
implemented by Squid. Using Squid as a TLS-in-TLS tunneling solution seems
less than ideal to me, and yet in many ways it seems like the "least
friction" option, especially for access control purposes.

I would really love a simple, straightforward approach to this problem with
a published RFC instead of an expired draft that's only implemented by
Squid. I also think TLS-in-TLS tunneling can solve this same problem in a
much more straightforward manner.

tl;dr: when making drafts regarding TLS-in-TLS tunneling, please consider
the forward-proxy use case in addition to the reverse-proxy case

[1]: https://datatracker.ietf.org/doc/draft-huitema-tls-sni-encryption/
[2]: https://www.rfc-editor.org/rfc/rfc2817.txt
[3]: https://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01

-- 
Tony Arcieri

---

From: Martin Thomson <[email-masked]>
Date: Thu, 10 Aug 2017 19:23:52 +1000

I'm trying to work out whether there is anything new here.  I know
that browsers implement proxying over HTTPS and CONNECT.  Can you
summarize the ask more succinctly?  Because I'm thinking that this is
a solved problem.

See Section 8.3 of RFC 7540.  We didn't put that there for a lark.

On 10 August 2017 at 15:54, Tony Arcieri <[email-masked]> wrote:
> tunneling mechanism, but I feel it is a generally useful mechanism, and this
> draft relegates it to providing a point solution specifically for the
> One of the things I like the most about TLS 1.3 is how it has harmonized the
> sort of chunky stew of ill-conceived features found in previous TLS versions
> (with nebulous and overlapping responsibilities) into a smaller set of
> clearly-defined parsimonious ones which cover a wide range of use cases.
>
> within the context of TLS-in-TLS tunneling solution, I humbly ask that other
> use cases which would benefit from a TLS-in-TLS tunneling mechanism are
> considered. I think any draft about this should have TLS-in-TLS tunneling
> itself as the centerpiece, and "SNI encryption" off to the side as one
> potential use case.
>
> client and the requested destination server. Also, all "setup" communication
> to the gateway should also happen over TLS
>
> tunneled destination host against a public CA bundle. We might want a client
> to present an internal client certificate to the gateway, but present no
> cert/a different cert to the destination host. That said, aside from minutia
> like that, the machinery seems largely the same.
>
> What are the real-world "rough consensus and running code" solutions to this
> sort of problem in place today? There are all sorts of options that are
> sort-of-not-quite like what I just described, e.g. a SOCKS proxy. But the
> one I'm thinking of as I write this is CONNECT tunnels:
>
> These sorts of tunnels (ab)use a HTTP(S) forward-proxy to establish outbound
> TCP connections (which, if you care about security, will carry TLS encrypted
> traffic).
>
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Tony Arcieri <[email-masked]>
Date: Thu, 10 Aug 2017 07:03:42 -0700

> See Section 8.3 of RFC 7540.  We didn't put that there for a lark.

Backing up a bit: my personal primary use cases are services running on a
network trying to speak outbound. Yes it's great browsers have support, but
what about anything else that wants to make an outbound TLS connection to
the Internet?

Trying to solve this problem with HTTP, rather than the TLS, forces every
single network client library on earth that wants to talk through these
proxies to implement both CONNECT and enough HTTP to speak to the proxy and
request CONNECT.

Do you really think (ab)using an HTTP proxy this way is a good idea? I
don't. I also don't think it's been particularly successful:

- We've wound up with a server-side ecosystem where, as far as I can tell,
Squid is the only service which implements all the features needed to
provide an HTTPS-authenticated outbound CONNECT gateway with
client-by-client ACLs

- Support is not as ubiquitous as you may think. For example Go's net/http
library does not support CONNECT through an HTTPS proxy:
https://github.com/golang/go/issues/11332

Solving this problem with TLS instead of HTTPS could result in a solution
where once it's implemented in a TLS library, any clients using that TLS
library could take advantage of it, rather than each client having to
implement CONNECT themselves.

I say this all as someone looking at rolling out Squid for this purpose as
we speak, and having worked places who have run Squid this way in the past.
CONNECT is widely supported enough to mostly make this work, but I think
things could be... much better than they are.

-- 
Tony Arcieri

---

From: Martin Thomson <[email-masked]>
Date: Fri, 11 Aug 2017 12:07:52 +1000

So you want CONNECT for TLS?  You could have said that.

What makes you think that the implementation story here would be any
different?  I'm not trying to destroy your idea, which seems fine on
face value, but just trying to understanding the value proposition
better.

---

From: Tony Arcieri <[email-masked]>
Date: Thu, 10 Aug 2017 22:40:49 -0700

> face value, but just trying to understanding the value proposition

As I said earlier, the implementation story is the same (or extremely
similar), but it's looking at the problem from a different perspective:

> internal network which needs to go through a proxy host to reach the

I did also list a few things I think are tangibly different:

> from minutia like that, the machinery seems largely the same.

Support for using different CA bundles for the gateway versus the
destination host seems important in this use case, IMO.
Also: support for sending different certs to the gateway versus the
destination host.

While these are ultimately just implementation details, I think they're
worth at least considering when such a draft is being authored.

-- 
Tony Arcieri

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Fri, 18 Aug 2017 18:46:13 -0400

> control which clients are allowed to reach which external endpoints.

While i think i understand where you're coming from, Tony, i can't help
but note that this use case is difficult to distinguish from a regime
that:

 (a) wants to forbid anonymous speech, and

 (b) wants to censor "unapproved" information sources, and

 (c) wants the capacity to undermine freedom of association.

That makes me wary, and i hope that SNI Encryption is *not* conflated
with these particular use cases.

In particular, the requirement of user identification/authentication in
combination with a heavily constrained network seems problematic.  I
don't think that we should design SNI encryption with an intent to
facilitate this scenario.

           --dkg

---

From: Ilari Liusvaara <[email-masked]>
Date: Sat, 19 Aug 2017 19:20:05 +0300

> friction" option, especially for access control purposes.

As far as I can see, draft-luotonen-web-proxy-tunneling-01 doesn't
really bring anything new on top of RFC 2817 (and in fact, is older
than the RFC).

Neither seemingly describes TLS-in-TLS (SSL-in-SSL) tunnels. But those
are a straightforward extension of the normal HTTP tunneling mechanism.
Including cases where trustpiles for inner and outer connections are
different and where client certificates are different.

However, some non-TLS protocols will not work over HTTPS CONNECT,
unless both client and proxy break TLS semantics (specifically the
behavior of close_notify alert).

In terms of complexity, as far as I can see, the complexity of minimal
implementation of HTTPS tunneling is comparable to dedicated TLS layer
method. HTTPS tunneling does double-encrypt, but eliminating that
double encryption is nontrivial (at least for analysis).

One annoyance in HTTPS tunneling is that the hostname can be duplicated
in three places:

1) The CONNECT target (this is actual place to connect to).
2) The host header (this is supposed to be absent in HTTP/1.0, and MAY
   be blank in HTTP/1.1).
3) The SNI in TLS handshake (in plaintext, can be extracted).

-Ilari

---

From: Tony Arcieri <[email-masked]>
Date: Tue, 29 Aug 2017 23:19:06 -0700

> with these particular use cases.

TLS tunnels have a multitude of use cases, from SNI encryption to service
discovery-aware load balancers to Tor-like anonymity networks to
privacy-preserving payment channel networks to my much more mundane
"Squid-like authenticated egress proxy" problem.

I'm simply asking that if tunnels become the mechanism by which SNI
encryption is ultimately implemented, that all of the potential use cases
of tunnels are considered, rather than observing the problem through the
microcosm that is "SNI Encryption".

Note that I'm proposing absolutely nothing new, just asking that the
tunneling problem be considered from more angles than one. If TLS contains
(mis)features which forbid anonymous speech or censor unapproved
information sources, I'm afraid that the ship has already sailed there. But
perhaps, well-implemented TLS tunnels could ultimately help route around
censorship.

-- 
Tony Arcieri