PDA

View Full Version : [Standards] S2S and massive virtual hosting


Pedro Melo
06-04-2008, 10:21 AM
Hi,

I've been working on a massive hosting XMPP service and trying to get
my head around the operational problems that the current S2S rules
introduce. Basically, for each domain hosted (and in our case they
include services for MUC, FT, and PubSub per hosted domain), we need
8 TCP connections for bi-directional communications per pair of local-
remote domains, worst case. Even with modern kernel event TCP APIs,
it adds up.

I've worked out a small proposal that I would like to get feedback
on. It would change S2S to use a lot less TCP while keeping the
certificate-based security.

Concepts used in the text:

* XMPP domain: a domain used by a XMPP service, either for C2S or
other services like MUC, FT, and PubSub;
* XMPP host: a system of one or more servers that host XMPP domains.

Each XMPP host will have a DNS name. For example, My.ISP could have a
XMPP host named xmpp.my.isp.

Each XMPP domain hosted at My.ISP would use xmpp.my.isp in their DNS
SRV records. For example, saramago.lit would announce the following
SRV records:

_xmpp-server._tcp.saramago.lit. 600 IN SRV 5 0 5269
xmpp.my.isp.
_xmpp-server._tcp.chat.saramago.lit. 600 IN SRV 5 0 5269
xmpp.my.isp.
_xmpp-server._tcp.ft.saramago.lit. 600 IN SRV 5 0 5269
xmpp.my.isp.
_xmpp-server._tcp.pubsub.saramago.lit. 600 IN SRV 5 0 5269
xmpp.my.isp.

A XMPP domain pessoa.lit (hosted at another XMPP host named
xmpp.other.isp) also has equivalent records.

When pessoa.lit wants to communicate with saramago.lit, the following
protocol would be used:

1. pessoa.lit XMPP host, xmpp.other.isp, establishes a XMPP stream
with xmpp.my.isp. The current spec is used but the domains used in
the stream handshake would be xmpp.other.isp and xmpp.my.isp.

this first step would create a secure, authenticated and, given
proper certificates for both xmpp.my.isp and xmpp.other.isp, a
trusted connection between the two XMPP hosts. Using improvements to
the protocol discussed previously in this list, this stream could
even be a bidirectional stream over a single TCP connection.

2. XMPP host xmpp.other.isp then sends a XMPP domain stream
activation request. It generates a random key, signs it with
pessoa.lit certificate and encrypts it with saramago.lit certificate.
Then it sends this request to xmpp.my.isp.

3. XMPP host xmpp.my.isp decrypts the request and checks the
signature of the random key. If the signature matches, it signs the
key with saramago.lit certificate, and encrypts with pessoa.lit
certificate. This response is sent to XMPP host xmpp.other.isp.

4. XMPP Host xmpp.other.isp decrypts the response with pessoa.lit
certificate and checks the signature using saramago.lit certificate.
If the signature matches, the channel between saramago.lit and
pessoa.lit is deemed trusted and ready to be activated.

5. XMPP host xmpp.other.isp sends a activate stanza with both
domains. The channel is now active bi-directionally.

This process can be execute multiple times per connection between the
two XMPP hosts, supporting multiple domains in the same connection.


This protocol will radically reduce the number of TCP connections a
XMPP host will need to support multiple domains, while keeping the
certificates-based security in place. The problem is that it's not
backwards compatible. It would require a new _xmpp-federation._tcp
(just a suggestion) record. This is required because the initial
domain in the XMPP stream is not the destination XMPP domain but the
destination XMPP host name.

Best regards,
--
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: melo (AT) simplicidade (DOT) org
Use XMPP!

Philipp Hancke
06-04-2008, 11:15 AM
Hi Pedro,
[...]
> 2. XMPP host xmpp.other.isp then sends a XMPP domain stream activation
> request. It generates a random key, signs it with pessoa.lit certificate
> and encrypts it with saramago.lit certificate. Then it sends this
> request to xmpp.my.isp.

You have a valid certificate and private keys for all of the domains
you're hosting?

The request includes the pessoa.lit certificate? If not, how does
saramago.lit obtain the certificate to check the signature in step 3?

'random' keys are usually bad (replay attacks). The key should be - in
part - based on a challenge by xmpp.my.isp. Which makes this quite
similar to how dialback keys are generated... if you replace the key
validation part (4.3/4.4 in xep 220) with crypto instead of DNS mojo.

philipp

Pedro Melo
06-04-2008, 11:35 AM
On Jun 4, 2008, at 10:14 AM, Philipp Hancke wrote:

