Skip to content

Conversation

pelle-c
Copy link

@pelle-c pelle-c commented Oct 7, 2025

This commit adds a configuration option, "xmpp.server.dialback.offer", that can be used to control if dialback stream feature should be offered.

One usecase is where openfire is used as a gateway between XMPP domains ("trunking") - https://download.igniterealtime.org/openfire/docs/latest/documentation/trunking-guide.html

In situations where dialback has to be enabled in the gateway, it also forces the server(s) behind the gateway to use dialback. Before this commit, the code did not add dialback unless the certificates are selfsigned. Which means that a session to a remote domain via the gateway will not be established both ways due to lack of dialback, when the certificates are signed by CAs and trust exists.

With "xmpp.server.dialback.offer" set to "true", dialback will be added as a stream feature and sessions can be established in both directions.

This commit adds a configuration option, "xmpp.server.dialback.offer", that can be used to control if
dialback stream feature should be offered.

One usecase is where openfire is used as a gateway between XMPP domains ("trunking") -
https://download.igniterealtime.org/openfire/docs/latest/documentation/trunking-guide.html

In situations where dialback has to be enabled in the gateway, it also forces the server(s) behind
the gateway to use dialback. Before this commit, the code did not add dialback unless the certificates
are selfsigned. Which means that a session to a remote domain via the gateway will not be established
both ways due to lack of dialback, when the certificates are signed by CAs and trust exists.

With "xmpp.server.dialback.offer" set to "true", dialback will be added as a stream feature and
sessions can be established in both directions.
@guusdk
Copy link
Member

guusdk commented Oct 8, 2025

Hi! Thanks for your contribution. I'll need to find some time to dig into it in more detail (I wonder if this is the most correct place to control that behavior), but one thing that does stand out to me is that we'd want an option like this ("enable Server Dialback Authenticaton") to be added to the admin console pages.

The admin console pages now only allow for "Mutual Authentication" (SASL EXTERNAL) to be required, which implies that Server Dialback is to be used as a fallback. It would be far better to have the Server Dialback option be there explicitly (with maybe a warning if both SASL EXTERNAL and Dialback are disabled).

Can you add that to connection-settings-advanced.jsp and friends?

image

- Adding a checkbox that enables/disables dialback
- Adding a checkbox for offering dialback even if SASL fails - for openfire trunking
- Add a warning if both peer certificate verification and dialback are disabled
@pelle-c
Copy link
Author

pelle-c commented Oct 10, 2025

I haven't considered moving the added "dialbackoffer"-functionality to a more proper location. If doing so, I suspect that other surrounding parts would be nice to move as well.

Not sure if this is what you had in mind, but... for the web ui, I added two checkboxes and a warning if no authentication is configured. The "Enable dialback" reflects an already exisiting property, and the "Offer dialback..." is the one I introduced in this PR.

dialback_options

@guusdk
Copy link
Member

guusdk commented Oct 10, 2025

I'm a bit confused about how these two checkboxes are intended to work together:

  • "If attempting to validate a cerificate fails, the connection is closed and not attempted via dialback authentication"
  • "Offer dialback even if SASL EXTERNAL fails. Useful when peer certificate doesn't include the anticipated domain, for instance when trunking"

Aren’t these two options essentially opposites?

For context: Openfire supports two authentication mechanisms for server-to-server communication, both of which are fairly standard among XMPP servers:

  1. SASL EXTERNAL - which authenticates based on the identity in TLS certificates. In client-to-server communication, this is sometimes referred to as "mutual authentication.” Our admin console uses that term for server-to-server settings as well, which, I think, is somewhat misleading.
  2. Server Dialback - which verifies a server’s domain ownership by querying an authoritative server.

Before this PR, the admin console allowed explicit configuration of SASL EXTERNAL using the Disabled / Wanted / Needed radio buttons. There was no equivalent enable/disable option for Server Dialback, although this PR now adds one (which I think is good).

I believe the following adjustments would make configuration both clearer and more robust:

  • It should be possible to explicitly enable or disable each authentication mechanism.
  • When both authentication mechanisms are disabled, Openfire should display a warning, since server-to-server connections would then be impossible.

