Openfire Logo

Trunking Guide

Introduction

Openfire can be configured to act as a gateway to transfer data between other XMPP domains. This document covers what the use-cases for such a setup, how to configure this functionality, and what known caveats with this approach are.

The following sections are available in this document:

Use cases

The trunking functionality of Openfire is typically used in one of two scenarios:

  1. Connection Mediation (allow data to flow between remote XMPP domains)
  2. Data Monitoring / Filtering (ensure that only allowable data enters or leaves an XMPP domain

Use Case: Connection Mediation

The architecture of an XMPP network is similar to email; anyone can run their own XMPP domain and there is no central master domain. This federated open system approach allows users to interoperate with others on any domain. When users of one domain address data to users of another domain, servers of each domain will establish point-to-point connections between each-other, over which the data is exchanged. Multiple domains connecting to each other in a point-to-point manner creates a mesh-style network, as illustrated in figure 1.

Hub-and-Spoke Network
Figure 2 - Hub-and-Spoke Network.
Mesh-style Network
Figure 1 - Mesh-style Network.

In certain environments, it is undesirable to have a mesh-style network. When, for example, it is hard or undesirable to create and maintain many technical connections, or when central auditing of data is desirable (see Use Case: Data Monitoring / Filtering), then a Hub-and-Spoke network model, as shown in figure 2 is often a better fit than a mesh-style network. The main advantage of this style is that all domains only need to create and maintain a single connection to a single entity: the central hub. This central hub manages and passes through connections between all domains.

To facilitate a Hub-and-Spoke approach with XMPP domains, the Trunking functionality of Openfire can be used. With this functionality enabled, an Openfire instance can act as the central 'hub' in such a network. In this mode, it can create and accept server-to-server connections with each individual XMPP domain in the network, passing stanzas from one domain to another, and vice versa.

Use Case: Data Monitoring / Filtering

Openfire, in trunking mode, can be deployed as a border filtering device, to check the releasability of data that is exposed from within one network to another.

A common scenario is one where a trusted network labels messages that are exchanged with a security label (as defined in XEP-0258: Security Labels in XMPP for example) that define the confidentiality of the content of the message. An Openfire trunk can be placed between two networks of domains that each have a different security clearance. The trunking Openfire server can filter data (through a plugin), ensuring that only appropriately labelled messages are exchanged between the XMPP domains, rejecting, for example, messages labelled 'TOP SECRET' sent from an internal XMPP domain to an unrecognized or untrusted XMPP domain.

Setup

The essence in getting an Openfire instance to act as a Trunking entity in your network is to have all other XMPP domains connect to this server, when they intend to connect to another remote domain. The Trunking entity needs to be configured to accept stanzas for the target domain. This is typically achieved through DNS manipulation. It will then process the data, and pass it on to the target domain.

The server that is sending the message will attempt to establish a server-to-server connection with the target server. The sending server perform DNS lookups based on the domain name of the target server. The results of this lookup must be manipulated in such a way that the resulting IP address is that of the trunking server. Openfire can facilitate such DNS manipulation, as it allows DNS lookups to be skipped in favor of preconfigured hard-coded values. To configure such values, the property dnsutil.dnsOverride can be used. Note that these changes are needed only on the server(s) that send data through the trunking server. The trunking server itself should not need them.

The expected format of the value of the dnsutil.dnsOverride property is a comma-sparated list of {HOST,IP:PORT}. Note that whitespace is not allowed, as shown in example 1:

Example 1: dnsutil.dnsOverride property value, mapping two hostnames to the same IP address and port. {saturn.example.org,198.51.100.4:5269},{jupiter.example.com,198.51.100.4:5269}

To enable the trunking functionality in Openfire, the property xmpp.gateway.enabled needs to be set to true, and the property xmpp.gateway.domains needs to be populated with a (comma-separated) list of XMPP domain names of remote XMPP domains that the Openfire server will forward data to.

Full example

Let us imagine three XMPP domains, each domain consisting of one Openfire server. For simplicity's sake, we assume that the fully qualified domain name of each server is equal to the XMPP domain name that it serves:

  • saturn.example.org (203.0.113.2)
  • trunk.example.com (198.51.100.4)
  • mercury.example.net (233.252.0.6)

The objective of this example is to allow users of the domains saturn.example.org and mercury.example.net to exchange XMPP stanzas without their servers creating direct connections to each-other, instead using trunk.example.com as a gateway. To achieve this, the following three steps are needed:

  1. Openfire at trunk.example.com needs to be configured to allow trunking to both XMPP domains. To achieve this, it's property xmpp.gateway.domains is configured to use this value: saturn.example.org,mercury.example.net

  2. When a user of saturn.example.org sends a stanza to one of the users of mercury.example.net, saturn.example.org will attempt to establish a server-to-server connection to mercury.example.net. The objective here is to ensure that saturn.example.org is made to believe that the IP address of mercury.example.net is 198.51.100.4, instead of its actual address 233.252.0.6. This will cause the server-to-server connection to be established to trunk.example.org instead of to mercury.example.net. To this end, the property dnsutil.dnsOverride is configured with the following value on saturn.example.org: {mercury.example.net,198.51.100.4:5269}

    Illustration of usage of DNS override.
    Figure 3: DNS override of mercury's IP address as observed by saturn.
  3. Typically, users will want to be able to respond to messages that they receive. To allow users of mercury.example.net to send back messages to users of saturn.example.org, a configuration change needs to be applied on mercury.example.net: it needs to resolve the IP address of saturn.example.org to a value that equals that of the trunking server: 198.51.100.4. Similar to what was done on the other server, the property dnsutil.dnsOverride on mercury.example.net is configured with the value: {saturn.example.org,198.51.100.4:5269}

These steps are all that is needed to finish the configuration in this basic example. Both servers will connect to the trunk when sending data to each-other. The trunk (which does not override DNS using the dnsutil.dnsOverride property) will accept the stanzas from either server, and route them to the intended target server.

Caveats

Openfire was originally not specifically designed for trunking functionality. This introduces a couple of caveats.