> Hi Pedro,
> [...]
>> 2. XMPP host xmpp.other.isp then sends a XMPP domain stream
>> activation request. It generates a random key, signs it with
>> pessoa.lit certificate and encrypts it with saramago.lit
>> certificate. Then it sends this request to xmpp.my.isp.
>
> You have a valid certificate and private keys for all of the domains
> you're hosting?

Yes, I have to if I want to host them. Same thing if you are a HTTPS
hosting company.

I don't know how you can reduce the number of certificates and keep
the same security properties of the protocol.


> The request includes the pessoa.lit certificate? If not, how does
> saramago.lit obtain the certificate to check the signature in step 3?

How does it work today? The certificate could be included in the
request or a out-of-band method could be used to obtain it. The
security is not based on how you get the other party certificate but
on the CA that signed it, right?

In the PGP/GPG world there are key servers. In the X.509 is there
anything similar? OCSP allows you to check the status of a
certificate but I don't know if it can be used to find them.


> 'random' keys are usually bad (replay attacks). The key should be - in
> part - based on a challenge by xmpp.my.isp. Which makes this quite
> similar to how dialback keys are generated... if you replace the key
> validation part (4.3/4.4 in xep 220) with crypto instead of DNS mojo.

That is the idea, maybe I was not clear. The current challenge in a
dialback scenario is also random, right? The point is that the
initiator chooses some key/string and uses that in the process.

One of the reasons I send this here, is that my knowledge of
certificates and X.509 is limited. I understand the concepts of pki
but I don't have a lot of knowledge about X.509. So it might show a
bit in the proposal. Thanks for any corrections.

Best regards,
--
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: melo (AT) simplicidade (DOT) org
Use XMPP!

Philipp Hancke
06-04-2008, 12:07 PM
Pedro Melo wrote:
[...]
>> You have a valid certificate and private keys for all of the domains
>> you're hosting?
>
> Yes, I have to if I want to host them. Same thing if you are a HTTPS
> hosting company.

I know some people who will have a problem with that. Well... they will
probably continue to use _one_ certificate for all domains and
rely on no one caring about proper tls usage :-)

> I don't know how you can reduce the number of certificates and keep the
> same security properties of the protocol.
>
>
>> The request includes the pessoa.lit certificate? If not, how does
>> saramago.lit obtain the certificate to check the signature in step 3?
>
> How does it work today? The certificate could be included in the request
> or a out-of-band method could be used to obtain it. The security is not
> based on how you get the other party certificate but on the CA that
> signed it, right?

Yes. Which is why you can include the certificate in the request.

[...]
>> 'random' keys are usually bad (replay attacks). The key should be - in
>> part - based on a challenge by xmpp.my.isp. Which makes this quite
>> similar to how dialback keys are generated... if you replace the key
>> validation part (4.3/4.4 in xep 220) with crypto instead of DNS mojo.
>
> That is the idea, maybe I was not clear. The current challenge in a

It was clear. I just think it can be solved in a more backward
compatible way.

> dialback scenario is also random, right? The point is that the initiator
> chooses some key/string and uses that in the process.

In dialback, the challenge is the stream id sent by the receiving
server in example 2. The point is that it is not chosen by the
originating server.

In example 4 (xep-220), you would generate the 'key' as

{ 'saramago.lit', ' ', 'pessoa.lit', ' ', 'therandomchallenge'}

and then sign the resulting string with the pessoa.lit certificate.

Then you send a (modified) dialback over the connection:
<db:result from='pessoa.lit' to='saramago.lit'>
somemarker;base-64-signature;base64-certificate-of-saramago
</db:result>

If the remote server understands the crypto protocol and recognizes
the marker, it can reconstruct the message, verify the signature and
send the result (ex. 11).

If the remote server does not understand the crypto protocol, it
will treat the key as an opaque string and try to verify it using
dialback.

philipp

Pedro Melo
06-04-2008, 01:02 PM
On Jun 4, 2008, at 11:06 AM, Philipp Hancke wrote:

> Pedro Melo wrote:
> [...]
>>> You have a valid certificate and private keys for all of the domains
>>> you're hosting?
>> Yes, I have to if I want to host them. Same thing if you are a
>> HTTPS hosting company.
>
> I know some people who will have a problem with that. Well... they
> will
> probably continue to use _one_ certificate for all domains and
> rely on no one caring about proper tls usage :-)

They can do that, but they shouldn't be surprised if sometime in the
future other servers stop talking to them.

