1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-30 21:22:15 -05:00
xeps/inbox/host-meta-2.xml

221 lines
13 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>Host Meta 2 - One Method To Rule Them All</title>
<abstract>This document defines an XMPP Extension Protocol for extending XEP-0156 by modifying the JSON Web Host Metadata Link format to support discovering all possible XMPP connection methods, for c2s and s2s</abstract>
&LEGALNOTICE;
<number>XXXX</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>RFC 1464</spec>
</dependencies>
<supersedes>
<spec>XEP-0156</spec>
<spec>RFC 7711</spec>
</supersedes>
<supersededby/>
<shortname>connections-v2</shortname>
<registry/>
&moparisthebest;
<revision>
<version>0.0.1</version>
<date>2023-11-19</date>
<initials>tjb</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>Although &xmppcore; specifies the use of TCP as the method of connecting to an XMPP server, alternative connection methods exist, including the &xep0124; method (for which &xep0206; is the XMPP profile), the websocket
subprotocol specified in &rfc7395;, &xep0368;, &xep0467;, and &xep0468;, and surely others that don't yet exist. For some of these methods, it is necessary to discover further parameters before connecting, such as the HTTPS URL of a BOSH or WebSocket request. Without ways to auto-discover these parameters, the relevant information would need to be provided manually by a human user (which is cumbersome and error-prone) or hard-coded into XMPP software applications (which is brittle and not interoperable
).</p>
<p>Additional things also require automatic discovery, like &rfc7711; (replaced here by pinning public keys instead like &rfc7469;), &tls-ech;, SNI names, and ALPN protocols. The web solves these problems in HTTP3 by introducing another set of DNS records (SVCB and HTTPS) but that poses a problem for XMPP because we don't have the clout to introduce our own DNS records and hope for any sort of adoption with the myriad DNS setup panels most people use. Additionally while we all hope and pray for DNSSEC (and DANE), many TLDs don't yet support it, and we can't trust this info over plaintext (note the web doesn't trust it over plaintext either, DNS-over-TLS is a requirement for ECH).</p>
<p>This document defines a way to encapsulate information about all these connection methods and parameters for auto-discovery via Link entries in a server's "host-meta.json" file. It also provides a flag to signal to the client or server that all info is here and no other methods need be used.
</p>
</section1>
<section1 topic='HTTPS Lookup Method' anchor='http'>
<section2 topic='Link Format' anchor='httpformat'>
<p>The HTTPS lookup method uses Web Host Metadata &rfc6415; to categorize and list the URIs of alternative connection methods. It is intended to replace all current methods for looking up connection information by "native" clients and servers, as well as be used by web browsers.</p>
<p>Each alternative connection method is specified in the host-meta.json (JRD) file using a distinctive link relation &rfc5988;. This specification defines several extension relation types, here links are provided to their respective transport definitions:</p>
<ul>
<li>urn:xmpp:alt-connections:tls - c2s Direct TLS - &xep0368;</li>
<li>urn:xmpp:alt-connections:quic - c2s Quic - &xep0467;</li>
<li>urn:xmpp:alt-connections:s2s-websocket - s2s WebSocket - &xep0468;</li>
<li>urn:xmpp:alt-connections:s2s-tls - s2s Direct TLS - &xep0368;</li>
<li>urn:xmpp:alt-connections:s2s-quic - s2s Quic - &xep0467;</li>
</ul>
<p>And additionally re-uses some defined in &xep0156;:</p>
<ul>
<li>urn:xmpp:alt-connections:websocket - c2s WebSocket - &rfc7395;</li>
<li>urn:xmpp:alt-connections:xbosh - c2s BOSH - &xep0206;</li>
</ul>
<p>Additionally a top level "xmpp" object is defined, which currently has the following subfields defined:</p>
<ul>
<li>"ttl" - integer - MANDATORY - seconds this document can be cached for</li>
<li>"public-key-pins-sha-256" - list of strings - OPTIONAL - base64 sha256 hashes of public keys to trust, use as defined in &rfc7469;</li>
</ul>
<p>The following are new fields defined in each link object:</p>
<ul>
<li>"priority" and "weight" - integers - MANDATORY - Use as defined in &rfc2782;</li>
<li>"sni" - string - MANDATORY - name to send in the TLS/QUIC SNI extension</li>
<li>"ech" - string - OPTIONAL - Use as defined in &tls-ech;</li>
<li>"ips" - list of strings - at least one MANDATORY - IPv4 or IPv6 addresses only, connect to these</li>
</ul>
<p>The "href" field in websocket/bosh links remains unchanged from XEP-0156, but is replaced by "port" (integer) in Direct TLS/Quic connections.</p>
</section2>
<section2 topic='Business Rules' anchor='httpbizrules'>
<p>The following business rules apply:</p>
<ol start='1'>
<li>host-meta files MUST be fetched only over HTTPS, and MUST only use secure connections (TLS or equivalent).
This provides secure delegation, meaning you MUST send the provided SNI and validate that the certificate
is valid for that host *or* the XMPP domain (or the public key hash is pinned).</li>
<li>host-meta responses with the top level "xmpp" object mean this XEP is in use and legacy SRV/POSH/etc lookups SHOULD be skipped, alternatively if the top level "xmpp" object does not exist, XEP-0156 rules apply instead.</li>
<li>Client/Server implementations SHOULD consider weight/priority as presumably the server admin has thought about which links can handle load best etc, but MAY prioritize certain protocols over others, for example a privacy client may want to use websocket to look most like HTTPS, or a mobile client might prefer Quic for connection roaming. Regardless server operators MUST NOT count on any ordering, a client can connect to any of these under even normal circumstances.</li>
</ol>
</section2>
<section2 topic='Examples' anchor='httpexamples'>
<p>It is possible to use additionally a JSON-based format for host-meta information. The JSON representation of the host metadata is named JRD and specified in Appendix A of &rfc6415;. The above XRD example would be presented in JRD as:</p>
<example caption='Result for /.well-known/host-meta.json'><![CDATA[
{
"xmpp": {
"ttl": 3000,
"public-key-pins-sha-256": [
"4/mggdlVx8A3pvHAWW5sD+qJyMtUHgiRuPjVC48N0XQ="
]
},
"links": [
{
"rel": "urn:xmpp:alt-connections:websocket",
"href": "wss://other.example.org/xmpp-websocket",
"ips": [
"1.2.3.4",
"fd00:feed:dad:beef::1"
],
"priority": 15,
"weight": 50,
"sni": "example.org",
"ech": "eG1wcC1jbGllbnQ="
},
{
"rel": "urn:xmpp:alt-connections:tls",
"port": 443,
"ips": [
"1.2.3.4",
"fd00:feed:dad:beef::1"
],
"priority": 10,
"weight": 50,
"sni": "example.org",
"ech": "eG1wcC1jbGllbnQ="
},
{
"rel": "urn:xmpp:alt-connections:quic",
"port": 443,
"ips": [
"1.2.3.4",
"fd00:feed:dad:beef::1"
],
"priority": 5,
"weight": 50,
"sni": "example.org",
"ech": "eG1wcC1jbGllbnQ="
},
{
"rel": "urn:xmpp:alt-connections:s2s-websocket",
"href": "wss://other.example.org/s2s-xmpp-websocket",
"ips": [
"1.2.3.4",
"fd00:feed:dad:beef::1"
],
"priority": 15,
"weight": 50,
"sni": "example.org",
"ech": "eG1wcC1jbGllbnQ="
},
{
"rel": "urn:xmpp:alt-connections:s2s-tls",
"port": 443,
"ips": [
"1.2.3.4",
"fd00:feed:dad:beef::1"
],
"priority": 10,
"weight": 50,
"sni": "example.org",
"ech": "eG1wcC1jbGllbnQ="
},
{
"rel": "urn:xmpp:alt-connections:s2s-quic",
"port": 443,
"ips": [
"1.2.3.4",
"fd00:feed:dad:beef::1"
],
"priority": 5,
"weight": 50,
"sni": "example.org",
"ech": "eG1wcC1jbGllbnQ="
},
{
"rel": "urn:xmpp:alt-connections:xbosh",
"href": "https://web.example.com:5280/bosh"
}
]
}
]]></example>
</section2>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
<section2 topic='For Server Administrators' anchor='impl-admins'>
<p>For the forseeable future you will need to maintain legacy SRV records in addition to this file, and you should provide DANE TLSA records too if possible.</p>
<p>To make your server as accessible to other clients/servers no matter how bad the network they are on, it is advised to use port 443 when possible, as it looks the most like HTTPS.</p>
<p>To make connection discovery work in web clients (including those hosted on a different domain) the host service SHOULD set appropriate <link url="https://www.w3.org/TR/cors/">CORS</link> headers for Web Host Metadata files. The exact headers and values are out of scope of this document but may include: <em>Access-Control-Allow-Origin</em>, <em>Access-Control-Allow-Methods</em> and <em>Access-Control-Allow-Headers</em>.</p>
<p>Due care has to be exercised in limiting the scope of <em>Access-Control-Allow-Origin</em> response header to Web Host Metadata files only.</p>
<code caption="Example header allowing all sites to read host metadata"><![CDATA[
Access-Control-Allow-Origin: *
]]></code>
<p class="box"><em>Access-Control-Allow-Origin</em> header with a value of <em>*</em> allows JavaScript code running on a different domain to read the content of Web Host Metadata files. Special value <em>*</em> ensures that the request will only succeed if it is <link url="https://www.w3.org/TR/cors/#resource-requests">invoked without user credentials</link> (e.g. cookies, HTTP authentication).</p>
</section2>
<section2 topic='For Programmers' anchor='impl-codemonkey'>
<p>
As an author of a client or server, you presumably have users, and those users have a single desire, to communicate over XMPP.
This means that they want to connect at any costs, they *do not* want to see the first error to appear and have all further attempts aborted until it's fixed.
With this problem statement, here is a list of current best practices to make this happen:
</p>
<ul>
<li>"ttl" is a guideline for when you SHOULD try to fetch a newer copy, if you can't, you MUST try to fetch connection info other ways, and also fall back to expired data if needed</li>
<li>When trying a particular connection with a list of IPs, you can try them all in order, or pick a random one like DNS would do, but if you do, you MUST keep track of the ones you tried, and try all the rest later if your connection wasn't succesful</li>
<li>An application MUST keep trying every possible connection until they have both an authenticated stream (the TLS certificate is valid) and have seen a valid XMPP stream element for the server you are trying to connect to. You may get an authenticated stream and an HTTP or IMAP or SMTP error, or even an XMPP stream header for another server, you MUST keep going until both of these are satisified.</li>
</ul>
</section2>
<section2 topic='For Future Spec Writers' anchor='impl-speccy'>
<p>Keep in mind this json file is defined in an RFC and we need to keep backwards compatibility with it, software only implementing XEP-0156 should be able to read and use this file as extended by this XEP only seeing the websocket/bosh connections.</p>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>It should be noted this allows your web host to hijack your XMPP connection, but that's actually been true for quite some time, they could already bypass the need for a certificate with POSH, or get one from LetsEncrypt if you didn't have the proper CAA records, or hijack it for websocket/bosh supporting clients, so this doesn't really open up new avenues of attack.</p>
<p>Please refer to the security considerations and warnings of &rfc7469; with regards to having a backup public key and being careful to not break your domain for the whole TTL</p>
<p>Validating certs is full of edge cases and must be done with the utmost of care and precision.</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'>
<p>This document requires no interaction with the &REGISTRAR;.</p>
</section1>
</xep>