XMPP over TLS (formerly XEP-0368) is a clever mechanism that allows users to connect to a XMPP server from networks that restrict outgoing traffic only to specific ports; this block is circumvent by routing XMPP traffic via port TCP 443.
If the server hosts only a XMPP server setting up XMPP over TLS is pretty easy, just instruct the server to listen on port 443.
If the server also runs a webserver which is listening on port 443 things are a bit more complicated; luckily Nginx provides a way to manage XMPP traffic and redirect it to the XMPP server.


$ cat /etc/nginx/nginx.conf

stream {
    upstream httpserver {
        server localhost:8443;   # webserver_host:webserver_port
    }

    upstream xmppserver {
        server localhost:5223;   # xmpp_server_host:xmpp_over_tls_port
    }

    map $ssl_preread_alpn_protocols $upstream {
        default httpserver;
        "xmpp-client" xmppserver;
    }

    server {
        listen 443;

        ssl_preread on;
        proxy_pass $upstream;
    }
}

Also be sure to change Nginx virtual hosts accordingly, those should listen to port TCP 8443 instead of the usual TCP 443.


$ cat /usr/local/etc/ejabberd/ejabberd.yml

listen:
  -
    port: 5223
    ip: "::"
    module: ejabberd_c2s
    max_stanza_size: 65536
    shaper: c2s_shaper
    access: c2s
    tls: true

scheme: _service._proto.name TTL class SRV priority weight port target

_xmpps-client._tcp.example.org. 86400 IN SRV 5  0 443  xmpp.example.org.
_xmpp-client._tcp.example.org.  86400 IN SRV 10 0 443  xmpp.example.org.
_xmpp-client._tcp.example.org.  86400 IN SRV 15 0 5222 xmpp.example.org.

$ semanage port -l | grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

Ejabberd should have no issues to bind port TCP 5223, the only thing left to do is create a SELinux module to allow Nginx from redirecting traffic from port TCP 443 to TCP 5223.
Be sure to have auditd service installed and running and also the package policycoreutils-python installed on your system.
To create a new SELinux module run:


$ ausearch -c 'nginx' --raw | audit2allow -M nginx-xmppovertls
$ semodule -i nginx-xmppovertls.pp