The SASL EXTERNAL option "If attempting to validate a certificate fails, the connection is closed and not attempted via dialback authentication” should be reworded to reduce confusion. The current phrasing suggests that specifically Server Dialback is skipped when validation fails. Instead, the text should clarify the reasoning: If SASL EXTERNAL is attempted (because the peer presented a certificate) but fails (because the certificate was invalid), then, to avoid the risk of talking to a compromised peer, not any other (weaker) authentication mechanisms (like Server Dialback) should be attempted. However, if SASL EXTERNAL is enabled but cannot be used (because the peer did not offer a certificate), then it’s fine to fall back to another mechanism, if one is available.

I believe this is a better label, instead of "If attempting to validate a cerificate fails, the connection is closed and not attempted via dialback authentication":

  • Treat invalid TLS certificates as fatal (do not attempt weaker authentication)

This last checkbox is likely the one causing confusion. In environments that use gatewaying or trunking (a fairly niche setup), running into 'invalid' certificates on the gateway are common, but they’re not necessarily a reason to skip other authentication methods like Server Dialback. In those cases, you’d want to uncheck that option.

These all are, I think, good improvements - but I don't quite get yet how these would fix the problem that you were initially trying to address with this PR. Given that you're introducing an option that's basically the inverse of a preexisting option:

  • Isn't the preexisting option working properly?
  • Is using that preexisting option (unsetting it) enough to solve your problem (was this a problem with us not using better words in its label)?

@guusdk
Copy link
Member

guusdk commented Oct 10, 2025

I have raised a new ticket for the suggested improvement on wording: https://igniterealtime.atlassian.net/browse/OF-3135

Another new ticket has been raised for improving the layout of these pages: https://igniterealtime.atlassian.net/browse/OF-3136

@pelle-c
Copy link
Author

pelle-c commented Oct 10, 2025

Let me join you in the confusion :-)
And yes, wording seems to be an issue here.

So we have the StartTLS policy, which states if we need certs or not. This should be in my view grouped together with certificate validation (expiry, trust, revocation etc).

Then we have authentication, with SASL and dialback.
For SASL, what exactly is the verification? Is it more than checking that the certificate contains the domain? The current wording can be misunderstood as being certificate validation with expiry etc.

And you are right, the two checkboxes that you mention seem to address the same issue. However, during testing, the existing checkbox had no impact. Could possibly depend on which end that starts the connection. I have to do some digging there.

Browsed through "XEP-0178: Best Practices for Use of SASL EXTERNAL with Certificates"

After successful TLS negotiation:
Server2 advertises SASL mechanisms. If the 'from' attribute of the stream header sent by Server1 can be matched against one of the identifiers provided in the certificate following the matching rules from RFC 6125 [7], Server2 SHOULD advertise the SASL EXTERNAL mechanism. If no match is found, Server2 MAY either close Server1's TCP connection or continue with a Server Dialback (XEP-0220) [8] negotiation.

So, I think the first checkbox is trying to address one of the the "eithers" above when no match is found. Again maybe reword that checkbox to something about identifiers/doman name in certificate instead of mentioning certificate validation. Also, with this interpretation, I think this checkbox should take care of my trunking case.
Guess I need to go back and see what failed, or what was missing.

@guusdk
Copy link
Member

guusdk commented Oct 10, 2025

We seem to be getting on the same page. :)

I think we both agree that things like STARTTLS policy, certificate validation, revocation etc mostly relate to the encryption configuration of a connection.

SASL EXTERNAL and Server Dialback both relate to authentication

Under OF-3136, I think this should be presented in a much clearer way.

SASL is a framework that can have many different authentication mechanisms. For server-to-server connections, XMPP only defines EXTERNAL, which ties authentication to the identity that's provided by the peer in a certificate (see RFC6120 and the specifications that you've found.

I agree that the preexisting checkbox should have addressed your issue. Perhaps we shouldn't be adding a feature, but fix a bug.

@guusdk
Copy link
Member

guusdk commented Oct 10, 2025

I have now roughly separated the 'configuration' admin page in three pages. This is roughly working and still somewhat of a mock-up. Texts need work (and functionality probably too), but it shows my intent.

