sslh - 2 option
SRV records for XMPP over TLS
This Page was written with Ubuntu 16.04 LTS in mind, and may not work correctly with other versions or distributions.
XMPP PortalXMPP Servers: Servers Category XMPP Clients: Clients Category User Guides: User Guide Category
This artical will walk you through implementing XEP-0368: SRV records for XMPP over TLS on a Prosody version 0.10 XMPP server, running on Ubuntu version 16.04 LTS server. This will allow users to connect to the XMPP server while connecting through a restrictive firewall that blocks port 5222. This also adds that ability for a client to connect directly a TLS port instead of a STARTTLS port, this allows for a slightly quicker connection (in theory).[1] Contents
1 Overview
2 Install SSLH from Source
3 Configuring SSLH for XMPP and HTTPS Traffic
4 Web Server Changes
4.1 Using Nginx
5 Changes to be made on the XMPP Server
5.1 ejabberd Changes
5.2 Prosody Changes
6 DNS Changes
7 Testing
8 References
8.1 Notes
Overview
The concept of the XEP-0368 standard is to allow users to connect to the xmpp server via port 443, but still allow HTTPS traffic to flow over the same port. This is accomplished by installing the program sslh that will sit in front of both the web server and the xmpp server and splits the connection between them.
When a client connects via port 5222, they connect via STARTTLS directly to prosody port.
When a client connects via port 5223, they connect via direct TLS directly to prosody port.
When a client connects via port 443, they connect via TLS to sslh that will then redirect the connection to prosody port 5223.
Install SSLH from Source
You must install sslh with ALPN support; sslh version 1.18 or greater.[2]
To start out with, you must install the below prerequisites, on ubuntu[2], use the following command:
apt install git libwrap0-dev libconfig8-dev libpcre3-dev
After you have installed the prerequisites, download the git repository for sslh
mkdir -p /var/src && cd /var/src/
git clone https://github.com/yrutschle/sslh.git
And findlay, go into into the source sslh directory to compile and install the code.
cd /var/src/sslh/
make install
After the software is installed, copy the init file to start sslh.
cp scripts/etc.init.d.sslh /etc/init.d/sslh
Configuring SSLH for XMPP and HTTPS Traffic
You must create and/or update the /etc/sslh.cfg file.
The host entry, that is currently im.example.org, must be changed to you XMPP server's DNS Host Name.
verbose: true;
foreground: false;
inetd: false;
numeric: false;
transparent: false;
timeout: 2;
user: "nobody";
pidfile: "/var/run/sslh.pid";
syslog_facility: "auth";
# Change hostname with your external address name. Note: It should not be resolving to 127.0.0.1
listen:
(
{ host: "im.example.com"; port: "443"; }
);
protocols:
(
#{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; keepalive: true; fork: true; },
{ name: "http"; host: "localhost"; port: "443"; log_level: 0;},
# just match ALPN
{ name: "tls"; host: "localhost"; port: "5223"; alpn_protocols: [ "xmpp-client" ]; log_level: 1;},
{ name: "tls"; host: "localhost"; port: "443"; alpn_protocols: [ "h2", "http/1.1", "spdy/1", "spdy/2", "spdy/3" ]; log_level: 0; },
# just match SNI
{ name: "tls"; host: "localhost"; port: "5223"; probe: "builtin"; sni_hostnames: [ "example.com" ]; log_level: 1;},
{ name: "tls"; host: "localhost"; port: "5223"; probe: "builtin"; sni_hostnames: [ "example2.com" ]; log_level: 1;},
{ name: "tls"; host: "localhost"; port: "5223"; probe: "builtin"; sni_hostnames: [ "example3.com" ]; log_level: 1;},
{ name: "tls"; host: "localhost"; port: "443"; probe: "builtin"; sni_hostnames: [ "im.example.com" ]; log_level: 0; },
{ name: "tls"; host: "localhost"; port: "443"; probe: "builtin"; sni_hostnames: [ "im.example2.com" ]; log_level: 0; },
{ name: "tls"; host: "localhost"; port: "443"; probe: "builtin"; sni_hostnames: [ "im.example3.com" ]; log_level: 0; },
# catch anything else TLS
{ name: "tls"; host: "localhost"; port: "443"; log_level: 0;},
# Jabber
{ name: "regex"; host: "localhost"; port: "5222"; regex_patterns: [ "jabber" ]; log_level: 1;},
{ name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "jabber" ]; log_level: 0;},
# Catch-all
{ name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "" ]; log_level: 0;}
);
on-timeout: "timeout";
Once complete, you must also set
RUN=yes in the /etc/default/sslh file.
Web Server ChangesSince SSLH needs to use port 443 on the server's network interface, you must set your web server to listen to the loopback interface for any host that is using port 443. Using Nginx
When using nginx, you must change all entries that are listening on the https port (443) to use the localhost interface and not the same interface SSLH is attached to.
In the below example, the IPv4 host is changed to localhost, and the IPv6 host is changed to ::1 .
server {
listen localhost:443 ssl http2;
listen [::1]:443 ssl http2;
server_name im.example.com;
server_name conference.example.com;
server_name upload.example.com;
This must be done for EVERY entry within nginx. Changes to be made on the XMPP Server ejabberd Changes
By default, ejabberd should already be configured to allow XEP-0368 connects. You may confirm that required sections are enabled.
Default XMPP client port
listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
starttls_required: true
shaper: c2s_shaper
access: c2s
Direct-TLS XMPP client port
-
port: 5223
ip: "::"
module: ejabberd_c2s
tls: true
shaper: c2s_shaper
access: c2s
Prosody Changes
Prosody needs to allow connections from clients via TLS (not STARTTLS). This is done by enabling legacy SSL support by adding the below line in the global section of your prosody.cfg.lua:
legacy_ssl_ports = 5223;
DNS Changes
And finally, we need to make the required DNS Changes.
The XEP-0368[3] states that
In this example, the XMPP host (im.example.org) is listening for clients on ports 5223, 5222, and 443.
# Clients will try in the following order, 5223/tls, 5222/xmpp, 443/tls
_xmpps-client._tcp.example.org. 86400 IN SRV 5 1 5223 im.example.org.
_xmpp-client._tcp.example.org. 86400 IN SRV 10 1 5222 im.example.org.
_xmpps-client._tcp.example.org. 86400 IN SRV 15 1 443 im.example.org.
_xmpp-client._tcp.example.org. 86400 IN SRV 20 1 443 im.example.org.
The client will first try to connect to port 5223, if it is unable to, it will then try port 5222, if it is unable to, it will then try port 443. Testing References
"XEP-0368: SRV records for XMPP over TLS § Introduction". 2017-03-09. Retrieved 2017-08-05. "Installing Prosody § XMPP over HTTPS". Retrieved 2017-08-05.
"XEP-0368: SRV records for XMPP over TLS § Requirements". 2017-03-09. Retrieved 2017-08-05.
Notes
XEP-0368: SRV records for XMPP over TLS Installing Prosody - XMPP over HTTPS Implement xep-0368 SRV records for xmpp over tls