* Ignores any events pushed without a room ID
* Removes needless clones for PDU size checking
* Removes incorrect ACL check in incoming handler
* Fast-path handling already handled outlier events
* Remove redundant same-room checks, replace with useful ones
* Combine event rejection and persistence in a single function
* Additional safety assertions in upgrade task
* Split upgrade task into multiple subroutines for reduced cognitive complexity
* Only mutate current state and forward extremities in tandem
* Improve code documentation to better explain the logic flow
This removes the old (broken) DNS caching method for reqwest, and replaces
it with resolvematrix' `MatrixDnsResolver`, as it correctly implements
caching and overrides for correct SNI behavior.
diff --git c/src/service/resolver/actual.rs i/src/service/resolver/actual.rs
index 9cd1aec15..495d83172 100644
--- c/src/service/resolver/actual.rs
+++ i/src/service/resolver/actual.rs
@@ -1,9 +1,5 @@
use std::fmt::Debug;
-use super::{
- cache::{CachedDest, CachedOverride, MAX_IPS},
- fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
-};
use conduwuit::{Err, Result, debug, debug_info, err, error, trace};
use futures::{FutureExt, TryFutureExt};
use hickory_resolver::{
@@ -15,9 +11,11 @@
use super::{
cache::{CachedDest, CachedOverride, MAX_IPS},
- fed::{FedDest, PortString, add_port_to_hostname, get_ip_with_port},
+ fed::{FedDest, PortString, add_port_to_hostname, ensure_host_has_port, get_ip_with_port},
};
+const DEFAULT_PORT: u16 = 8448;
+
#[derive(Clone, Debug)]
pub(crate) struct ActualDest {
pub(crate) dest: FedDest,
@@ -26,9 +24,7 @@ pub(crate) struct ActualDest {
impl ActualDest {
#[inline]
- pub(crate) fn string(&self) -> String {
- self.dest.https_string()
- }
+ pub(crate) fn string(&self) -> String { self.dest.https_string() }
}
impl super::Service {
@@ -75,7 +71,8 @@ pub async fn resolve_actual_dest(
// Ensure dest is a valid connection endpoint
self.validate_dest(dest)?;
- // Clippy believes this can be a clone, however we are actually converting ServerName to String
+ // Clippy believes this can be a clone, however we are actually converting
+ // ServerName to String
#[allow(clippy::implicit_clone)]
let mut host = dest.to_string().to_owned();
let actual_dest = self.resolve_server_name(dest, cache, &mut host).await?;
@@ -103,8 +100,8 @@ async fn resolve_server_name(
cache: bool,
host: &mut String,
) -> Result<FedDest> {
- // 1. If `dest` is an IP, use it directly. If a port is provided as well (IP:port socket pair)
- // use that, otherwise default to port 8448
+ // 1. If `dest` is an IP, use it directly. If a port is provided as well
+ // (IP:port socket pair) use that, otherwise default to port 8448
if let Some(fed_dest) = get_ip_with_port(dest.as_str()) {
debug!("1: IP literal with provided or default port");
return Ok(fed_dest);
@@ -117,8 +114,8 @@ async fn resolve_server_name(
.await?;
}
- // Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed either way
- // https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
+ // Pre-resolve IP? Unsure what overrides exactly do, system is due to be removed
+ // either way https://matrix.to/#/!da26JtAjE6APGLnX8ncWsvc-skF2KQZ9Nw_MbNpYD2k/%24_hq6JP0JXANbMTMPdV64iZbgbsZdhy92M5ndDYGy6No
self.conditional_query_and_cache(dest.as_str(), DEFAULT_PORT, true)
.await?;
@@ -126,7 +123,8 @@ async fn resolve_server_name(
self.services.server.check_running()?;
// 3. If `dest` is a hostname with no port, send GET to `https://<dest>/.well-known/matrix/server`.
- // If invalid JSON (throws error), skip to step 4. Otherwise, parse `delegated` as `<hostname>[:<port>]` and...
+ // If invalid JSON (throws error), skip to step 4. Otherwise, parse `delegated`
+ // as `<hostname>[:<port>]` and...
if let Some(delegated) = self.request_well_known(dest.as_str()).await? {
// delegated=matrix-federation.matrix.org:443 // host=matrix.org
self.resolve_3_well_known(host, cache, delegated).await?;
@@ -137,11 +135,13 @@ async fn resolve_server_name(
self.resolve_4_srv_lookup(host, cache, overrider).await?;
}
- // 5. if .well-known errored and no SRV exists, resolve IP and connect on default port (8448)
+ // 5. if .well-known errored and no SRV exists, resolve IP and connect on
+ // default port (8448)
self.resolve_5_direct(dest, cache).await
}
- /// Parse a host:port socket pair into separate parts, and resolve the hostname into an IP address
+ /// Parse a host:port socket pair into separate parts, and resolve the
+ /// hostname into an IP address
async fn resolve_2_host_port(
&self,
dest: &ServerName,
@@ -180,14 +180,16 @@ async fn resolve_3_well_known(
return Ok(host_and_port);
}
- // 3.2 - If <delegated> is not an IP and a port is present, lookup IP for hostname and connect
+ // 3.2 - If <delegated> is not an IP and a port is present, lookup IP for
+ // hostname and connect
if let Some(pos) = &delegated.find(':') {
self.resolve_3_2_hostname_port(cache, &delegated, *pos)
.await?;
}
- // 3.3 - If <delegated> is not an IP and there is no port, lookup SRV `_matrix._tcp.<delegated>`
- // (which may provide a new hostname + port to use, see steps 3.1 and 3.2)
+ // 3.3 - If <delegated> is not an IP and there is no port, lookup SRV
+ // `_matrix._tcp.<delegated>` (which may provide a new hostname + port to use,
+ // see steps 3.1 and 3.2)
trace!("Delegated hostname has no port, querying SRV");
if let Some(overrider) = self.query_srv_record(&delegated).await? {
self.resolve_3_3_use_srv(cache, &delegated, overrider)
@@ -342,17 +344,14 @@ async fn query_and_cache_override(
match self.resolver.resolver.lookup_ip(hostname.to_owned()).await {
| Err(e) => Self::handle_resolve_error(&e, hostname),
| Ok(override_ip) => {
- self.cache.set_override(
- untername,
- &CachedOverride {
- ips: override_ip.iter().take(MAX_IPS).collect(),
- port,
- expire: CachedOverride::default_expire(),
- overriding: (hostname != untername)
- .then_some(hostname.into())
- .inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
- },
- );
+ self.cache.set_override(untername, &CachedOverride {
+ ips: override_ip.into_iter().take(MAX_IPS).collect(),
+ port,
+ expire: CachedOverride::default_expire(),
+ overriding: (hostname != untername)
+ .then_some(hostname.into())
+ .inspect(|_| debug_info!("{untername:?} overridden by {hostname:?}")),
+ });
Ok(())
},
@@ -415,7 +414,8 @@ fn handle_resolve_error(err: &NetError, host: &'_ str) -> Result<()> {
}
}
- /// Ensure `dest` is a valid destination (valid ip if it is an IP), and not ourselves (unless in config)
+ /// Ensure `dest` is a valid destination (valid ip if it is an IP), and not
+ /// ourselves (unless in config)
fn validate_dest(&self, dest: &ServerName) -> Result<()> {
if dest == self.services.server.name && !self.services.server.config.federation_loopback {
return Err!("Won't send federation request to ourselves");
diff --git c/src/service/resolver/fed.rs i/src/service/resolver/fed.rs
index b43f62eed..83601a98a 100644
--- c/src/service/resolver/fed.rs
+++ i/src/service/resolver/fed.rs
@@ -9,8 +9,8 @@
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
pub enum FedDest {
- Literal(SocketAddr),
- Named(String, PortString),
+ Literal(SocketAddr), // "ip:port"
+ Named(String, PortString), // ("hostname", ":port")
}
/// numeric or service-name
@@ -18,6 +18,9 @@ pub enum FedDest {
const DEFAULT_PORT: &str = ":8448";
+/// Attempt to parse `dest_str` as either an IP:port socket pair or as a plain
+/// IP (adding the default port), returning `None` if dest_str is neither a
+/// socket pair nor a plain IP.
pub(crate) fn get_ip_with_port(dest_str: &str) -> Option<FedDest> {
if let Ok(dest) = dest_str.parse::<SocketAddr>() {
Some(FedDest::Literal(dest))
@@ -28,6 +31,8 @@ pub(crate) fn get_ip_with_port(dest_str: &str) -> Option<FedDest> {
}
}
+/// Convert a `dest` string with or without port into a FedDest with either
+/// the provided port (if host:port format) or the default port (8448)
pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
let (host, port) = match dest.find(':') {
| None => (dest, DEFAULT_PORT),
@@ -42,8 +47,8 @@ pub(crate) fn add_port_to_hostname(dest: &str) -> FedDest {
/// Ensure `host` always has a port
///
-/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain IP,
-/// in which case `add_port_to_hostname` adds it instead
+/// `get_ip_with_port` returns `None` if `host` isn't an IP:port string or plain
+/// IP, in which case `add_port_to_hostname` adds it instead
#[inline]
pub(crate) fn ensure_host_has_port(host: &str) -> FedDest {
get_ip_with_port(host).unwrap_or_else(|| add_port_to_hostname(host))
Previously the function assumed the caller had performed proper validation on the inputs (and all current callers do), but this is a poor reason to panic when sane error handling is available.
Events with no prev events now return an error, and prev events which are illegal are simply skipped.
Some servers reference events in prev_events that they might not yet have finished processing, so this allows us to at least attempt to get the state from another trustworthy server in the room that might be faster. I don't think this is too effective, however it's more effective than giving up immediately.
This may look scary, but this is safe because event auth performs the same check, and will reject the event if it doesn't reference the create event correctly.
tomfos.tr act-runner image removed the possibility to install the latest LLVM using an installer script, so let us also remove the detection and just live with the distro's clang image.
Untested
chore: Add news fragment
feat: Support stable policy servers
feat: Don't attempt erroneous loopback federation for policy server checks
refactor: Update PS upgrade to use new ruma
fix: Only check loopback via after attempting incoming verification
This allows for rooms to be created with a m.room.server_acl event by
default. This event can be thought of as part of the initial_state
events, although it is not provided by the client.
Implements #775
* Rename "Using a forwarder" to "Recursion vs forwarding"
* Un-highlight DoT and put it in the unbound.conf snippet
* Small wording improvements for Technitium section
* Highlights dns_cache_entries=0 recommendation above others
* docs: Move typing/readmarks disabling section up, and separate
outbound sending disablement from total disablement of features
* docs: Change introduction tone to "get more out of your server",
remove wrong notion of tuned for small instances
Fallback keys can be provided by client devices to be used in case the
supply of one-time keys run out. The server will store one fallback key
per user, per device, per algorithm. The server will keep track of
whether this fallback key has been used or not.
The /keys/claim endpoint now provides a fallback key
if no one-time key is found
The /keys/upload endpoint now accepts fallback keys
The /sync endpoint now informs the client of the algorithms for which it
has an unused fallback key in stock.
* Rename "You're done" to "Starting Your Server"
* Add instructions for initial registration token flow
* Shorten "How do I know it works" section
* Beautify "What's Next" section
* Link docker builds to section in dev pages
* Delete old section on port forwarding
* Create new section on port exposing, near reverse proxy section
* Rewrite Other Reverse Proxies section to update specified routes
* Move reverse proxy software caveats into its own subsection
* Other wording and structure fixes and improvements
* Use indirect URLs
* Change your.server.name to canonical example.com
* Put Getting help section in a tip admonition
* Remove statement on Caddy preference
* Clean up "What's next" section
* Use de facto unstasble path instead of the standard one
* Document both the unstable and well-known paths as being exposed by
Continuwuity when set
* Make curling said path one of the Testing steps
* Removing confusing console `~$` prefix symbols, move commands and
response into separate code blocks
* Number the MSCs
- enabling the `http3` features requires unstable features, namely `reqwest_unstable`
- the main suggestion of cargo is to enable this through RUSTFLAGS
- we had no way to customize RUSTFLAGS, now we do
- changed the max-perf package to showcase this feature
- also turn on http3 by default in both max-perf and the default build
(jade approved this)
Previously, we would push all tagged releases into the stable component,
including alphas and rc's. Let's use some regex to only push stable
releases which conform to tag "^v+\d\.+\d\.+\d$"
so we ONLY get the manually published releases into the stable
component.
All pre-releases go into the "unstable" component for now. Nightly builds
go into the "dev" component (as before) and feature branches still get
their dedicated component named after the branch.
TODO: It would be nifty if stable releases would ALSO be published at the
unstable component.
When running the mirror-images step from within the release-image workflow
we receive error messages such as
> msg="Failed to sync" target=ghcr.io/continuwuity/continuwuity:v0.5.0-rc.7
> source=forgejo.ellis.link/continuwuation/continuwuity:v0.5.0-rc.7
> error="failed to send blob post, ref
> ghcr.io/continuwuity/continuwuity@sha256:74976f7b85018b5abd867333bc783c7230d985a4b0af595bbf55964e25afe6ef:
> unauthorized"
So, we will need to define our credentials in the release-image workflow too
it seems, when we pull in the mirror-image workflow.
This is a test by adding all credentials that are defined in mirror-images.yml
Probably we don't need them all, but if this does not work, the whole approach
is flawed and we can remove everyting again.
If it works, we should remove unneccessary credentials until we found the
required ones.
Blind attempt at fixing the:
> 'runs-on' key not defined in Release Docker Image/merge-release
> 'runs-on' key not defined in Release Docker Image/merge-maxperf
Errors in the release-image CI
Run it once a night for regular cleanup etc and after each release-image
workflow instead of doing it blindly every 2 hours.
This will only run the mirror job if BOTH build types were
successful, but it is better than nothing, and we have the nightly run
to pick up everything else.
Thanks @jade for the quick feedback and hand-holding in creating this.
.well-known env var in example composes now point to `example.com:443`,
and are turned on by default for Caddy labels and the Traefik configs.
For the Caddyfile example, they're left uncommented. Added small
bulletpoint on how to use this env var. Consistencize all the
.well-known comments inside these composes.
I don't want to overly fix the example composes and get it wrong, so
this small change should be enough. Split-domain deployments are fully
outsourced to the Delegation page now, and some changes are also made
there to be more comprehensive.
Instead of /etc/resolv.conf on host. This works around the
systemd-resolved footgunning issue and provide an inline way to
configure resolvers, separate from that of the host system.
* Also add a note disclaiming that Docker is for demo purposes only
* Use port 8008 for Docker Quick Run instructions
* Remove the steps to create first admin user
I do believe "Docker - Quick Run" should be moved to after Docker
Compose section, but will want to discuss this before advancing
* Move all *.yml files to docs/public/deploying so they can be viewable
as raw files on the webpage
* Link to those files with "(view raw)"
* Move minimal environment variables to Docker Compose section
* Unheading the Docker Quick Run stuff to prepare deprioritizing them
* Remove redundant Registry column in Image table
* Rename reverse proxy subsections to have software name as first word
* Add compose and included Caddyfile using caddy:latest official image
* Rename old Caddy files as caddy-labels.yml and new one as caddy.yml
* Remove external: true network in caddy-labels.yml to simplify docs
* Move all Caddy selections to top, unprioritize Traefik and other RPs
Included some additional comments. .well-known Delegation seems to be
much more convenient for traefik + caddy. How they're documented can be
decided in a future commit.
* Remove unnecessary c10y env vars
* Remove unnecessary comment about image build and vim
* Remove references to Element-Web
Other changes like unified port and domain names will be in a future
commit
* docs: "Docker - Quick Run" and "Docker Compose" are now two top-level
sections
* docs: Mark building your images as "(Optional)"
* docs: Move calls to "Next step" section
* docs: Make "Available Images" a top-level option, to be followed by
Docker and Docker Compose sections in a future commit
* docs: Make "Mirrors" a subsection of "Available images", and add
links to the mirrors themselves
* docs: Use indirect linkages to URLs for better maintainability
* docs: Remove initial sentence and its reference to the (advanced)
building your image flow
* docs: Recommend `latest` OCI tag and include link to
- Added support for linking an external identity provider with OIDC. Contributed by @ginger. (#765)
- Updated [MSC4284: Policy Servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) implementation to support the newly stabilised proposal. Contributed by @nex. (#1487)
- Added config option for default room ACLs. Contributed by @eve. (#1691)
- Added support for fallback encryption keys. (#1710)
- Add `!admin users reject-all-invites` to clean invite spam (#1741)
- Implemented event rejection, which should resolve and prevent future netsplits of the kinds observed
within some Continuwuity rooms.
Also resolved several bugs related to both soft-failing events, and event backfilling, which should
improve state resolution stability.
The `!admin debug get-pdu` command was updated to disambiguate event acceptance status, and
`!admin debug show-auth-chain` was added to visually display event auth chains, which may assist
developers in debugging strangely complex events.
Contributed by @nex. (#1747)
- Added full support for [MSC4168: Update `m.space.*` state on room upgrade](https://github.com/matrix-org/matrix-spec-proposals/pull/4168). Contributed by @nex. (#1807)
- Improved the performance and reliability of fetching missing events, improving network partition recovery. Contributed
by @nex. (#1818)
- Added static builds using Nix, allowing for Continuwuity on musl. During this, we also introduced a `max-perf-haswell` package, separating it from `max-perf`, so you may want to swap to this if you are on NixOS. Contributed by @Henry-Hiles (QuadRadical). (#1853)
- Added support for MSC4380 invite blocking, which has become part of the Matrix specification in v1.18. Contributed by @nex. (#1875)
- Added a configuration option to allow choosing a client IP source that is not the TCP connecting IP. Contributed by @nex. (#1931)
- Added support for MSC4466, which allows clients to customize how changes to a user's global profile are propagated. Contributed by @ginger.
- Added support for Matrix 1.16's `state_after` feature, allowing clients which understand it to sync room state changes more reliably. Contributed by @ginger.
- Added support for authenticating clients using the new OAuth 2.0 login API. Contributed by @ginger.
- Appservice device management as outlined in MSC4190 (part of Matrix 1.17) is now fully supported. Contributed by @ginger.
- Users may now be forbidden from deactivating their own accounts with the new `allow_deactivation` config option. Contributed by @ginger.
## Bugfixes
- Adjusted legacy sync logic to allow the `roomsynctoken_shortstatehash` database column to be dropped, massively reducing database sizes, especially for old deployments. Contributed by @ginger. (#917)
- Fixed a bug that caused the server to drop events during processing if several events for the same room were sent in a singular transaction. Contributed by @nex. (#1711)
- fix `!admin query account-data account-data-get` not returning the content (#1742)
- Fixed an issue where Continuwuity would only advertise support for the unstable endpoint for Mutual Rooms (MSC2666), despite only supporting the stable endpoint. Contributed by @Henry-Hiles (QuadRadical) (#1752)
- Fixed admin commands being ignored when they had leading whitespace before admin commands. Contributed by @kitvonsnookerz. (#1804)
- Fixed several bugs in the `POST /_matrix/client/v3/rooms/{roomId}/upgrade` endpoint. Contributed by @nex. (#1807)
- Devices which set their presence as "offline" will no longer be considered for presence updates. Contributed by @timedout.
- Improved invite and join reliability in clients using legacy sync. Contributed by @ginger
- The invite recipient's membership event is now included in invite stripped state, which should fix flaky invite display in some clients. Contributed by @ginger
## Improved Documentation
- Add performance tuning documentation. Contributed by @stratself. (#1498)
- Explain accessing Continuwuity's server console when deployed via Docker. (#1671)
- Clarified in the config that `max_request_size` affects federated media as well. (#1706)
- Added example configuration using caddy-docker-proxy in the livekit setup section of the docs. Contributed by @Cease (#1762)
- Updated deployment docs to account for new RPM package availability across more distros. Contributed by @julian45. (#1912)
## Deprecations and Removals
- Removed support for LDAP. (#1701)
- Removed support for guest user registration, a little-used and deprecated approach to room previews.
- Removed the `/_conduwuit/` versions of the `local_user_count` and `version` routes. These routes are still accessible under the `/_continuwuity` prefix.
- Support for server-side blurhashing (part of MSC2448) has been removed.
- The deprecated `well_known.rtc_focus_server_urls` config option has been removed. MatrixRTC foci should be configured using the `matrix_rtc.foci` config option.
## Misc
- #1505, #1829, #1927, #1933, #1934
- Switched from Continuwuity's fork of Ruma back to upstream Ruma. Contributed by @ginger.
- The version of Debian that the Docker-based build process uses has been upgraded from Bookworm to Trixie, meaning that standalone binaries now have a minimum glibc of 2.41, and can no longer be used on distro versions from before 2025-01-30
# Continuwuity 0.5.8 (2026-04-24)
## Features
- LDAP can now optionally be connected to using StartTLS, and you may unsafely skip verification. Contributed by @getz (#1389)
- Users will now be prevented from removing their email if the server is configured to require an email when registering an account.
## Bugfixes
- Fixed a situation where multiple email addresses could be associated with one user when that user changes their email address.
## Improved Documentation
- Updated config docs to state we support room version 12, and set it as default. Contributed by @ezera. (#1622)
- Improve instructions for generic deployments, removing unnecessary parts and documenting the new initial registration token flow. Contributed by @stratself (#1677)
# Continuwuity v0.5.7 (2026-04-17)
## Features
- Re-added support for reading registration tokens from a file. Contributed by @ginger and @benbot. (#1371)
- Add new config option to allow or disallow search engine indexing through a `<meta ../>` tag. Defaults to blocking indexing (`content="noindex"`). Contributed by @s1lv3r and @ginger. (#1527)
- Add new config option for [MSC4439](https://github.com/matrix-org/matrix-spec-proposals/pull/4439)
PGP key URIs. Contributed by LogN. (#1609)
- Added `!admin users reset-push-rules` command to reset the notification settings of users. Contributed by @nex. (#1613)
- Notification pushers are now automatically removed when their associated device is. Admin commands now exist for manual cleanup too. Contributed by @nex. (#1614)
- Implemented option to deprioritize servers for room join requests. Contributed by @ezera. (#1624)
- Added admin commands to get build information and features. Contributed by @Jade (#1629)
- Added support for associating email addresses with accounts, requiring email addresses for registration, and resetting passwords via email. Contributed by @ginger
- Added support for requiring users to accept terms and conditions when registering.
- Added support for using an admin command to issue self-service password reset links.
## Bugfixes
- Fixed corrupted appservice registrations causing the server to enter a crash loop. Contributed by @nex. (#1265)
- Prevent removing the admin room alias (`#admins`) to avoid accidentally breaking admin room functionality. Contributed by @0xnim (#1448)
- Stripped `join_authorised_via_users_server` from json if user is already in room (@partha:cxy.run) (#1542)
- Fixed internal server errors for fetching thumbnails. Contributed by @PerformativeJade (#1572)
- Fixed error 500 when joining non-existent rooms. Contributed by @ezera. (#1579)
- Refactored nix package. Breaking, since `all-features` package no longer exists. Continuwuity is now built with jemalloc and liburing by default. Contributed by @Henry-Hiles (QuadRadical). (#1596)
- Fixed resolving IP of servers that only use SRV delegation. Contributed by @tulir. (#1615)
- Fixed "Sender must be a local user" error for make_join, make_knock, and make_leave federation routes. Contributed by @nex. (#1623)
- Fixed restricted joins not being signed when we are being used as an authorising server. Contributed by @nex, reported by [vel](matrix:u/vel:nhjkl.com?action=chat). (#1630)
- Fixed room alias deletion so removing one local alias no longer removes other aliases from room alias listings.
- Stopped left rooms from being unconditionally sent on initial sync, hopefully fixing spurious appearances of left rooms in some clients (and making sync faster as a bonus). Contributed by @ginger
- Correct the response field name for MatrixRTC transports. Contributed by @spaetz
## Improved Documentation
- Added Testing and Troubleshooting instructions for Livekit documentation. Contributed by @stratself. (#1429)
- Refactored docker docs to include new initial token workflow, and add Caddyfile example. Contributed by @stratself. (#1594)
- Add DNS tuning guide for Continuwuity. Users are recommended to set up a local caching resolver following the guide's advice. Contributed by @stratself (#1601)
## Misc
- Fixed compiler warning in cf_opts.rs when building in release. Contributed by @ezera. (#1620)
Added support for associating email addresses with accounts, requiring email addresses for registration, and resetting passwords via email. Contributed by @ginger
Stopped left rooms from being unconditionally sent on initial sync, hopefully fixing spurious appearances of left rooms in some clients (and making sync faster as a bonus). Contributed by @ginger
Add new config option to allow or disallow search engine indexing through a `<meta ../>` tag. Defaults to blocking indexing (`content="noindex"`). Contributed by @s1lv3r and @ginger.
Refactored nix package. Breaking, since `all-features` package no longer exists. Continuwuity is now built with jemalloc and liburing by default. Contributed by @Henry-Hiles (QuadRadical).
Fixed restricted joins not being signed when we are being used as an authorising server. Contributed by @nex, reported by [vel](matrix:u/vel:nhjkl.com?action=chat).
LiveKit provides a utility to generate secure random keys
```bash
~$ docker run --rm livekit/livekit-server:latest generate-keys
API Key: APIUxUnMnSkuFWV
API Secret: t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
docker run --rm livekit/livekit-server:latest generate-keys
# API Key: APIUxUnMnSkuFWV
# API Secret: t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
```
:::
@@ -91,7 +91,7 @@ ### 3. Telling clients where to find LiveKit
To tell clients where to find LiveKit, you need to add the address of your `lk-jwt-service` to the `[global.matrix_rtc]` config section using the `foci` option.
The variable should be a list of servers serving as MatrixRTC endpoints. Clients discover these via the `/_matrix/client/v1/rtc/transports` endpoint (MSC4143).
The variable should be a list of servers serving as MatrixRTC endpoints. Replace the URL with the address you are deploying your instance of lk-jwt-service to:
```toml
[global.matrix_rtc]
@@ -100,7 +100,10 @@ ### 3. Telling clients where to find LiveKit
]
```
Remember to replace the URL with the address you are deploying your instance of lk-jwt-service to.
This will expose LiveKit information on the following endpoints for clients to discover:
# add additional environment, volume, and network config here...
labels:
caddy: matrix.example.com
caddy.reverse_proxy: "{{upstreams 8008}}"
```
</details>
@@ -210,7 +288,7 @@ ### add these to livekit's docker-compose ###
### if you're using `network_mode: host`, you can skip this part
```
Recreate the LiveKit container (with `docker-compose up -d livekit`) to apply these changes. Remember to allow the new `3478/udp` and `50100:50200/udp` ports through your firewall.
Recreate the LiveKit container (with `docker-compose up -d livekit`) to apply these changes. Remember to allow the new `3478/udp` and `50300:50400/udp` ports through your firewall.
### Integration with an external TURN server
@@ -253,15 +331,29 @@ # livekit.yaml
## Testing
To test that LiveKit is successfully integrated with Continuwuity, you will need to replicate its [Token Exchange Flow](https://github.com/element-hq/lk-jwt-service#%EF%B8%8F-how-it-works--token-exchange-flow).
To test that LiveKit is successfully integrated with Continuwuity, you will need to replicate its [Token Exchange Flow](https://github.com/element-hq/lk-jwt-service#%EF%B8%8F-how-it-works--token-exchange-flow). Follow the steps below while checking Docker logs (`docker-compose logs --follow`), in order to help [troubleshooting](#troubleshooting) any issues.
First, you will need an access token for your current login session. These can be found in your client's settings or obtained via [this website](https://timedout.uk/mxtoken.html).
Then, using that token, request another OpenID token for use with the lk-jwt-service:
Then, using that token, fetch the discovery endpoints for MatrixRTC services:
```bash
~$ curl -X POST -H "Authorization: Bearer <session-access-token>" \
The lk-jwt-service will, after checking against Continuwuity, answer with a `jwt` token to create a LiveKit media room. Use this token to test at the [LiveKit Connection Tester](https://livekit.io/connection-test). If everything works there, then you have set up LiveKit successfully!
Use this token to test at the [LiveKit Connection Tester](https://livekit.io/connection-test). If everything works there, then you have set up LiveKit successfully!
## Troubleshooting
To debug any issues, you can place a call or redo the Testing instructions, and check the container logs for any specific errors. Use `docker-compose logs --follow` to follow them in real-time.
To debug any issues, you can place a call or redo the Testing instructions, and check the container logs for any specific errors. Use `docker-compose logs --follow` to follow these logs in real-time.
### Common errors in Element Call UI
- `MISSING_MATRIX_RTC_FOCUS`: LiveKit is missing from Continuwuity's config file
- "Waiting for media" popup always showing: a LiveKit URL has been configured in Continuwuity, but your client cannot connect to it for some reason
For browser-based clients, you can also inspect connections using DevTools' Networking tab, to see which requests are erroring out.
### Docker loopback networking issues
Some distros do not allow Docker containers to connect to its host's public IP by default. This would cause `lk-jwt-service` to fail connecting to `livekit` or `continuwuity` on the same host. As a result, you would see connection refused/connection timeouts log entries in the JWT service, even when `LIVEKIT_URL` has been configured correctly.
You can also test that this is the case by cURLing from a sidecar container:
```bash
docker run --rm --net container:lk-jwt-service docker.io/curlimages/curl https://livekit.example.com
# --- some errors ---
```
To alleviate this, you can try one of the following workarounds:
- Use `network_mode: host` for the `lk-jwt-service` container (instead of the default bridge networking).
- Add an `extra_hosts` file mapping livekit's (and continuwuity's) domain name to a localhost address:
- Add an `extra_hosts` file mapping livekit's (and continuwuity's) domain name to a locally-reachable address:
- (**untested, use at your own risk**) Implement an iptables workaround as shown [here](https://forums.docker.com/t/unable-to-connect-to-host-service-from-inside-docker-container/145749/6).
After implementing the changes and restarting your compose, you can test whether the connection works by cURLing from a sidecar container:
```bash
~$ docker run --rm --net container:lk-jwt-service docker.io/curlimages/curl https://livekit.example.com
OK
```
After implementing the changes and restarting your compose, `lk-jwt-service` should now connect to your other services. The sidecar container test above should now return an `OK` from LiveKit.
This chapter describes various ways to configure Continuwuity.
## Basics
## Configuration file
Continuwuity uses a config file for the majority of the settings, but also supports
setting individual config options via commandline.
Continuwuity uses a TOML config file for all of its settings. This is the recommended way to configure Continuwuity. Please refer to the [example config file](./reference/config.mdx) for all of these settings.
Please refer to the [example config
file](./reference/config.mdx) for all of those
settings.
You can specify the config file to be used by Continuwuity with the command-line flag `-c` or `--config`:
The config file to use can be specified on the commandline when running
Continuwuity by specifying the `-c`, `--config` flag. Alternatively, you can use
the environment variable `CONTINUWUITY_CONFIG` to specify the config file to be
used; see [the section on environment variables](#environment-variables) for
more information.
```bash
./conduwuit -c /path/to/continuwuity.toml
```
## Option commandline flag
Alternatively, you can use the environment variable `CONTINUWUITY_CONFIG` to specify the config file to be used; see [the section on environment variables](#environment-variables) for more information.
Continuwuity supports setting individual config options in TOML format from the
`-O` / `--option` flag. For example, you can set your server name via `-O
server_name=\"example.com\"`.
## Environment variables
All of the options in the config file can also be specified by using environment variables. This is ideal for containerised deployments and infrastructure-as-code scenarios.
The environment variable names are represented in all caps and prefixed with `CONTINUWUITY_`. They are mapped to config options in the ways demonstrated below:
```bash
# Top-level options (those inside the [global] section) are simply capitalised
For backwards compatibility, Continuwuity also supports the following environment variable prefixes, in order of descending priority:
- `CONDUWUIT_*` (compatibility)
- `CONDUIT_*` (legacy)
As an example, the environment variable `CONTINUWUITY_CONFIG` can also be expressed as `CONDUWUIT_CONFIG` or `CONDUIT_CONFIG`.
## Option command-line flag
Continuwuity also supports setting individual config options in TOML format from the `-O` / `--option` flag. For example, you can set your server name via `-O server_name=\"example.com\"`.
Note that the config is parsed as TOML, and shells like `bash` will remove quotes. Therefore, if the config option is a string, quote escapes must be properly handled. If the config option is a number or a boolean, this does not apply.
Note that the config is parsed as TOML, and shells like bash will remove quotes.
So unfortunately it is required to escape quotes if the config option takes a
string. This does not apply to options that take booleans or numbers:
- `--option allow_registration=true` works ✅
- `-O max_request_size=99999999` works ✅
- `-O server_name=example.com` does not work ❌
- `--option log=\"debug\"` works ✅
- `--option server_name='"example.com'"` works ✅
## Execute commandline flag
## Order of priority
Continuwuity supports running admin commands on startup using the commandline
argument `--execute`. The most notable use for this is to create an admin user
on first startup.
The above configuration methods are prioritised, in descending order, as below:
The syntax of this is a standard admin command without the prefix such as
`./conduwuit --execute "users create_user june"`
- Command-line `-o`/`--option` flags
- Environment variables
- `CONTINUWUITY_*` variables
- `CONDUWUIT_*` variables
- `CONDUIT_*` variables
- Config file
An example output of a success is:
```
Therefore, you can use environment variables or the options flags to override values in the config file.
---
## Executing startup commands
Continuwuity supports running admin commands on startup using the command-line flag `--execute`. This is treated as a standard admin command, without the need for the `!admin` prefix. For example, to create a new user:
```bash
# Equivalent to `!admin users create_user june`
./conduwuit --execute "users create_user june"
INFO conduwuit_service::admin::startup: Startup command #0 completed:
Created user with user_id: @june:girlboss.ceo and password: `<redacted>`
```
This commandline argument can be paired with the `--option` flag.
Alternatively, you can configure `CONTINUWUITY_ADMIN_EXECUTE` or the config file value `admin_execute` with a list of commands.
## Environment variables
All of the settings that are found in the config file can be specified by using
environment variables. The environment variable names should be all caps and
prefixed with `CONTINUWUITY_`.
For example, if the setting you are changing is `max_request_size`, then the
environment variable to set is `CONTINUWUITY_MAX_REQUEST_SIZE`.
To modify config options not in the `[global]` context such as
`[global.well_known]`, use the `__` suffix split:
`CONTINUWUITY_WELL_KNOWN__SERVER`
Conduit and conduwuit's environment variables are also supported for backwards
compatibility, via the `CONDUIT_` and `CONDUWUIT_` prefixes respectively (e.g.
`CONDUIT_SERVER_NAME`).
This command-line argument can be paired with the `--option` flag.
CONTINUWUITY_SERVER_NAME:your.server.name.example# EDIT THIS
CONTINUWUITY_TRUSTED_SERVERS:'["matrix.org"]'
CONTINUWUITY_ALLOW_REGISTRATION:'false'# After setting a secure registration token, you can enable this
CONTINUWUITY_REGISTRATION_TOKEN:""# This is a token you can use to register on the server
#CONTINUWUITY_REGISTRATION_TOKEN_FILE: "" # Alternatively you can configure a path to a token file to read
CONTINUWUITY_ADDRESS:0.0.0.0
CONTINUWUITY_PORT:6167# you need to match this with the traefik load balancer label if you're want to change it
CONTINUWUITY_DATABASE_PATH:/var/lib/continuwuity
#CONTINUWUITY_CONFIG: '/etc/continuwuity.toml' # Uncomment if you mapped config toml above
### Uncomment and change values as desired, note that Continuwuity has plenty of config options, so you should check out the example example config too
# Available levels are: error, warn, info, debug, trace - more info at: https://docs.rs/env_logger/*/env_logger/#enabling-logging
# CONTINUWUITY_LOG: info # default is: "warn,state_res=warn"
# CONTINUWUITY_ALLOW_ENCRYPTION: 'true'
# CONTINUWUITY_ALLOW_FEDERATION: 'true'
# CONTINUWUITY_ALLOW_CHECK_FOR_UPDATES: 'true'
# CONTINUWUITY_ALLOW_INCOMING_PRESENCE: true
# CONTINUWUITY_ALLOW_OUTGOING_PRESENCE: true
# CONTINUWUITY_ALLOW_LOCAL_PRESENCE: true
# CONTINUWUITY_WORKERS: 10
# CONTINUWUITY_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
- `git.nexy7574.co.uk/mirrored/continuwuity` (releases only, no `main`)
### Quick Run
Get a working Continuwuity server with an admin user in four steps:
#### Prerequisites
### Prerequisites
Continuwuity requires HTTPS for Matrix federation. You'll need:
- A domain name pointing to your server
- A reverse proxy with SSL/TLS certificates (Traefik, Caddy, nginx, etc.)
- A domain name pointing to your server's IP address - we will be using `example.com` in this guide.
- A reverse proxy with SSL/TLS certificates (Traefik, Caddy, nginx, etc.) - see [Docker Compose](#docker-compose) for complete examples.
- Port `:443` (for Client-Server traffic) and `:8448` (for federation traffic) opened on your server's firewall.
See [Docker Compose](#docker-compose) for complete examples.
- Alternatively, if you want both client and federation traffic on `:443`, you can configure `CONTINUWUITY_WELL_KNOWN` following some of the [examples](#choose-your-reverse-proxy) below.
#### Environment Variables
- `CONTINUWUITY_SERVER_NAME` - Your Matrix server's domain name
- `CONTINUWUITY_DATABASE_PATH` - Where to store your database (must match the
volume mount)
- `CONTINUWUITY_ADDRESS` - Bind address (use `0.0.0.0` to listen on all
interfaces)
- `CONTINUWUITY_ALLOW_REGISTRATION` - Set to `false` to disable registration, or
use with `CONTINUWUITY_REGISTRATION_TOKEN` to require a token (see
Docker's default DNS resolver can cause performance issues with Matrix
federation. If you experience slow federation or DNS timeouts, you may need to
use your host's DNS resolver instead. Add this volume mount to the
`continuwuity` service:
```yaml
volumes:
- /etc/resolv.conf:/etc/resolv.conf:ro
```
See [Troubleshooting - DNS Issues](../troubleshooting.mdx#potential-dns-issues-when-using-docker)
for more details and alternative solutions.
:::tip Split-domain setups
For more setups with `.well-known` delegation and split-domain deployments, consult the [Delegation/Split-domain](../guides/delegation) page.
:::
##### For existing Traefik setup
## Docker Compose
Docker Compose is the recommended deployment method for Continuwuity containers. The following environment variables will be set:
- `CONTINUWUITY_SERVER_NAME` - Your Matrix server's domain name. **This CANNOT be changed later without a data wipe.**
- `CONTINUWUITY_DATABASE_PATH` - Where to store your database. This must match the docker volume mount.
- `CONTINUWUITY_ADDRESS` - Bind address (for Docker, use `0.0.0.0` to listen on all interfaces).
Alternatively, you can specify a path to mount the configuration file using the `CONTINUWUITY_CONFIG` environment variable.
See the [reference configuration](../reference/config) page for all config options, and the [Configuration page](../configuration#environment-variables) on how to convert them into Environment Variables.
### Choose Your Reverse Proxy
These examples include reverse proxy configurations for Matrix federation, which will route your Matrix domain (and optionally .well-known paths) to Continuwuity.
:::note Docker DNS Performance
Docker's default DNS resolver are known to [cause timeout issues](../troubleshooting#dns-issues) for Matrix federation. To bypass it and use a more performant resolver, mount a custom `/etc/resolv.conf` config file into the Continuwuity container.
```yaml title='docker-compose.yml'
services:
homeserver:
# ...
volumes:
- ./continuwuity-resolv.conf:/etc/resolv.conf
```
```txt title='continuwuity-resolv.conf'
nameserver 1.0.0.1
nameserver 1.1.1.1
```
Consult the [**DNS tuning guide (recommended)**](../guides/dns.mdx) for full solutions to this issue.
See the [Other reverse proxies](generic.mdx#setting-up-the-reverse-proxy) section of the Generic page for further routing details.
### Starting Your Server
1. Choose your compose file from the above, and rename it to `docker-compose.yml`. Replace `example.com` with your homeserver's domain name, and edit other values as you see fit.
2. If using the override file, rename it to `docker-compose.override.yml` and
edit your values
edit your values.
3. Start the server:
```bash
docker compose up -d
```
```bash
docker compose up -d
```
4. Check your server logs for a registration token:
```bash
docker-compose logs continuwuity 2>&1
```
You'll see output as below.
```
In order to use your new homeserver, you need to create its
first user account.
Open your Matrix client of choice and register an account
on example.com using registration token x5keUZ811RqvLsNa .
Pick your own username and password!
```
5. Log in to your server with any Matrix client, and register for an account with the registration token from step 4. You'll automatically be invited to the admin room where you can [manage your server](../reference/admin).
See the [generic deployment guide](generic.mdx) for more deployment options.
### Building Custom Images
## Testing
Test that your setup works by following these [instructions](./generic.mdx#how-do-i-know-it-works)
Check your container logs using `docker-compose logs --follow` to debug any issues. See the [Troubleshooting](../troubleshooting.mdx) page for common errors and how to fix them.
## Other deployment methods
### Docker - Quick Run
:::warning For testing only
The instructions below are only meant for a quick demo of Continuwuity with **federation disabled**.
For production deployment, we recommend using [Docker Compose](#docker-compose).
:::
Get a working Continuwuity server with an admin user in four steps:
In order to use your new homeserver, you need to create its
first user account.
Open your Matrix client of choice and register an account
on example.com using registration token x5keUZ811RqvLsNa .
Pick your own username and password!
```
4. Configure your reverse proxy to forward HTTPS traffic to Continuwuity at port 8008. See [Docker Compose](#docker-compose) or the [Generic instructions](./generic.mdx#setting-up-the-reverse-proxy) for examples.
Once configured, log in to your server with any Matrix client, and register for an account with the registration token from step 3. If you did not configure step 4., log in via the `http://<your_server_ip>:8008` address. You will be automatically invited to the admin room where you can [manage your server](../reference/admin).
### (Optional) Building Custom Images
For information on building your own Continuwuity Docker images, see the
Before you can access the server's console and [send admin commands](../reference/admin/index.md) from the CLI, you will need to make the container interactive and allocate a pseudo-tty. Make sure you set `admin_console_automatic` to `true` in [the config](../reference/config.mdx) as well for Continuwuity to activate the CLI on startup.
For Docker Compose deployments this means adding `stdin_open: true` and `tty: true` to the container's declaration:
```yaml
services:
homeserver:
stdin_open: true
tty: true
# ...
```
If you choose to deploy via `docker run`, add the flags `-i`/`--interactive` and `-t`/`--tty` to the command.
From there you can access the server's console by running `docker attach <container-name>`, which will show the server's prompt `uwu> `. To exit `docker attach`, press `CTRL+p` then `CTRL+q`.
Note that using `CTRL+c` within `docker attach`'s context will forward the signal to the server, stopping it. See [Docker's reference][docker-attach-reference] for more information.
Theres a Nix package defined in our flake, available for Linux and MacOS. Add continuwuity as an input to your flake, and use `inputs.continuwuity.packages.${system}.default` to get a working Continuwuity package.
If you wish to generate a static binary, you can do so using Nix: `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity#packageName`, where `packageName` is one of:
If you simply wish to generate a binary using Nix, you can run `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity` to generate a binary in `result/bin/conduwuit`.
- `default-static-x86_64`
- `default-static-aarch64`
- `max-perf-static-x86_64`
- `max-perf-haswell-static-x86_64`
- `max-perf-static-aarch64`
`max-perf` takes longer to build, but has more runtime optimizations. Haswell builds are optimized for modern CPUs.
### Compiling
@@ -55,7 +63,8 @@ ### Compiling
#### Using Docker
If you would like to build using docker, you can run the command `docker build -f ./docker/Dockerfile -t forgejo.ellis.link/continuwuation/continuwuity:main .` to compile continuwuity.
See the [Building Docker Images](../development/index.mdx#building-docker-images)
section in the development documentation.
#### Manual
@@ -69,7 +78,7 @@ ##### Dependencies
##### Build
You can build Continuwuity using `cargo build --release`.
You can now build Continuwuity using `cargo build --release`.
Continuwuity supports various optional features that can be enabled during compilation. Please see the Cargo.toml file for a comprehensive list, or ask in our rooms.
@@ -155,9 +145,7 @@ ## Creating the Continuwuity configuration file
**Please take a moment to read the config. You need to change at least the
server name.**
RocksDB is the only supported database backend.
## Setting the correct file permissions
### Setting the correct file permissions
If you are using a dedicated user for Continuwuity, you need to allow it to
read the configuration. To do this, run:
@@ -175,22 +163,29 @@ ## Setting the correct file permissions
sudo chmod 700 /var/lib/conduwuit/
```
## Setting up the Reverse Proxy
## Exposing ports in the firewall or the router
We recommend Caddy as a reverse proxy because it is trivial to use and handles TLS certificates, reverse proxy headers, etc. transparently with proper defaults.
For other software, please refer to their respective documentation or online guides.
Matrix's default federation port is **:8448**, and clients use port **:443**. You will need to
expose these ports on your firewall or router. If you use UFW, the commands to allow them
are: `ufw allow 8448/tcp` and `ufw allow 443/tcp`.
:::tip Alternative port/domain setups
If you would like to use only port 443, a different port, or a subdomain for the homeserver, you will need to set up `.well-known` delegation. Consult the `[global.well_known]` section of the config file, and the [**Delegation/Split-domain**](../guides/delegation) page to learn more about these kinds of deployments.
:::
## Setting up the Reverse Proxy
### Caddy
After installing Caddy via your preferred method, create `/etc/caddy/conf.d/conduwuit_caddyfile`
and enter the following (substitute your actual server name):
Caddy is the recommended reverse proxy as it is easy to use, has good defaults,
and handle TLS certificates automatically. After installing Caddy via your preferred
method, create `/etc/caddy/conf.d/conduwuit_caddyfile` and enter the following
(substitute `example.com` with your actual server name):
```
your.server.name, your.server.name:8448 {
example.com, example.com:8448 {
# TCP reverse_proxy
reverse_proxy 127.0.0.1:6167
# UNIX socket
#reverse_proxy unix//run/conduwuit/conduwuit.sock
reverse_proxy 127.0.0.1:8008
}
```
@@ -202,51 +197,45 @@ ### Caddy
### Other Reverse Proxies
As we prefer our users to use Caddy, we do not provide configuration files for other proxies.
Normally, your reverse proxy should route everything from port :8448 and :443 back to Continuwuity.
You will need to reverse proxy everything under the following routes:
For more granular controls, you will need to proxy everything under these following routes:
- `/_matrix/` - core Matrix C-S and S-S APIs
- `/_conduwuit/` and/or `/_continuwuity/` - ad-hoc Continuwuity routes such as `/local_user_count` and
`/server_version`
- `/_matrix/` - core Matrix APIs, which includes:
- `/_matrix/federation` and `/_matrix/key` - core Server-Server APIs. These should be available on port :8448
- `/_matrix/client` - core Client-Server APIs. These should be available on port :443
For Apache and Nginx there are many examples available online.
Lighttpd is not supported as it appears to interfere with the `X-Matrix` Authorization
- Lighttpd is not supported as it appears to interfere with the `X-Matrix` Authorization
header, making federation non-functional. If you find a workaround, please share it so we can add it to this documentation.
If using Apache, you need to use `nocanon` in your `ProxyPass` directive to prevent httpd from interfering with the `X-Matrix` header (note that Apache is not ideal as a general reverse proxy, so we discourage using it if alternatives are available).
- If using Apache, you need to use `nocanon` in your `ProxyPass` directive to prevent httpd from interfering with the `X-Matrix` header (note that Apache is not ideal as a general reverse proxy, so we discourage using it if alternatives are available).
If using Nginx, you need to pass the request URI to Continuwuity using `$request_uri`, like this:
- If using Nginx, you need to pass the request URI to Continuwuity using `$request_uri`, like this:
- `proxy_pass http://127.0.0.1:6167$request_uri;`
- `proxy_pass http://127.0.0.1:6167;`
- `proxy_pass http://127.0.0.1:6167$request_uri;`
- `proxy_pass http://127.0.0.1:6167;`
Nginx users need to increase the `client_max_body_size` setting (default is 1M) to match the
`max_request_size` defined in conduwuit.toml.
Furthermore, Nginx users need to increase the `client_max_body_size` setting (default is 1M) to match the `max_request_size` defined in conduwuit.toml.
## You're done
## Starting Your Server
Now you can start Continuwuity with:
@@ -260,36 +249,59 @@ ## You're done
sudo systemctl enable conduwuit
```
## How do I know it works?
You can open [a Matrix client](https://matrix.org/ecosystem/clients), enter your
homeserver address, and try to register.
You can also use these commands as a quick health check (replace
`your.server.name`).
Check Continuwuity logs with the following command:
Continuwuity versions v0.5.10+ are available as RPM packages for the following distributions:
<Tabs groupId="distro">
<Tab label="Fedora">
Available for upstream-supported Fedora versions (including compatible distributions, such as Ultramarine Linux) and Rawhide through Terra.
</Tab>
<Tab label="EL">
Available for Enterprise Linux (RHEL, AlmaLinux, Rocky Linux, etc.) **10+** through Terra.
:::warning Oracle Linux support
Due to upstream limitations, Terra is only usable on Oracle Linux if you use [upstream EPEL](https://docs.fedoraproject.org/en-US/epel/getting-started/)
rather than Oracle's rebuilds of EPEL. Oracle tends to lag behind on new EL versions, both major and minor—for example, as of the time of writing, 10.2 has been
available for over a month through other ELs, but Oracle has not yet released corresponding updates—so you may encounter further compatibility issues with EPEL.
**For this reason, it is recommended that you use another EL distribution if at all possible.**
:::
</Tab>
<Tab label="SUSE">
Available for openSUSE Tumbleweed and [supported Leap versions](https://en.opensuse.org/Lifetime) through the openSUSE Build Service.
</Tab>
</Tabs>
## Installation methods
### Stable releases (recommended)
<Tabs groupId="distro">
<Tab label="Fedora">
1. Follow [Terra's directions for adding the Terra repo on your distribution](https://docs.terrapkg.com/usage/installing/#fedora-and-derivatives).
2. Install the `continuwuity` package.
</Tab>
<Tab label="EL">
1. Follow [Terra's directions for adding the Terra repo on your distribution](https://docs.terrapkg.com/usage/installing/#enterprise-linux). Be sure to acquire/enable relevant dependencies!
2. Install the `continuwuity` package.
</Tab>
<Tab label="SUSE">
openSUSE packages are available through an openSUSE Build Service project namespace provided by a community member.
1. Navigate to [this page](https://software.opensuse.org/download.html?project=home%3Ajulian45&package=continuwuity).
2. Click on the "Add repository and install manually" text to expand install instructions.
3. Follow the provided instructions for your version of openSUSE.
</Tab>
</Tabs>
### Nightly releases
Nightly versions are built from the latest commit on the `main` branch every 24 hours.
<Tabs groupId="distro">
<Tab label="Fedora">
1. Follow [Terra's directions for adding the Terra repo on your distribution](https://docs.terrapkg.com/usage/installing/#fedora-and-derivatives).
2. Install the `continuwuity-nightly` package.
</Tab>
<Tab label="EL">
1. Follow [Terra's directions for adding the Terra repo on your distribution](https://docs.terrapkg.com/usage/installing/#enterprise-linux). Be sure to acquire/enable relevant dependencies!
2. Install the `continuwuity-nightly` package.
</Tab>
<Tab label="SUSE">
Nightly packages for openSUSE are **not currently available**.
If there is an ongoing need for these, please ask in `#continuwuity:continuwuity.org` or [open an issue on Forgejo](https://forgejo.ellis.link/continuwuation/continuwuity/issues/new).
In the meantime, you may follow the [generic deployment instructions](generic).
</Tab>
</Tabs>
## Service management and removal
**Systemd service commands**
```bash
# Start the service
sudo systemctl start conduwuit
# Enable on boot
sudo systemctl enable conduwuit
# Check status
sudo systemctl status conduwuit
# View logs
sudo journalctl -u conduwuit -f
```
**Uninstallation**
```bash
# Stop and disable the service
sudo systemctl stop conduwuit
sudo systemctl disable conduwuit
# Remove the package
sudo dnf remove continuwuity # replace `dnf` with `zypper` on openSUSE
1. Follow [Terra's prep directions](https://docs.terrapkg.com/contributing/getting-started/#preparation) to bootstrap your development environment.
2. `git clone` the [Terra sources repo](https://github.com/terrapkg/packages).
3. Follow [Terra's build instructions](https://docs.terrapkg.com/contributing/getting-started/#building), using the path `anda/misc/continuwuity/nightly/pkg`. If desiring a build of the latest stable version, replace `nightly` with `stable` instead.
</Tab>
<Tab label="EL">
1. Follow [Terra's prep directions](https://docs.terrapkg.com/contributing/getting-started/#preparation) to bootstrap your development environment.
2. `git clone` the [Terra sources repo](https://github.com/terrapkg/packages).
3. Follow [Terra's build instructions](https://docs.terrapkg.com/contributing/getting-started/#building), using the path `anda/misc/continuwuity/nightly/pkg`. If desiring a build of the latest stable version, replace `nightly` with `stable` instead.
</Tab>
<Tab label="SUSE">
1. Navigate to [this package's location in the openSUSE Build Service web UI](https://build.opensuse.org/package/show/home:julian45/continuwuity).
2. Click on the "Checkout package" text and follow the instructions to acquire a local copy of the packaging source.
3. In the `_service` file, adjust the revision within the `<param name="revision">` tag (approx. line 6) to your desired git repo revision.
4. Run `osc service ra` to update your copy of the Continuwuity sources and vendored packages.
5. Run `osc build` to locally build an openSUSE-ready RPM.
@@ -115,12 +122,74 @@ ## Serving with a reverse proxy
</details>
### Serving well-known files manually
Instead of reverse proxying well-known URIs, you can serve these files directly as static JSON that match the ones above. This is useful if your base domain points to a different physical server, and reverse proxying isn't feasible.
:::warning
Even if you choose to serve the well-known files manually, if you are using delegation at all, you **must** still set the `global.well_known.client` configuration option to the domain you're delegating to. Continuwuity needs to know the domain it runs on for OAuth-compatible clients to work correctly.
:::
<details>
<summary>Example Caddyfile **for the base domain**</summary>
Make sure there is an `Access-Control-Allow-Origin: *` header in your `/.well-known/matrix/client` path. While Continuwuity serves this header by default, it may be dropped by reverse proxies or other middlewares.
### Issues with alternative setups
As Matrix clients prioritize well-known URIs for their destination, this can lead to issues with alternative methods of accessing the server that doesn't use a publicly routeable IP and domain name. You will probably find yourself connecting to non-existent/undesired URLs in certain cases like:
- Accessing to the server via localhost IPs (e.g. for testing purposes)
- Accessing the server from behind a VPN, or from alternative networks (such as from an onionsite)
In these scenarios, further configurations would be needed. Refer to the [Related Documentation](#related-documentation) section for resolution steps and see how they could apply to your use case.
---
## Using SRV records (not recommended)
@@ -204,3 +273,45 @@ ## Related Documentation
- [Server-to-Server resolution](https://spec.matrix.org/v1.17/server-server-api/#resolving-server-names) (see this for more information on SRV records)
- [MSC1929: Homeserver Admin Contact and Support page](https://github.com/matrix-org/matrix-spec-proposals/pull/1929)
## Appendix
### Docker Compose examples
The following Compose files are taken from [Docker instructions](../deploying/docker.mdx) and reconfigured to support split-domain delegation. Note the updated `CONTINUWUITY_WELL_KNOWN` variable and relevant changes in reverse proxy rules.
For federation, Matrix homeservers conduct an enormous amount of DNS requests, sometimes up to thousands of queries per minute. Normal DNS resolvers are simply not designed for this load, and running Continuwuity with them will likely result in various [DNS and federation errors](../troubleshooting#dns-issues).
To solve this issue, it is strongly recommended to self-host a high-quality, external caching DNS resolver for Continuwuity. This guide will use [Unbound][unbound] as the recommended example, but the general principle applies to any resolver.
For generic deployments, install your resolver of choice and configure `/etc/resolv.conf` to point to it. The resolver should ideally reside on the same host as Continuwuity.
```txt title="/etc/resolv.conf"
nameserver 127.0.0.1
```
**Avoid using `systemd-resolved`** as it does **not** perform very well under high load, and we have identified its DNS caching to not be very effective.
### For Docker users
Docker bridge networks uses a non-performant resolver to intercept and respond to container hostnames, and **this should also be avoided**. Instead, mount a custom `/etc/resolv.conf` file into the container, and hardcode a resolver address to bypass Docker's.
It is recommended to run a dedicated resolver container for Continuwuity, as to separate from the host's resolver setup. To do this, create a custom bridge network and IP range, and explicitly define an IP address for the resolver container.
<details>
<summary>Example Docker deployment with unbound</summary>
```yaml title="docker-compose.yml"
networks:
matrix_net:
ipam:
driver: default
config:
- subnet: "10.10.10.0/24"
services:
homeserver:
# ...
volume:
- ./continuwuity-resolv.conf:/etc/resolv.conf:ro
unbound:
# ...
networks:
matrix_net:
ipv4_address: 10.10.10.20
```
```txt title="continuwuity-resolv.conf"
nameserver 10.10.10.20
```
</details>
### For IPv4-only users
If you don't have IPv6 connectivity, changing `ip_lookup_strategy` to only resolve for IPv4 will reduce unnecessary AAAA queries.
```toml title="continuwuity.toml"
[global]
# 1 - Ipv4Only (Only query for A records, no AAAA/IPv6)
ip_lookup_strategy = 1
```
## Unbound
[Unbound][unbound] is the recommended resolver to run with Continuwuity. For Docker users, the `docker.io/madnuttah/unbound` image ([Github repo][madnuttah-unbound-repo]) can be used.
After installation, you can tune `/etc/unbound/unbound.conf` values according to your needs. While Continuwuity cannot recommend a "works-for-everyone" Unbound DNS setup guide, the official [Unbound tuning guide][unbound-tuning-guide] and the [Unbound Arch Linux wiki page][unbound-arch-linux] may be of interest.
Some values that are commonly tuned include:
- Increase `rrset-cache-size` and `msg-cache-size` to something much higher than the default `4M`, such as `64M`.
- Increase `discard-timeout` to something like `4800` to wait longer for upstream resolvers, as recursion can take a long time to respond to some domains. Continuwuity default to `dns_timeout = 10` seconds, so dropping requests early would lead to unnecessary retries and/or failures.
### Recursion versus forwarding
Unbound by default employs **recursive resolution** and contacts many servers around the world. While this allows updated and authoritative answers and are generally viable for most users, sometimes these recursive queries can be too slow to fully resolve. As an alternative, you can consider **forwarding** your queries to public resolvers, and benefit from faster responses from their CDNs.
Do note that most popular upstreams (such as Google DNS or Quad9) employ IP ratelimiting, so a generous cache is still needed to avoid making too many queries.
If you want to use forwarders, configure it as follows:
<details>
<summary>unbound.conf</summary>
```
# Use cloudflare public resolvers as an example
forward-zone:
name: "."
forward-addr: 1.0.0.1@53
forward-addr: 1.1.1.1@53
# Also use IPv6 ones if you're dual-stack
# forward-addr: 2606:4700:4700::1001@53
# forward-addr: 2606:4700:4700::1111@53
# alternatively, use DNS-over-TLS for forwarders.
# this will encrypt traffic between you and the forwarder,
[Dnsproxy][dnsproxy] and its sister product [AdGuard Home][adguard-home] are known to work with Continuwuity and has an official Docker image. They have support for DNS-over-HTTPS as well as DNS-over-QUIC, but not recursion.
To best utilise dnsproxy, you should enable proper caching with `--cache` and set `--cache-size` to something bigger, like `64000000`.
[dnsmasq][arch-linux-dnsmasq] can possibly work with Continuwuity, though it only supports forwarding rather than recursion. Increase the `cache-size` to something like `30000` for better caching performance.
However, `dnsmasq` does not support TCP fallback which can be problematic when receiving large DNS responses such as from large SRV records. If you still want to use dnsmasq, make sure you disable `dns_tcp_fallback` in Continuwuity config.
[Technitium DNS Server][technitium] supports recursion as well as a myriad of forwarding protocols, allows saving cache to disk natively, and does work well with Continuwuity. Its out-of-the-box configs however ratelimits single-IP requests by a lot, and hence must be changed.
You may consult this [community guide][technitium-continuwuity] for more details on setting up and fine-tuning a dedicated Technitium instance for Continuwuity.
As a rough stress test, you can run `!admin query resolver flush-cache -a` or `!admin server clear-caches` to trigger a netburst of DNS queries. If your resolver can handle these loads without problem, then it should be ready for regular Continuwuity activity.
To test connectivity against a specific server, use `!admin debug ping <SERVER_NAME>` and `!admin debug resolve-true-destination <SERVER_NAME>`.
Note that it is expected that not all servers will be resolved, as some of them may be temporarily offline, have broken DNS and/or discovery configuration, or have been decommissioned.
## Further steps
It is recommended to set **`dns_cache_entries = 0`** inside Continuwuity to fully rely on the external resolver. While Continuwuity does have an internal cache, it can run into reliability issues if you're federating with many domains.
Additionally, you can also make the following improvements:
- Consider employing **persistent cache to disk**, so your resolver can still run without hassle after a restart. Unbound, via [Cache DB module][unbound-cachedb], can use Redis as a storage backend for this feature.
- Consider [enabling **Serve Stale**][unbound-serve-stale] functionality to serve expired data beyond DNS TTLs. Since most Matrix homeservers have static IPs, this should still allow federating with them when upstream resolvers have timed out. For dnsproxy, this corresponds to its [optimistic caching options][dnsproxy-usage].
- If you still experience DNS performance issues, another step could be to **disable DNSSEC** (which is computationally expensive) at a cost of slightly decreased security. On Unbound this is done by commenting out `trust-anchors` config options and removing the `validator` module.
- Some users have reported that setting `query_over_tcp_only = true` in Continuwuity has improved DNS reliability at a slight performance cost due to TCP overhead. Generally this is not needed if your resolver and homeserver is on the same machine.
Continuwuity supports delegating user authentication to an external identity provider that implements the OpenID Connect specification, such as Authentik, kanidm, or Keycloak.
:::warning{title="OIDC versus OAuth, and supported clients"}
**OIDC** is not to be confused with **OAuth**. In the context of Matrix, OAuth is the protocol that Matrix clients use to authenticate with the _homeserver_. OIDC is the protocol that the _homeserver_ uses to communicate with the _identity provider_. Continuwuity supports OAuth by default, alongside the legacy **UIAA** authentication framework.
When OIDC is configured, Continuwuity will disable its support for legacy authentication. **Only clients that support OAuth**, such as the Element family of clients, will be able to log in when OIDC is configured. If your client of choice shows an error when you try to log in after configuring OIDC, it likely does not support OAuth. This is an issue with your client, not Continuwuity, and should be reported to your client's developers.
:::
A simple OIDC configuration is as easy as creating a new OIDC application in your identity provider's settings and supplying Continuwuity with the client ID and client secret. This guide will use kanidm as an example, but the described steps are broadly applicable to other identity providers.
First, create a new application for Continuwuity in your identity provider.
```sh
# Here, `c10y` is the client ID that kanidm will use, and `Continuwuity` is the display name.
# Other identity providers may generate a client ID for you.
# Use the domain that clients can reach Continuwuity at, which may not be the same as your server name
# if you have configured well-known delegation.
kanidm system oauth2 create c10y Continuwuity https://matrix.yourdomain.com
```
Configure the redirect URL that Continuwuity uses.
```sh
kanidm system oauth2 add-redirect-url c10y https://matrix.yourdomain.com/_continuwuity/oidc/complete
```
Allow Continuwuity to request the `openid` scope. Other identity providers may not require this step.
```sh
kanidm system oauth2 update-scope-map c10y idm_all_persons openid
```
Find the client secret that was generated. Other identity providers may show this information in their web UI.
```sh
kanidm system oauth2 show-basic-secret c10y
d1qgx352kkuvs1j70b6w293d65x68jve1f7b27fyk90gjhpr
```
Configure Continuwuity with the client ID, client secret, and discovery URL. kanidm has a different discovery URL for each client, but other identity providers may have a single discovery URL at the root of their domain.
```toml
[global.oauth.oidc]
# `/.well-known/openid-configuration` will be appended automatically
Finally, restart Continuwuity, and log out and back in again. Your client should prompt you to continue in your web browser and open a webpage with the Continuwuity logo that allows you to continue in your identity provider. Once you log in successfully, you will be prompted to choose a user ID -- to link your existing account, enter its user ID, and then your old password when prompted.
Continuwuity offers several additional configuration options to tweak its integration with your identity provider. Review the `[global.oauth.oidc]` section towards the bottom of the [reference configuration](../reference/config) for a complete list of options and documentation.
Continuwuity's default configs are suited for many typical setups and scales appropriately with the size of your hardware. However, there are many scenarios where additional modifications can be made to better utilize your server resources.
This page aims to outline various performance tweaks for Continuwuity and their effects. These adjustments are especially helpful for homeservers that join many large federated rooms or have many users, and it will become increasingly necessary as the Matrix network expands. As always, your mileage may vary according to your setup's specifics. If you have further discussions or recommendations, please share them in the community rooms.
## DNS tuning (recommended)
Please see the dedicated [DNS tuning guide](./dns.mdx).
## Cache capacities
If you have memory to spare, consider increasing the `cache_capacity_modifier` value to a larger number to allow more data to be stored in hot memory. This *significantly* speeds up many intensive operations (such as state resolutions) and decreases CPU usage and disk I/O. Start with a baseline of `cache_capacity_modifier = 2.0` and tune up until you are satisfied with RAM usage.
On the other hand, if your system doesn't have a lot of RAM, consider decreasing the cache capacity modifier to something smaller than `1.0` to avoid low-memory issues (at the cost of higher load on disk/CPU). This recommendation also works if your system has abnormally little RAM compared to the number of CPU cores (for example, 2GB RAM for 12 cores), as cache capacities scale according to number of available cores.
## Disabling some features
You can disable outgoing **typing notifications** and **read markers** to reduce strain on the CPU and network when actively participating in rooms.
```toml
# disables sending read receipts
allow_outgoing_read_receipts = false
# disables sending typing notifications
allow_outgoing_typing = false
```
Outgoing presence updates are also considered very expensive and have been disabled by default (`allow_outgoing_presence = false`). For more savings, you may wish to disable _all_ processing of presence entirely.
```toml title=continuwuity.toml
# disabling presence updates entirely
allow_local_presence = false
allow_incoming_presence = false
allow_outgoing_presence = false
```
## Tuning database compression
:::warning
These steps SHOULD be done **before** starting Continuwuity for the first time. While switching database compression midway through is theoretically possible, this has not been tested extensively in the wild.
:::
### Changing the compression algorithm
For reduced CPU usage at a tradeoff of increased storage space, consider deploying Continuwuity with the faster and less intensive `lz4` algorithm instead of `zstd` for rocksdb, and disable WAL compression entirely:
```toml
### in continuwuity.toml ###
rocksdb_compression_algo = "lz4"
rocksdb_wal_compression = "none"
```
This tweak can especially be helpful if you have an older or less performant CPU (e.g. a Raspberry Pi) and disk space to spare.
The bottommost layer of the database usually contains old and read-only data, so it is a suitable place for further compression. In Continuwuity, this is possible by setting `rocksdb_bottommost_compression = true` and tuning `rocksdb_bottommost_compression_level` to a more compact level than the default one used in `rocksdb_compression_level`. This tweak comes at a cost of increased CPU usage, but may prevent your database from growing too large in the long run.
For those using `zstd` compression, the compression level ranges from 1 to 22. An example like this could apply:
```toml
### in continuwuity.toml ###
rocksdb_compression_algo = "zstd"
rocksdb_compression_level = 32767 # magic number, translates to level 3 on zstd
rocksdb_bottommost_compression = true
rocksdb_bottommost_compression_level = 9 # level 9 on zstd
```
For `lz4` users, the default level (`-1`) is already the most compact. You can only further decrease it to favor compression speed over ratio.
Consult these documents for more information on compression tuning and levels:
If your homeserver and reverse proxy live on the same machine, you may wish to expose Continuwuity on a UNIX socket instead of a port. This removes TCP overhead between the two programs.
<details>
<summary>Example config with Caddy</summary>
```toml
### in continuwuity.toml ###
# `address` and `port` has to be commented out first
Trusted servers are your first point of contact when obtaining public keys from other servers, and they could theoretically impersonate other servers and cause significant harm to your deployment. Please thoroughly verify your trusted servers' credibility before adding them to your configuration.
:::
Trusted servers are queried sequentially in the order they are listed. If you have multiple trusted servers configured, put the faster ones first:
```toml
# Example config, using maintainers' recommended homeservers
Avoid prioritising `matrix.org` as your primary trusted server, as it tends to be quite slow.
Some users have also reported that increasing `trusted_server_batch_size` has helped with faster joins for huge rooms. Start with doubling the default to `2048` until you find a suitable value.
### Enable HTTP/3 on your reverse proxy
Consider enabling the newer **HTTP/3** protocol for inbound connections to Continuwuity. In Caddy HTTP/3 is allowed by default, but you must expose port :443/**udp** on your firewall.
HTTP/3 can vastly improve Client-Server connections especially on unstable networks, as it reduces packet losses and latency from TCP head-of-line blocking, includes workarounds for network switching, and reduces connection establishment handshakes. Continuwuity also includes experimental _outbound_ HTTP/3 support in its Docker images, so connections between Continuwuity servers can benefit from this too.
"message": "Welcome to Continuwuity! Important announcements about the project will appear here."
},
{
"id": 10,
"mention_room": false,
"date": "2026-03-03",
"message": "We've just released [v0.5.6](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v0.5.6), which contains a few security improvements - plus significant reliability and performance improvements. Please update as soon as possible. \n\nWe released [v0.5.5](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v0.5.5) two weeks ago, but it skipped your admin room straight to [our announcements channel](https://matrix.to/#/!jIdNjSM5X-V5JVx2h2kAhUZIIQ08GyzPL55NFZAH1vM?via=ellis.link&via=gingershaped.computer&via=matrix.org). Make sure you're there to get important information as soon as we announce it! [Our space](https://matrix.to/#/!8cR4g-i9ucof69E4JHNg9LbPVkGprHb3SzcrGBDDJgk?via=continuwuity.org&via=ellis.link&via=matrix.org) has also gained a bunch of new and interesting rooms - be there or be square."
"id": 15,
"mention_room": true,
"date": "2026-07-10",
"message": "[Continuwuity 26.6.0](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v26.6.0) is finally out! This is by far our largest release yet, and it wouldn't have been possible without our community. Thank you so much for all of your patience, support, and/or development time over the last three months <3"
Some slowness is to be expected if you're the first person on your homserver to join a room (which will
Some slowness is to be expected if you're the first person on your homeserver to join a room (which will
always be the case for single-user homeservers). In this situation, your homeserver has to verify the signatures of
all of the state events sent by other servers before your join. To make this process as fast as possible, make sure you have
multiple fast, trusted servers listed in `trusted_servers` in your configuration, and ensure
@@ -45,75 +45,30 @@ ### Lost access to admin room
## DNS issues
### Potential DNS issues when using Docker
### DNS server overload
Docker's DNS setup for containers in a non-default network intercepts queries to
enable resolving of container hostnames to IP addresses. However, due to
performance issues with Docker's built-in resolver, this can cause DNS queries
to take a long time to resolve, resulting in federation issues.
If your server experience any of the following symptoms:
This is particularly common with Docker Compose, as custom networks are easily
created and configured.
- Spurious server log entries with "DNS No connections available", "mismatching responding nameservers", or "error sending request"
- Excessively long room joins (30+ minutes) as seen from server logs
- Partial or non-functional outbound federation
Symptoms of this include excessively long room joins (30+ minutes) from very
long DNS timeouts, log entries of "mismatching responding nameservers",
and/or partial or non-functional inbound/outbound federation.
This is likely due to your DNS server being overloaded. Most likely, these problems are encountered in the following scenarios:
This is not a bug in continuwuity. Docker's default DNS resolver is not suitable
for heavy DNS activity, which is normal for federated protocols like Matrix.
- Homeservers hosted on a machine that uses `systemd-resolved`.
- Docker deployments which use the bridge network's forwarding resolver.
Workarounds:
Matrix federation is extremely heavy and sends wild amounts of DNS requests. This makes normal resolvers like the ones above unsuitable for its activity. Ultimately, the best solution/fix for this is to selfhost a high quality caching DNS resolver such as Unbound, and configure Continuwuity to use it.
- Use DNS over TCP via the config option `query_over_tcp_only = true`
- Bypass Docker's default DNS setup and instead allow the container to use and communicate with your host's DNS servers. Typically, this can be done by mounting the host's `/etc/resolv.conf`.
Follow the [**DNS tuning guide**](./guides/dns) for details on setting it up.
### DNS No connections available error message
### Intermittent federation failures to a specific server
If you receive spurious amounts of error logs saying "DNS No connections
available", this is due to your DNS server (servers from `/etc/resolv.conf`)
being overloaded and unable to handle typical Matrix federation volume. Some
users have reported that the upstream servers are rate-limiting them as well
when they get this error (e.g. popular upstreams like Google DNS).
There may be circumstances where servers fail to connect to each other, probably due to a bad DNS cache. In such cases, issuing `!admin debug ping <SERVER_NAME>` would return some errors.
Matrix federation is extremely heavy and sends wild amounts of DNS requests.
Unfortunately this is by design and has only gotten worse with more
server/destination resolution steps. Synapse also expects a very perfect DNS
setup.
To fix this, you can run `!admin query resolver flush-cache <SERVER_NAME>` to clear the bad cache for that domain, and outbound requests should work again.
There are some ways you can reduce the amount of DNS queries, but ultimately
the best solution/fix is selfhosting a high quality caching DNS server like
[Unbound][unbound-arch] without any upstream resolvers, and without DNSSEC
validation enabled.
DNSSEC validation is highly recommended to be **disabled** due to DNSSEC being
very computationally expensive, and is extremely susceptible to denial of
service, especially on Matrix. Many servers also strangely have broken DNSSEC
setups and will result in non-functional federation.
Continuwuity cannot provide a "works-for-everyone" Unbound DNS setup guide, but
the [official Unbound tuning guide][unbound-tuning] and the [Unbound Arch Linux wiki page][unbound-arch]
may be of interest. Disabling DNSSEC on Unbound is commenting out trust-anchors
config options and removing the `validator` module.
**Avoid** using `systemd-resolved` as it does **not** perform very well under
high load, and we have identified its DNS caching to not be very effective.
dnsmasq can possibly work, but it does **not** support TCP fallback which can be
problematic when receiving large DNS responses such as from large SRV records.
If you still want to use dnsmasq, make sure you **disable** `dns_tcp_fallback`
in Continuwuity config.
Raising `dns_cache_entries` in Continuwuity config from the default can also assist
in DNS caching, but a full-fledged external caching resolver is better and more
reliable.
If you don't have IPv6 connectivity, changing `ip_lookup_strategy` to match
your setup can help reduce unnecessary AAAA queries
(`1 - Ipv4Only (Only query for A records, no AAAA/IPv6)`).
If your DNS server supports it, some users have reported enabling
`query_over_tcp_only` to force only TCP querying by default has improved DNS
reliability at a slight performance cost due to TCP overhead.
You may also use `!admin server clear-caches` or `!admin query resolver flush-cache -a` to clear all server/resolver caches, in case of failures with many domains. However, note that this significantly increases your server load for a short period.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.