Every connection-type (client, server, external component, multilexer) now gets three (instead of one) 'advanced' configuration pages:

  • config
  • encryption
  • authentication

(and that's duplicated for both ports, plaintext and directtls)

For server-to-server, it looks like this:

image image image image

@pelle-c
Copy link
Author

pelle-c commented Oct 11, 2025

Nice, these new pages makes the distinction between encryption and authentication much more clear!
I'll see if I can fix the issue(bug?) I was facing, without adding a new property.

Back to the text in your new pages...I guess this was just a first preview on the new layout and that the text hasn't been finalized. Nevertheless, a few comments...

  • "Certificate chain checking" should probably be changed to "Certificate validation" due to its content.
  • On "Authentication" page, the text at the top is a copy/paste from encryption so it's not spot on.
  • On "Authentication" page, both "boxes" have "Mutual authentication" - maybe "SASL EXTERNAL" and "Dialback" instead
  • For SASL, I'd like to reword the phrases for the options, in order to not confuse validate with certificate validation in encryption:
    • Disabled - Identities in peer certificates are not verified
    • Wanted - Identities in peer certificates are verified, but only when they are presented by the peer
    • Needed - A connection cannot be established if the peer does not present a certificate with a valid identity
    • If attempting to validate the identity in a certificate fails, the connection is closed without falling back to dialback
  • Dialback:
    • "it presents a dialback key..." now reads as there is a shared secret in DNS....maybe something like: "it presents a generated dialback key based on the communicating domains, the stream id and a secret only known to the authoritative server for the originating domain.
    • Disabled - Dialback will not be used to verify identities
    • Enabled - Dialback can be negotiated and may be used to verify identities

Per Carlén (Yubi) added 2 commits October 13, 2025 08:39
- Instead of introducing a new property, the code now uses STRICT_CERTIFICATE_VALIDATION to determine if dialback feature should be offered.
- Split up a few cases in the event handler for outbound connections, to support the above and give better guidance in troubleshooting by more precise logging.
@pelle-c
Copy link
Author

pelle-c commented Oct 13, 2025

The code now uses the old checkbox to determine if dialback should be offered.
And, it didn't work before, with the checkbox "unchecked", and using CA signed certificates.

But there are multiple locations with code like "... if (dialbackOffered && (ServerDialback.isEnabled() || ServerDialback.isEnabledForSelfSigned()))" - without any checks that the presented cert is indeed selfsigned.
I was wondering if the "enabled for selfsigned" could be removed - given that tls can be established with selfsigned option...and with the checkbox above we could have the same result"?

@guusdk
Copy link
Member

guusdk commented Oct 13, 2025

Thanks for your feedback! That's exactly the type of thing that I was hoping for.

I've been progressing a bit further, but I hit a bit of a snag: these pages are re-used for four types of connections:

  • client-to-server
  • server-to-server
  • external components
  • connection managers

The separation that we've been discussing here makes sense for server-to-server, but not so much for the others. They, for example, have most of their "authentication" settings on different places. For client-to-server connections, that's mostly on the "Registration & Login" page, for example. It's weird to have that page co-exist with an 'authentication' page under the connection settings.

I am also not liking how these settings are duplicated for every port (plain and directtls). It is very flexible, but that could also be an annoyance: if you want to disable TLS 1.1 on the plaintext port for client-to-server, chances are that you also want that on the directtls port. To top off the confusion, some settings apply to both ports, even if we do show them separately.

Hopefully we can find a better way to organize these pages, although I'm not immediately seeing how.

@pelle-c
Copy link
Author

pelle-c commented Oct 15, 2025

Sounds a bit tricky indeed. Too much flexibility often leads to increased complexity.
Would it be possible to collect all settings that are common for each type (s2s, cs2s...) on each "startpage", and then have the settings that differ on a page like "advanced settings". Then have boxes like today, but with more clear distinction - encryption and certificate validation, ciphers and protocols, authentication etc. If a box is not directly applicable for the type, just an information note could point in a better direction. Not a big change page I assume, mostly a question of rephrasing and moving things around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants