cancel
Showing results for 
Search instead for 
Did you mean: 

XMPP with STARTTLS

Rick_Nyman
Nimbostratus
Nimbostratus
I love the simplicity of SSL offload using standard SSL/TLS. Unfortunately, I've recently been given a requirement to do XMPP (an Instant Messaging protocol) using STARTTLS.

 

 

I found the excellent examples of IMAP and SMTP using STARTTLS, but it appears that XMPP is a different animal. To start, it's XML based. In addition, it appears to keep track of client requests and will not respond to what it thinks are repeat requests.

 

 

Here's what I have so far (Caveat - I do a little bit of PERL coding, but don't know much about TCL, so there may be fundamental issues with this script). At a basic level, this script starts by watching the server output and when it sees a stream:features XML tag, it inserts the STARTTLS capability. At that point, it starts watching client traffic - and expects to see the client requesting encryption. At that point, it starts encryption locally.

 

 

Anyone here familiar with XMPP?

 

 

Thanks all,

 

Rick

 

 

Last week's code

 

 

when CLIENT_ACCEPTED {

 

SSL::disable

 

}

 

when SERVER_CONNECTED {

 

TCP::collect

 

}

 

when CLIENT_DATA {

 

set lcpayload [string tolower [TCP::payload]]

 

if { $lcpayload starts_with " TCP::respond "\r\n"

 

TCP::payload replace 0 [TCP::payload length] ""

 

TCP::release

 

SSL::enable

 

} else {

 

TCP::respond "TLS is required on this stream - you sent $lcpayload\r\n"

 

TCP::payload replace 0 [TCP::payload length] ""

 

TCP::release

 

TCP::collect

 

}

 

}

 

when SERVER_DATA {

 

if {[string first "" [TCP::payload]] == -1 } {

 

TCP::release

 

TCP::collect

 

}

 

else {

 

regsub {\} [TCP::payload] {} changed

 

TCP::payload replace 0 [TCP::payload length] $changed

 

TCP::release

 

clientside { TCP::collect }

 

}

 

}

 

 

I received the following feedback from our XMPP expert

 

 

as I described in mail from last week, there are subsequent requests generated by the client as each feature is negotiated. What is happening is the server responds back w/ a list of (which the F5 rewrites as it is being sent to the client); the client negotiates TLS; then the client sends another request. The server receives this, but will *not* respond back... from the server's perspective, the client has simply made two requests and hasn't negotiated a feature yet.

 

 

Last night's rule - I'm still waiting for feedback

 

 

when CLIENT_ACCEPTED {

 

SSL::disable

 

}

 

when SERVER_CONNECTED {

 

TCP::collect

 

}

 

when CLIENT_DATA {

 

set clientdata [string tolower [TCP::payload]]

 

if { $clientdata starts_with " TCP::respond ""

 

TCP::payload replace 0 [TCP::payload length] ""

 

TCP::release

 

SSL::enable

 

TCP::collect

 

} elseif { $clientdata contains " TCP::respond $serverdata

 

} else {

 

TCP::respond "TLS is required on this stream - you sent $clientdata"

 

TCP::payload replace 0 [TCP::payload length] ""

 

TCP::release

 

TCP::collect

 

}

 

}

 

when SERVER_DATA {

 

if {[string first "" [TCP::payload]] == -1 } {

 

TCP::release

 

TCP::collect

 

}

 

else {

 

set serverdata [TCP::payload]

 

regsub {\} $serverdata {} changed

 

TCP::payload replace 0 [TCP::payload length] $changed

 

TCP::release

 

clientside { TCP::collect }

 

}

 

}
12 REPLIES 12

Rick_Nyman
Nimbostratus
Nimbostratus
It turns out that I didn't exactly understand how XMPP worked, but I continued to work with an engineer on the IM side (who luckily understood programming, so I could send him my scripts for comments as well), and the following script seems to be working.

 

 

Take care all,

 

Rick

 

 

when CLIENT_ACCEPTED {

 

SSL::disable

 

TCP::collect

 

}

 

when CLIENT_DATA {

 

set clientdata [string tolower [TCP::payload]]

 

if { $clientdata contains " TCP::respond ""

 

TCP::payload replace 0 [TCP::payload length] ""

 

TCP::release

 

SSL::enable

 

} elseif { $clientdata contains " TCP::respond ""

 

TCP::collect

 

} else {

 

TCP::collect

 

}

 

}

Mohit_63338
Nimbostratus
Nimbostratus
Hi Rick,

 

 

Thanks you for providing such a nice code. I have a similar requirement to connect to an XMPP server over the asm. I am using this code and my client to asm communication gets established however it gets struck afterwards. I believe from Proxy to Server communication needs to be established as wel. Could you please help me with that?

 

 

