Server dialback issue over TLS

It seems I’m still having issues with S2S encrypted connections which fail in the outgoing direction with OpenFire. The problem seems to be related to Dialback over TLS, and if encrypted connections are enforced, outbound connections can’t be established (breaking communication for my users).

Example:

2014.02.07 11:53:29 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: is-a-furry.org id: 646d148e-6d07-4ffb-8670-2b9b69e99447 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>
2014.02.07 11:53:29 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: is-a-furry.org id: 646d148e-6d07-4ffb-8670-2b9b69e99447 for domain: palemoon.net answer:<stream:error xmlns:stream=“http://etherx.jabber.org/streams”>Encrypted server-to-server communication is required but was not used</stream:error>

My server checks out fine in the IM observatory (Grade A-) and some other servers connect just fine with encryption in both directions. Is this a problem with OpenFire, my specific installation/setup, or the remote server?

Looks like many servers throw the same error - doing a server restart saw a nice cluster of warnings from many different servers

As far as I can tell:

  1. OF tries to make a secure outbound connection over TLS

  2. This connection is (for whatever reason) not trusted remotely

  3. Remote server performs a dialback

  4. Remote server indicates TLS parameters as part of the dialback, which aren’t accepted by OF

  5. As a result, STARTTLS is not initiated, secure dialback connection is not available

  6. If remote server requires TLS, connection fails completely. In other cases, an unencrypted connection is established for outbound traffic

Even if (2) might be a remote problem, it seems (4) is an OF problem that should be fixed?

Any suggestions?

Log entries:

2014.02.07 12:43:41 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: is-a-furry.org id: a7b0d78e-8b98-474e-803a-758d56cb808a for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:43:41 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: is-a-furry.org id: a7b0d78e-8b98-474e-803a-758d56cb808a for domain: palemoon.net answer:<stream:error xmlns:stream=“http://etherx.jabber.org/streams”>Encrypted server-to-server communication is required but was not used</stream:error>

2014.02.07 12:43:47 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: exploit.im id: 946065357 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:17 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: proxy.eu.jabber.org id: cc97f77dde4a2c4b for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:17 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: exploit.im id: 2335585930 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:18 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: kaddafi.me id: 4b7e9138 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:19 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: jodo.im id: 2405944945 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:19 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: jabber.ru id: 1347473344 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:20 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: zauris.ru id: 3900095867 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:20 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: xmpp.ru id: 1907898729 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:22 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: swissjabber.ch id: 3de51422-401f-4c20-a2b4-839b8c31196a for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:22 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: zloy.im id: 2963169042 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:22 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: darkode.com id: 1312476715 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:23 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: xmpp.jp id: 4146622770 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:23 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: jabbim.pl id: 4149536209 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:24 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: jabbim.cz id: 320712977 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:28 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: jabber.no id: 1587105493 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:28 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: loyaljabber.com id: aa0dba4 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:33 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: is-a-furry.org id: 401fd7f6-fc4d-4fb2-ba72-154ca1fbec61 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

2014.02.07 12:44:34 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: is-a-furry.org id: 401fd7f6-fc4d-4fb2-ba72-154ca1fbec61 for domain: palemoon.net answer:<stream:error xmlns:stream=“http://etherx.jabber.org/streams”>Encrypted server-to-server communication is required but was not used</stream:error>

2014.02.07 12:44:45 org.jivesoftware.openfire.server.ServerDialback - ServerDialback: OS - Ignoring unexpected answer in validation from: jabba.biz id: 2266420383 for domain: palemoon.net answer:<stream:features xmlns:stream=“http://etherx.jabber.org/streams”></stream:features>

I could/should report the same issue and we have to fix it in near future because other XMPP-Server vendors and administrators want make TLS for S2S mandatory. (https://github.com/stpeter/manifesto/blob/master/manifesto.txt)

To #2: If the remote server use a self-signed certificate or a CA which is not in our java keychain we need the callback. Maybe there are some other ssl issues in the software of the remote server but I could notice the behavior with some community servers that use CAcert or self-signed certificates. What I want to say: We couldn’t put the finger on other projects!

The most of my remote server vendors is ejabberd. The server is really popular and this might be the reason why we could find some issue reports in their tracker too. (all rejected, because they said it’s an openfire problem, which I would agree at the moment)

but back to #4: I watched the same handshake behavior like you on my server but I don’t saw the mistake of the callback-response. Could you give me a hint what you expect?

(Maybe I have to investigate the debug log again in a xml editor)

I checked out the openfire sourcecode a week ago and looked into the SSL-code. But its quite hard to come into a new codebase and work on such kind of issue. So I planned a debugging session this week with a local OF installation talking to a remote ejabberd-server.

Maybe we could work together on the issue here on the board?

I’m all for trying to find a way to fix this issue. I’m aware that encrypted S2S is planned to become mandatory (in a few months or so, judging by the xmpp operators mailing list) in which case my connectivity with other servers would break in a much wider sense.

As for #2, it doesn’t seem to be a self-signed issue at least, since as far as I can tell a lot of those servers have proper CA-signed certificates.

If you want a hint what I expect for #4, I thought that would be self-evident? :wink:

Of course I expect OF to see the response as-sent by the remote side, and respond in the proper way with starttls (not sure who is supposed to issue this command but it’s clear the remote side is expecting a response in return to what has been sent and rejected). I’m not entirely sure about the exact message contents and what all it means, but it seems to me like the remote server is asking to initiate TLS over the dialback connection and OF saying “huhwhat?” and not doing it because of this unexpected response that is not understood?

Note: I’m just an operator, I’m not a java programmer, so I can’t help you with any coding. I’m also not intimately familiar with the inner workings of the XMPP protocol so my points above are best guess and deduction from what I see in the logs. My help can go as far as adminstrator duties like trying different settings and providing debug logs.

I’ve installed OF on my local machine. With my dynamic DNS host and an opened port in my firewall my OF is able to connect other servers. So lets go…

I tried to connect to my own jabber-server. It is A-Graded by xmpp.org ssl test and has a StartSSL-Certificate. But my local jabber don’t like the certificate-chain and switch back to Dialback-Method. The reason is that startssl is not in my truststore I think. But the interesting part:

If the remote server offers tls OF will try it only once. If an Exception occure like the certificate chain is not trusted the whole block is skipped and the “old” dialback without encryption is used.

(This could be ok because if I don’t trust the certificate, why I should fallback to dialback over tls? But it’s an interesting feature if s2s works only encrypted.)

Then I tried to connect to an ejabberd-server. This endet up that the remote server don’t provide SAML or dialback authentication. So I can’t reproduce your exact szenario. I will try to use other remote servers instead.

If the remote server offers tls OF will try it only once. If an Exception occure like the certificate chain is not trusted the whole block is skipped and the “old” dialback without encryption is used.

I think this is the problem then. OF will try TLS on the initial outbound connection, but if dialback authentication is used because the remote certificate isn’t trusted (for whatever reason) then the dialback used doesn’t support starttls because it’s the “old” dialback. I.e.: if I understand correctly OF uses a routine for receiving remote server dialback that doesn’t support starttls? That would explain the errors, at least.

And it makes sense to try starttls over dialback if you want to establish encrypted connections. The problem is authentication/validation where there is no trust, not the actual encryption. Asking for a dialback confirms that you are making a connection to the server you intend to connect to; where you go from there can be either encrypted or non-encrypted. the step of making the dialback encrypted is where it goes wrong because OF expects the remote server dialback to be unencrypted.

Is there a temporary workaround that I could use, e.g. telling OF to ignore potential certificate problems, while this is sorted out?

OF tries to open a TLS connection and ask for SASL-features. Two sasl features EXTERNAL and DIALBACK could be handled.

If the certificates are self-signed only DIALBACK is used. But if something is wrong with the certificates the whole TLS-stuff is skipped and OF retries with classic dialback over an unencrypted connection.

If you set ‘xmpp.server.certificate.verify’ or ‘xmpp.server.certificate.verify.chain’ to false the whole chain is not validated and no exception is raised. In this case I could create an full-encrypted S2S between my both OF servers.

I read two documents to get involved whats happend:

http://xmpp.org/extensions/xep-0178.html #3 S2S

http://xmpp.org/extensions/xep-0220.html

Yesterday I tried ejabberd and the response is a bit strange: There is no offered feature for SAML authorization. But I’m not sure that the server is conigured very well. (See the first document example 25 - this is empty)

This cause an exception too and the unencrypted fallback is used as well.

When I look into your logs your reportet issue is different. I will search in the next days for a different ejabberd-server and try it again.

On the train I got some time to investigate about your log messages and I think they all occur due fallback-dialback and the remote server require TLS.

In this case the “policy-violation” is the correct way to deny the fallback to OF but I think that some implementations of the remote server handle the case different.

I think this could happend:

  1. OF opens a TLS connection and try to verify the peer with SAML or Dialback

  2. An exception occurs. Maybe a silent “exception” like no SAML-authentications offered from remote server

  3. The OF closes the TLS connection and retries with old unencrypted dialback.

  4. unencrypted connectons denied by remote server (with some different and not expected responses)

You have to enable debug-mode to get more informations whats really went wrong between handshake.

I found an “issue” and fixed it. The reason for the issue is the specification is not clear at one point:

If the remote server doesn’t offer any SASL-authentication feature the initiating server could handle this in two ways:

  • Close the connection als retry with classic dialback unencrypted

  • Fallback to dialback over tls

See XEP-0178 Point 3.9:

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, 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.

I changed the code and TADA, more servers get an encrypted connection.

I think it’s also a problem in ejabberd-implementation (they should provide auth-methods!) but all issue-reports to the team were very unspecific so they rejected all of them.

The remaining remote servers without TLS-connection: The issue is here the certificate-chain validation. As mentioned above it could be ok to kill the connection but I think if the root certificate is ok but the CA is not trusted we should provide a configureable way to use dialbackOverTls to authenticate the connection over this method.

I’m looking forward to raise an issue-report and provide two patches:

  • Use dialbackOverTls if no auth-feature is provided

  • Use dialbackOverTls if the CA is not trusted (and configuration property is set)

Also I will try to contact ejabberd to ask them why we don’t get any SASL-auth-features back.

@Moonchild: If you’re interested in an alpha-graded openfire.jar give me a PN with your email-adress.

1 Like

I did some more digging myself in the debug log, and found a potential cause for the original TLS connection to fail: Apparently, if the CN of the certificate of the server connecting to is not a match for the server connection, even if the correct domain name is indicated in the AlternativeNames cert extension, java throws a GenericSSLEngine error, more specifically java.security.cert.CertificateException: target verification failed of [{{CN}}]

e.g. a cert has www.domain.com as CN, and www.domain.com and domain.com as AltNames.

The actual XMPP server runs on domain.com (a very common scenario, right?)

Seems AltNames is ignored by OpenFire and only the CN is used? The debug log didn’t give more info.

Here’s the log entry:

2014.02.09 08:47:08 org.jivesoftware.openfire.session.LocalOutgoingServerSession - LocalOutgoingServerSession: Handshake error while creating secured outgoing session to remote server: is-a-furry.org(DNS lookup: is-a-furry.org:5269)

javax.net.ssl.SSLHandshakeException: General SSLEngine problem

at sun.security.ssl.Handshaker.checkThrown(Unknown Source)

at sun.security.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)

at sun.security.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)

at sun.security.ssl.SSLEngineImpl.wrap(Unknown Source)

at javax.net.ssl.SSLEngine.wrap(Unknown Source)

at org.jivesoftware.openfire.net.TLSStreamHandler.doHandshake(TLSStreamHandler.jav a:274)

at org.jivesoftware.openfire.net.TLSStreamHandler.start(TLSStreamHandler.java:168)

at org.jivesoftware.openfire.net.SocketConnection.startTLS(SocketConnection.java:1 82)

at org.jivesoftware.openfire.session.LocalOutgoingServerSession.secureAndAuthentic ate(LocalOutgoingServerSession.java:433)

at org.jivesoftware.openfire.session.LocalOutgoingServerSession.createOutgoingSess ion(LocalOutgoingServerSession.java:346)

at org.jivesoftware.openfire.session.LocalOutgoingServerSession.authenticateDomain (LocalOutgoingServerSession.java:167)

at org.jivesoftware.openfire.server.OutgoingSessionPromise$PacketsProcessor.sendPa cket(OutgoingSessionPromise.java:261)

at org.jivesoftware.openfire.server.OutgoingSessionPromise$PacketsProcessor.run(Ou tgoingSessionPromise.java:238)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem

at sun.security.ssl.Alerts.getSSLException(Unknown Source)

at sun.security.ssl.SSLEngineImpl.fatal(Unknown Source)

at sun.security.ssl.Handshaker.fatalSE(Unknown Source)

at sun.security.ssl.Handshaker.fatalSE(Unknown Source)

at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)

at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)

at sun.security.ssl.Handshaker.processLoop(Unknown Source)

at sun.security.ssl.Handshaker$1.run(Unknown Source)

at sun.security.ssl.Handshaker$1.run(Unknown Source)

at java.security.AccessController.doPrivileged(Native Method)

at sun.security.ssl.Handshaker$DelegatedTask.run(Unknown Source)

at org.jivesoftware.openfire.net.TLSStreamHandler.doTasks(TLSStreamHandler.java:32 5)

at org.jivesoftware.openfire.net.TLSStreamHandler.doHandshake(TLSStreamHandler.jav a:235)

… 10 more

Caused by: java.security.cert.CertificateException: target verification failed of [www.is-a-furry.org]

at org.jivesoftware.openfire.net.ServerTrustManager.checkServerTrusted(ServerTrust Manager.java:192)

at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown Source)

… 19 more

It’s not just ejabberd, either. the main one getting to my attention (is-a-furry.org) apparently uses Prosody, not ejabberd, and it raised a flag because they require S2S encryption. Other servers I’m having the issue with do not enforce encryption so I can still connect, but obviously not encrypted. Those will all fail once it becomes mandatory.

I’ll shoot you a PM for that alpha.

Apart from what I indicated about about CN != server host, there isn’t any other detail in the debug log. If fails the initial connection, dialback is initiated, verification over dialback succeeds ending in ServerDialback: AS - Key was: VALID for host: domain.com

It seems after that the debug log goes silent, up to the timeout message indicating the packet could not be delivered from the client.

So, combining both logs:

  1. OF attempts a connection, plaintext first, succeeds.
  2. TLS is requested, certificate verification by OF fails (possibly due to CN name mismatch with server hostname connected to)
  3. Server dialback verification is initiated and succeeds.
  4. Remote server then sends the logged request for starttls which is not understood by OF. This is the main issue.
  5. If remote server requires TLS, it will not accept the connection and send another informative response to OF which is not understood either (hence both showing up in the Warn logs)

yes, thats correct. It’s a bit hard to read the log-statements without knowing the code. The ServerDialback-Class is used for both variants: dialbackOverTLS and classic dialback.

You could try some configuration properties to accept more certificates (but then your server could be fooled by DNS spoofing):

xmpp.server.certificate.accept-selfsigned = true (default)

xmpp.server.dialback.enabled = true (default)

xmpp.server.certificate.verify = false

xmpp.server.certificate.verify.root = false

Thanks, I’ll try to set server verification to false as a temporary workaround. I already have the self-signed and dialback ones set to true (since I know there are a good number of servers with self-signed certs).

It’s a temp fix if it works, since cert verification is quite important - we want to avoid spoofing/MitM, after all :wink:

I guess if we at least can get the initial outbound TLS connection working, then any servers with proper cert chains would have no issue, right? Eagerly awaiting that openfire.jar replacement to test it out.

EDIT: Seems disabling cert verification solves the problem with is-a-furry.org, so that would confirm that there’s a problem checking the certificate that’s presented. Many other server connections are still not secured on outbound and I’m still getting the “unexpected answer” errors there (by the looks of it those are all ejabberd ones, so OF and ejd have a communication error there). Maybe your patched version will help with that…

i opened a discussion in the development board to discuss the integration of my simple patch.

The discussion could be found here: http://community.igniterealtime.org/thread/51785

@Moonchild: If you want write in this thread your positive experience with my SNAPSHOT-build.