Anyway, using a single certificate for all domains does not change
the protocol, but the verification of the certificate will fail on
the other side. What the other side does with the failure is a local
policy issue.


>> I don't know how you can reduce the number of certificates and
>> keep the same security properties of the protocol.
>>> The request includes the pessoa.lit certificate? If not, how does
>>> saramago.lit obtain the certificate to check the signature in
>>> step 3?
>> How does it work today? The certificate could be included in the
>> request or a out-of-band method could be used to obtain it. The
>> security is not based on how you get the other party certificate
>> but on the CA that signed it, right?
>
> Yes. Which is why you can include the certificate in the request.

Can or should?


> [...]
>>> 'random' keys are usually bad (replay attacks). The key should be
>>> - in
>>> part - based on a challenge by xmpp.my.isp. Which makes this quite
>>> similar to how dialback keys are generated... if you replace the key
>>> validation part (4.3/4.4 in xep 220) with crypto instead of DNS
>>> mojo.
>> That is the idea, maybe I was not clear. The current challenge in a
>
> It was clear. I just think it can be solved in a more backward
> compatible way.

Maybe I'm missing something obvious, but given that the stream needs
to be setup for the XMPP host and not the XMPP domain, I don't see
how we can be backwards compatible.


>> dialback scenario is also random, right? The point is that the
>> initiator chooses some key/string and uses that in the process.
>
> In dialback, the challenge is the stream id sent by the receiving
> server in example 2. The point is that it is not chosen by the
> originating server.

yes, thats right. Yes, we could use that.


> In example 4 (xep-220), you would generate the 'key' as
>
> { 'saramago.lit', ' ', 'pessoa.lit', ' ', 'therandomchallenge'}
>
> and then sign the resulting string with the pessoa.lit certificate.
>
> Then you send a (modified) dialback over the connection:
> <db:result from='pessoa.lit' to='saramago.lit'>
> somemarker;base-64-signature;base64-certificate-of-saramago
> </db:result>
>
> If the remote server understands the crypto protocol and recognizes
> the marker, it can reconstruct the message, verify the signature and
> send the result (ex. 11).
>
> If the remote server does not understand the crypto protocol, it
> will treat the key as an opaque string and try to verify it using
> dialback.

Nice. But the initial stream still needs to be addressed to the XMPP
host name and not the XMPP domain. And you have to do that before
receiving the <features> from the remote domain. And this is not
compatible with the current system.

An alternative, we could also initiate the session as usual, from
pessoa.lit to saramago.lit, and announce this S2S multiplexing
feature, and it accepted, start the TLS handshake with the XMPP host
name. This would make it easier to deploy... Using this stream
feature, we can fallback to current s2s cleanly.

Best regards,
--
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: melo (AT) simplicidade (DOT) org
Use XMPP!

Peter Saint-Andre
06-04-2008, 05:49 PM
On 06/04/2008 5:01 AM, Pedro Melo wrote:
>
> On Jun 4, 2008, at 11:06 AM, Philipp Hancke wrote:
>
>> In example 4 (xep-220), you would generate the 'key' as
>>
>> { 'saramago.lit', ' ', 'pessoa.lit', ' ', 'therandomchallenge'}
>>
>> and then sign the resulting string with the pessoa.lit certificate.
>>
>> Then you send a (modified) dialback over the connection:
>> <db:result from='pessoa.lit' to='saramago.lit'>
>> somemarker;base-64-signature;base64-certificate-of-saramago
>> </db:result>
>>
>> If the remote server understands the crypto protocol and recognizes
>> the marker, it can reconstruct the message, verify the signature and
>> send the result (ex. 11).
>>
>> If the remote server does not understand the crypto protocol, it
>> will treat the key as an opaque string and try to verify it using
>> dialback.

It's a good thing that we moved dialback out of rfc3920bis. :)

> Nice. But the initial stream still needs to be addressed to the XMPP
> host name and not the XMPP domain. And you have to do that before
> receiving the <features> from the remote domain. And this is not
> compatible with the current system.
>
> An alternative, we could also initiate the session as usual, from
> pessoa.lit to saramago.lit, and announce this S2S multiplexing feature,
> and it accepted, start the TLS handshake with the XMPP host name. This
> would make it easier to deploy... Using this stream feature, we can
> fallback to current s2s cleanly.

Graceful fallback is a good thing, so if there is any way we can
preserve it, I'm all in favor.

Peter

--
Peter Saint-Andre
https://stpeter.im/