mirror of
https://github.com/moparisthebest/xeps
synced 2024-11-10 11:25:00 -05:00
349 lines
15 KiB
XML
349 lines
15 KiB
XML
<?xml version='1.0' encoding='UTF-8'?>
|
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
|
<!ENTITY % ents SYSTEM 'xep.ent'>
|
|
%ents;
|
|
]>
|
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
|
<xep>
|
|
<header>
|
|
<title>Stanza Multiplexing</title>
|
|
<abstract>
|
|
This spec provides a mechanism for multiplexing multiple virtual hosts over
|
|
a single XMPP session.
|
|
</abstract>
|
|
&LEGALNOTICE;
|
|
<number>0451</number>
|
|
<status>Experimental</status>
|
|
<type>Standards Track</type>
|
|
<sig>Standards</sig>
|
|
<approver>Council</approver>
|
|
<dependencies>
|
|
<spec>XMPP Core</spec>
|
|
</dependencies>
|
|
<supersedes>
|
|
<spec>XEP-0220</spec>
|
|
</supersedes>
|
|
<supersededby/>
|
|
<shortname>mux</shortname>
|
|
&sam;
|
|
<revision>
|
|
<version>0.1.0</version>
|
|
<date>2021-01-19</date>
|
|
<initials>XEP Editor (jsc)</initials>
|
|
<remark>Accepted by vote of Council on 2020-12-09.</remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.0.1</version>
|
|
<date>2020-12-03</date>
|
|
<initials>ssw</initials>
|
|
<remark><p>First draft.</p></remark>
|
|
</revision>
|
|
</header>
|
|
<section1 topic='Introduction' anchor='intro'>
|
|
<p>
|
|
The ability to multiplex multiple virtual hosts over a single XMPP session
|
|
(historically known as "piggybacking") was originally defined in &rfc3920;
|
|
and later pulled out into &xep0220; for use with &rfc6120;.
|
|
With the advent of cheap or free TLS certificates the use of dialback
|
|
began falling off on the public XMPP network as more secure authentication
|
|
mechanisms such as SASL EXTERNAL began to become more common.
|
|
However, multiplexing is still a useful technique in constrained
|
|
environments regardless of the authentication mechanism being used.
|
|
</p>
|
|
<p>
|
|
Multiplexing is also useful for reusing connections for additional
|
|
services associated with a domain but hosted at a subdomain.
|
|
For example, both the "montague.example" and the "capulet.example" may be
|
|
hosted by the same XMPP server which may also host &xep0369; services at
|
|
"chat.montague.example" and "rooms.capulet.example" respectively.
|
|
Without multiplexing this would require eight TCP connections for a
|
|
bidirectional exchange of stanzas between two sending domains and two
|
|
target domains.
|
|
However, with multiplexing this can be reduced to two connections, or, at
|
|
the operator's discretion, more than two for operational reasons.
|
|
If multiplexing is not used, the number of server-to-server connections
|
|
needed to exchange stanzas between virtual hosting providers or
|
|
multi-service XMPP servers can increase signficantly.
|
|
This can lead to the number of connections exceeding the maximum number of
|
|
connections allowed from a single address as explained in &xep0205;.
|
|
</p>
|
|
<p>
|
|
This specification defines new mechanisms for advertising and negotiating
|
|
multiple hosts over a single session.
|
|
Furthermore it advances the state of the art over the multiplexing
|
|
solution defined in &xep0220; by working on both client-to-server (c2s)
|
|
and server-to-server (s2s) sessions.
|
|
</p>
|
|
</section1>
|
|
<section1 topic='Advertising Support' anchor='advertising'>
|
|
<p>
|
|
If a server supports receiving multiplexed streams it SHOULD inform the
|
|
connecting entity when returning stream features during the negotiation
|
|
process.
|
|
Two mechanisms exist for authenticating domains that can be multiplexed
|
|
over a connection: domains may be authenticated using the TLS certificate
|
|
(and client certificate if applicable), and domains may be authorized
|
|
using the connection authorization mechanism described later in this
|
|
document.
|
|
</p>
|
|
<p>
|
|
To advertise support for multiplexing all domains present in a TLS
|
|
certificate the server includes a <mux/> element qualified by the
|
|
'urn:xmpp:mux:0' namespace in the stream features list.
|
|
This feature MUST be advertised only after TLS has been negotiated (either
|
|
by opportunistic TLS using the STARTTLS feature or by implicit TLS when
|
|
establishing the TCP socket) an before authentication using SASL EXTERNAL
|
|
has been performed.
|
|
This feature is not mandatory to negotiate.
|
|
</p>
|
|
<example caption='Server advertises support for mux using SASL EXTERNAL'><![CDATA[
|
|
<stream:features>
|
|
<mux xmlns='urn:xmpp:mux:0'/>
|
|
<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
|
|
<mechanism>EXTERNAL</mechanism>
|
|
</mechanisms>
|
|
</stream:features>]]></example>
|
|
<p>
|
|
The mux feature may also be advertised after authentication with SASL
|
|
EXTERNAL.
|
|
If advertised after authentication the feature MUST include a list of
|
|
supported hosts wrapped in <host/> elements.
|
|
</p>
|
|
<example caption='Server advertises support for connection authorization'><![CDATA[
|
|
<stream:features>
|
|
<mux xmlns='urn:xmpp:mux:0'>
|
|
<host>capulet.example</host>
|
|
<host>montague.example</host>
|
|
<host>chat.montague.example</host>
|
|
<host>rooms.capulet.example</host>
|
|
</mux>
|
|
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
|
|
</stream:features>]]></example>
|
|
</section1>
|
|
<section1 topic='Authentication with SASL EXTERNAL' anchor='authn'>
|
|
<p>
|
|
If the initiating entity wishes to indicate that it intends to use
|
|
multiplexing with SASL EXTERNAL it MUST respond to the empty <mux/>
|
|
element by sending another empty <mux/> element qualified by the
|
|
'urn:xmpp:mux:0' namespace in reply.
|
|
No stream restart is necessary.
|
|
</p>
|
|
<p>
|
|
After indicating support for multiplexing by negotiating the mux stream
|
|
feature, authentication can proceed.
|
|
When using SASL EXTERNAL this is done by validating the certificate as
|
|
detailed in &xep0178; except that every domain that is present in the
|
|
certificate is now eligible for multiplexing without further negotiation.
|
|
Further stream features (such as resource binding) still use the JID from
|
|
the original connection (or from the authorization identity).
|
|
</p>
|
|
<p>
|
|
If a bidirectional s2s connection has been negotiated for this session using
|
|
&xep0288;, negotiation of the mux stream feature also implies that the
|
|
receiving entity SHOULD multiplex stanzas sent back to the initiating entity
|
|
for all domains in the verified client certificate.
|
|
If bidi is not negotiated then mux will need to be negotiated again when the
|
|
original receiving entity establishes a connection with the original
|
|
initiating entity.
|
|
</p>
|
|
</section1>
|
|
<section1 topic='Connection Authorization' anchor='authz'>
|
|
<p>
|
|
Often it is not desirable to have one certificate containing every XMPP
|
|
address or host managed by the server, or the use of SASL EXTERNAL may be
|
|
impossible.
|
|
In these cases the initiating entity may request authorization to
|
|
send stanzas over an existing connection.
|
|
</p>
|
|
<p>
|
|
If the initiating entity has an authenticated connection to a server and
|
|
wishes to send stanzas to another server that was listed in the original
|
|
servers post-auth <mux/> stream feature it MAY establish an XMPP
|
|
connection with the new server and verify that new server also lists the
|
|
original server in its post-auth mux stream feature.
|
|
If it does the initiating entity replies with a <mux/> element
|
|
qualified by the 'urn:xmpp:mux:0' namespace with a shared secret as the
|
|
payload and the host being selected included in the 'host' attribute.
|
|
The old server then sends an IQ over its existing connection with the
|
|
initiating entity containing the same mux element and secret, thereby
|
|
confirming its relationship to the new server.
|
|
If the client verifies that the secrets match it sends an empty IQ of type
|
|
"result" in response to indicate success, otherwise the IQ response should
|
|
be a "not-acceptable" stanza error (see &rfc6120; §8.3.3.9).
|
|
</p>
|
|
<p>
|
|
For example, if the server montague.example wishes to establish a
|
|
multiplexed connection with capulet.example and rooms.capulet.example the
|
|
flow would look like this:
|
|
</p>
|
|
<code><![CDATA[
|
|
montague.example capulet.example
|
|
---------------- ---------------
|
|
| |
|
|
| [if necessary, |
|
|
| perform DNS lookup |
|
|
| on Target Domain, |
|
|
| open TCP connection, |
|
|
| and establish stream] |
|
|
| -----------------------> | rooms.capulet.example
|
|
| | ---------------------
|
|
| [if necessary, | |
|
|
| perform DNS lookup, | |
|
|
| on Sender Domain, | |
|
|
| open TCP connection, | |
|
|
| and establish stream] | |
|
|
| -----------------------------------------------> |
|
|
| | |
|
|
| send mux secret | |
|
|
| -----------------------------------------------> |
|
|
| | |
|
|
| send mux secret IQ | |
|
|
| <----------------------- | |
|
|
| | |
|
|
| send IQ response | |
|
|
| -----------------------> | |
|
|
| | |
|
|
| | close connection |
|
|
| <----------------------------------------------- |]]></code>
|
|
<p>
|
|
The XML for this exchange would look like the following:
|
|
</p>
|
|
<example caption='Initial connection between montague.example and capulet.example'><![CDATA[
|
|
<!--
|
|
Elided: a stream is negotiated between montague.example and capulet.example.
|
|
After authentication is complete capulet.example advertises support for mux:
|
|
-->
|
|
<stream:features>
|
|
<mux xmlns='urn:xmpp:mux:0'>
|
|
<host>rooms.capulet.example</host>
|
|
</mux>
|
|
</stream:features>
|
|
|
|
<!--
|
|
Negotiation proceeds and the mux stream feature is not selected. After
|
|
negotiation is complete montague.example tries to establish a connection with
|
|
rooms.capulet example and sends it a secret. The server responds with the same
|
|
secret:
|
|
-->
|
|
<iq to="montague.example" from="capulet.example" type="set" id="1285152">
|
|
<mux xmlns='urn:xmpp:mux:0'>secret</mux>
|
|
</iq>
|
|
|
|
<-- The server at montague.example indicates that the secret was verified. -->
|
|
<iq to="capulet.example" from="montague.example" type="result" id="1285152"/>
|
|
]]></example>
|
|
|
|
<example caption='Secondary connection between montague.example and rooms.capulet.example'><![CDATA[
|
|
<!--
|
|
Elided: a stream is negotiated between montague.example and
|
|
rooms.capulet.example. After authentication is complete rooms.capulet.example
|
|
advertises support for mux:
|
|
-->
|
|
<stream:features>
|
|
<mux xmlns='urn:xmpp:mux:0'>
|
|
<host>capulet.example</host>
|
|
</mux>
|
|
</stream:features>
|
|
|
|
<!--
|
|
The server at montague.example indicates that it wishes to authorize its
|
|
existing connection with capulet.example:
|
|
-->
|
|
<mux xmlns='urn:xmpp:mux:0' host='capulet.example'>
|
|
secret
|
|
</mux>
|
|
|
|
<!--
|
|
The server at rooms.capulet.example closes the connection gracefully
|
|
if mux was established and begins using the connection between
|
|
montague.example and capulet.example.
|
|
-->
|
|
</stream:stream>
|
|
]]></example>
|
|
<p>
|
|
The format of the secret is not specified however, see the Security
|
|
Considerations section of this document for some suggestions.
|
|
</p>
|
|
</section1>
|
|
<section1 topic='Security Considerations' anchor='security'>
|
|
<p>
|
|
Some clients may send stanzas with no "from" attribute specified and rely on
|
|
the server to add the attribute before routing the stanza to its final
|
|
destination.
|
|
If multiplexing is used the lack of a from attribute indicates that the
|
|
client is acting on behalf of the origin JID for the connection, just like
|
|
normal, so clients MUST set the from attribute on any stanzas sent on behalf
|
|
of any multiplexed host.
|
|
</p>
|
|
<p>
|
|
The format of mux secrets is undefined in this document, however, they MUST
|
|
be unpredictable.
|
|
Only the initiating entity should attribute any meaning (if indeed there is
|
|
any) to the format of mux secrets.
|
|
In particular the receiving entity MUST NOT rely on a specific format for
|
|
the secret.
|
|
</p>
|
|
<p>
|
|
One suggestion for generating mux secrets is to generate a key that signs
|
|
information about the stream.
|
|
The format defined in &xep0185; is appropriate for this.
|
|
If the mux secret is a signature it must protect against reuse by at least
|
|
include a random secret generated with a cryptographically secure random
|
|
number source, the origin JID, the JID of the server initially receiving the
|
|
mux secret, and the stream ID for the stream the key will be authenticating
|
|
(this is not the same stream as the receiving entity's JID).
|
|
It is also RECOMMENDED that an expiration time be included in the key after
|
|
which it is no longer valid.
|
|
</p>
|
|
</section1>
|
|
<section1 topic='IANA Considerations' anchor='iana'>
|
|
<p>This document requires no interaction with &IANA;.</p>
|
|
</section1>
|
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
|
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
|
|
<p>This specification defines the following XML namespace:</p>
|
|
<ul>
|
|
<li>urn:xmpp:mux:0</li>
|
|
</ul>
|
|
<p>
|
|
Upon advancement of this specification from a status of Experimental to a
|
|
status of Draft, the ®ISTRAR; shall add the foregoing namespace to the
|
|
registries located at &STREAMFEATURES;, as described in Section 4 of
|
|
&xep0053;.
|
|
</p>
|
|
<code caption='Jabber/XMPP Protocol Stream Features Registry Submission'><![CDATA[
|
|
<feature>
|
|
<ns>urn:xmpp:mux:0</ns>
|
|
<name>mux</name>
|
|
<element>mux</element>
|
|
<desc>Indicate support for connection multiplexing and transmit secret keys to a peer.</desc>
|
|
<doc>Editor to add document reference if accepted</doc>
|
|
<status>provisional</status>
|
|
</feature>]]></code>
|
|
<p>
|
|
The ®ISTRAR; shall also add the foregoing namespace to the Jabber/XMPP
|
|
Protocol Namespaces Registry located at &NAMESPACES;.
|
|
Upon advancement of this specification from a status of Experimental to a
|
|
status of Draft, the ®ISTRAR; shall remove the provisional status from
|
|
this registry entry.
|
|
</p>
|
|
<code caption='Jabber/XMPP Protocol Namespaces Registry Submission'><![CDATA[
|
|
<ns>
|
|
<name>urn:xmpp:mux:0</name>
|
|
<doc>Editor to add document reference if accepted</doc>
|
|
<status>provisional</status>
|
|
</ns>]]></code>
|
|
</section2>
|
|
<section2 topic='Namespace Versioning' anchor='registrar-versioning'>
|
|
&NSVER;
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='Acknowledgements' anchor='ack'>
|
|
<p>
|
|
Thanks to Jeremie Miller, Peter Saint-Andre, and Philipp Hancke for writing
|
|
&xep0220; from which some of the text and techniques used in this document
|
|
were borrowed.
|
|
</p>
|
|
</section1>
|
|
</xep>
|