.ci | ||
contrib | ||
fuzz | ||
integration | ||
src | ||
.gitattributes | ||
.gitignore | ||
.rustfmt.toml | ||
Cargo.lock | ||
Cargo.toml | ||
LICENSE.md | ||
README.md | ||
xmpp-proxy.toml |
xmpp-proxy
xmpp-proxy is a reverse proxy and outgoing proxy for XMPP servers and clients, providing STARTTLS, Direct TLS, QUIC, and WebSocket connectivity to plain-text XMPP servers and clients and limiting stanza sizes without an XML parser.
xmpp-proxy in reverse proxy (incoming) mode will:
- listen on any number of interfaces/ports
- accept any STARTTLS, Direct TLS, QUIC, or WebSocket c2s or s2s connections from the internet
- terminate TLS
- connect them to a local real XMPP server over plain-text TCP
- send the PROXY protocol v1 header if configured, so the XMPP server knows the real client IP
- limit incoming stanza sizes as configured
xmpp-proxy in outgoing mode will:
- listen on any number of interfaces/ports
- accept any plain-text TCP connection from a local XMPP server or client
- look up the required SRV records
- connect to a real XMPP server across the internet over STARTTLS, Direct TLS, QUIC, or WebSocket
- fallback to next SRV target or defaults as required to fully connect
- perform all the proper required certificate validation logic
- limit incoming stanza sizes as configured
Installation
cargo install xmpp-proxy
- Download static binary from xmpp-proxy or xmpp-proxy (github mirror)
- your favorite package manager
Configuration
mkdir /etc/xmpp-proxy/ && cp xmpp-proxy.toml /etc/xmpp-proxy/
- edit
/etc/xmpp-proxy/xmpp-proxy.toml
as needed, file is annotated clearly with comments - put your TLS key/cert in
/etc/xmpp-proxy/
- Example systemd unit is provided in xmpp-proxy.service and locks it down with bare minimum permissions. Need to
set the permissions correctly:
chown -Rv 'systemd-network:' /etc/xmpp-proxy/
- start xmpp-proxy:
Usage: xmpp-proxy [/path/to/xmpp-proxy.toml (default /etc/xmpp-proxy/xmpp-proxy.toml]
How do I adapt my running Prosody config to use this instead?
You have 2 options here, use xmpp-proxy as only a reverse proxy, or as both reverse and outgoing proxy, I'll cover both:
Reverse proxy and outgoing proxy
In this mode both prosody doesn't need to do any TLS at all, so it needs no certs. xmpp-proxy need proper TLS
certificates, move prosody's TLS key to /etc/xmpp-proxy/le.key
and TLS cert to /etc/xmpp-proxy/fullchain.cer
, and
use the provided xmpp-proxy.toml
configuration as-is.
Edit /etc/prosody/prosody.cfg.lua
, Add these to modules_enabled:
"net_proxy";
"s2s_outgoing_proxy";
Until prosody-modules is updated, use my new module mod_s2s_outgoing_proxy.lua.
Add this config:
-- only need to listen on localhost
interfaces = { "127.0.0.1" }
-- we don't need prosody doing any encryption, xmpp-proxy does this now
-- these are likely set to true somewhere in your file, find them, make them false
-- you can also remove all certificates from your config
s2s_require_encryption = false
s2s_secure_auth = false
c2s_require_encryption = false
allow_unencrypted_plain_auth = true
-- xmpp-proxy outgoing is listening on this port, make all outgoing s2s connections directly to here
s2s_outgoing_proxy = { "127.0.0.1", 15270 }
-- handle PROXY protocol on these ports
proxy_port_mappings = {
[15222] = "c2s",
[15269] = "s2s"
}
-- don't listen on any normal c2s/s2s ports (xmpp-proxy listens on these now)
-- you might need to comment these out further down in your config file if you set them
c2s_ports = {}
legacy_ssl_ports = {}
-- you MUST have at least one s2s_ports defined if you want outgoing S2S to work, don't ask..
s2s_ports = {15268}
Reverse proxy only, prosody makes outgoing connections directly itself
In this mode both prosody and xmpp-proxy need proper TLS certificates, copy prosody's TLS key to /etc/xmpp-proxy/le.key
and TLS cert to /etc/xmpp-proxy/fullchain.cer
, and use the provided xmpp-proxy.toml
configuration as-is.
Edit /etc/prosody/prosody.cfg.lua
, Add these to modules_enabled:
"net_proxy";
"secure_interfaces";
Until prosody-modules is updated, use my patched version of mod_secure_interfaces.lua which also works for s2s.
Add this config:
-- trust connections coming to these IPs
secure_interfaces = { "127.0.0.1", "::1" }
-- handle PROXY protocol on these ports
proxy_port_mappings = {
[15222] = "c2s",
[15269] = "s2s"
}
-- don't listen on any normal c2s/s2s ports (xmpp-proxy listens on these now)
-- you might need to comment these out further down in your config file if you set them
c2s_ports = {}
legacy_ssl_ports = {}
-- you MUST have at least one s2s_ports defined if you want outgoing S2S to work, don't ask..
s2s_ports = {15268}
Customize the build
If you are a grumpy power user who wants to build xmpp-proxy with exactly the features you want, nothing less, nothing more, this section is for you!
xmpp-proxy has 5 compile-time features:
incoming
- enablesincoming_listen
config option for reverse proxy STARTTLS/TLSoutgoing
- enablesoutgoing_listen
config option for outgoing proxy STARTTLS/TLSquic
- enablesquic_listen
config option for reverse proxy QUIC, and QUIC support foroutgoing
if it is enabledwebsocket
- enables reverse proxy WebSocket onincoming_listen
, and WebSocket support foroutgoing
if it is enabledlogging
- enables configurable logging
So to build only supporting reverse proxy STARTTLS/TLS, no QUIC, run: cargo build --release --no-default-features --features incoming
To build a reverse proxy only, but supporting all of STARTTLS/TLS/QUIC, run: cargo build --release --no-default-features --features incoming,quic
License
GNU/AGPLv3 - Check LICENSE.md for details
Thanks rxml for afl-fuzz seeds
todo
- XEP for XMPP-over-QUIC and XMPP-S2S-over-WebSocket