Thanks in advance..

 

Rick_Nyman
Nimbostratus
Nimbostratus
The big issue is to make sure that all stream tags are paired with /stream tags if you're editing the script. Fundamentally, when the client first connects and sends the stream tag, I ignore the data they send and reply with a request for TLS. When I see them connect with the starttls command, I ignore their data and start SSL handshaking. All future data is handed to the pool doing processing. This isn't the most robust solution, but it's seemed to work with clients.

 

 

I'd do a packet capture from both client and real server to see what is actually being sent and received by each end.

 

 

Regards,

 

Rick

Mohit_63338
Nimbostratus
Nimbostratus
Thanks Rick for the response.. I did a packet capture and it looks like the ASM is not initiating TLS connection with the server I am running 10.0.1

 

Any ideas where I am going wrong?

 

 

Thanks in advance..

Mohit_63338
Nimbostratus
Nimbostratus
This is my code:

 

 

when CLIENT_ACCEPTED {

 

SSL::disable

 

}

 

 

when SERVER_CONNECTED {

 

SSL::disable

 

TCP::collect

 

}

 

 

when SERVER_DATA {

 

set serverdata [string tolower [TCP::payload]]

 

if { $serverdata contains " TCP::release

 

SSL::enable

 

SSL::enable clientside

 

} elseif { $serverdata contains " TCP::release

 

TCP::collect

 

} elseif { $serverdata contains "

Rick_Nyman
Nimbostratus
Nimbostratus
Just to be clear, what do you mean when you say not initiating SSL? Does the LTM add the TLS request to the outgoing XML? When the client issues starttls, does the LTM pass that to the real servers, or does it process it internally? With our clients, I think the starttls is immediately followed by TLS handshaking by the client, but I haven't looked since we got it working.

 

 

Rick

Carlos_Fernande
Nimbostratus
Nimbostratus
Im pretty new to this. What if i need to offload using a certificate.

 

I have a farm of XMPP server behind a LTM F5 and want to prevent having install a SSL certificate on each one of the xmpp servers.

 

How would i apply this code to my scenario.

 

Thanks

Rick_Nyman
Nimbostratus
Nimbostratus
Set up your virtual server with an SSL profile (as if you were setting up SSL/TLS over port 5223, but using 5222). The SSL profile won't take effect at connect because of the SSL::disable command.

 

 

Wireshark will be your friend troubleshooting this; you should see the XML/XMPP data going back and forth clear text, then SSL handshaking (which you might need to decode 5222 as SSL in Wireshark to decode.

 

 

Sorry for the delayed response, hope this helps.

 

 

doug_25397
Nimbostratus
Nimbostratus
Rick,

 

 

Quick question. I'm looking at the irule you have posted. Is this for passing the starttls onto the server or for offloading onto the f5? I have a setup that is just a passthrough. I.E. the f5 just passes this on to server and the server and client communicate tls. It's not working properly and I found your post on devcentral but I'm not sure if this would work in my setup. On my vips I dont have an ssl profile so I'm not sure about the ssl:disable ssl:enable in the rule.

 

 

Doug

Rick_Nyman
Nimbostratus
Nimbostratus
My iRule is to support SSL offload using the F5 LTM.

 

 

If you're having an issue, try doing a packet capture to see what's going on. Once you've looked at the plain text handshaking at the beginning, you should be able to decode as SSL and then see the SSL/TLS handshaking as well.

 

 

Rick

RavishAgg_20266
Nimbostratus
Nimbostratus

Hi All,

 

I am trying to integrate F5 between XMPP server (like openfire,CISCO) and Our XMPP Module( that act as xmpp server). currently Our module is doing the TLS +SASL with XMPP servers. now we need to delegate the TLS part towards F5.

 

could someone help in providing the information that what irules we need to create for this? Like In XMPP , befor TLS negotiation, streams and features(like starttls) exchanged between client and server, so does this will need to be handled at F5 level , or Our module will handle the same, and only TLS ( certificate exchange) part will be delegated to F5. I am new to TCL language.

 

How would i apply this code to my scenario. Please let me know if you need more information. Thanks in advance.

 

Regards,

 

Ravish Aggarwal

 

Just wanted to update this thread due to some changes in TCP::collect in v11. This actually caused a production issue on a very highly utilized instance. We had a seperate issue that was causing connections to this VIP to be held open. Because the connections weren't terminating, this irule quickly (4-8 hours) ran tmm out of memory.

 

See SOL6578 regarding the changes to TCP::collect memory usage in v11.