All posts
MatrixMessaging

Matrix: chat, calls and secure operation

I run Matrix with Element and LiveKit on my own infrastructure. These live services are used daily for messaging, voice and video calls, and screen sharing. Secure internal connections, administration and day-to-day operation are part of the same setup.

In this article

One platform, three responsibilities

Simplified architecture overview based on Synapse 1.x. Web access, media and internal dependencies follow different paths. Click to enlarge.
Simplified architecture overview based on Synapse 1.x. Web access, media and internal dependencies follow different paths. Click to enlarge.
  • Chat: Element provides the interface; Synapse manages accounts, rooms and events.
  • Calls: LiveKit handles audio, video and screen sharing; lk-jwt supplies the appropriate authorization.
  • Operations: Nginx and HAProxy control web access; Synapse Admin provides administration.

PostgreSQL stores persistent Synapse data. Redis supports caching and, depending on deployment mode, coordination between Synapse processes. Both are internal dependencies and need no public exposure.

Calls have a separate path

WSS carries signaling and WebRTC carries media. Audio and video therefore do not pass through the reverse proxy as ordinary HTTP requests. LiveKit can use its embedded TURN; coturn supports other compatible calling paths.

With lk-jwt, integration and permitted room actions depend on version and deployment mode. A valid Matrix identity should receive only the intended media permissions, not unrestricted use of the infrastructure.

Protect content and transport separately

End-to-end encryption, TLS and Zero Trust protect different boundaries. Internal placement alone grants no trust.
End-to-end encryption, TLS and Zero Trust protect different boundaries. Internal placement alone grants no trust.

In end-to-end encrypted Matrix rooms, a server administrator cannot decrypt message text without the room keys. TLS instead protects a connection that may terminate at the proxy. A separate TLS connection to the backend requires its own identity validation.

Metadata and compromised devices remain separate concerns. Verify call and screen-sharing E2EE with the actual clients and features in use.

Zero Trust applies inside the network too

I treat my internal network as potentially untrusted, just like an external one. An internal IP address grants no permission. Connections are explicitly allowed, identities verified and privileges limited. For me, hardening therefore continues beyond the public reverse proxy.

Reconstructed examples: reject public administration requests; an approved network source reaches only the sign-in form. Not screenshots of the running environment.
Reconstructed examples: reject public administration requests; an approved network source reaches only the sign-in form. Not screenshots of the running environment.

The project restricted both Synapse Admin and its administration API. The actual client matters: HAProxy can be trusted to convey its IP without gaining administrative access itself. Setup checks also rejected forged forwarding headers.

Behind the proxy, rules restrict source, destination and required service. Database and cache stay internal; the Synapse listener discussed here binds to host-local loopback. Between hosts, encryption and certificate validation are explicit parts of the design. Network permission still does not replace sign-in.

Hardening needs application context

At the public web entry point I also use ModSecurity with the OWASP Core Rule Set to inspect HTTP requests for common attack patterns. Tune exceptions narrowly per route so sign-in, synchronization and uploads keep working. WebRTC media is outside this HTTP inspection.

  • Limit login and request traffic per endpoint; use meaningful HTTP responses such as 403 or 429 for rejections.
  • Account for WebSockets and synchronization: unsuitable global timeouts must not terminate legitimate long connections.
  • Use custom Fail2ban filters to identify abuse and block the real client at an effective enforcement point.

Keep tokens and passwords out of logs. Centralized operational events help investigate web access, Synapse and media setup together. A successful sign-in alone does not prove a working call.

Test operation as well as installation

Controlled testWhat must work
Call from another networkSignaling, audio, video and TURN where needed.
Unauthorized administration or token requestRejection at the intended boundary, including forged client-IP headers.
Individual service failureAssess messaging, sign-in and existing calls separately.
RestoreInclude database, media and required keys, then test real workflows.

Updates, bounded log retention and tested backups matter as much as initial installation. I simulate failures virtually. That helps testing but does not replace physically separate sites. An additional Synapse instance also does not make database and media paths highly available automatically.

Conclusion

These services are part of everyday operation. What matters to me is that chat and calls work, access stays limited and faults can be investigated and resolved.

Technical references: Synapse reverse proxy · Matrix E2EE · LiveKit deployment · lk-jwt · Fail2ban · Zero Trust: NIST SP 800-207 · ModSecurity / OWASP CRS

Matrix logo: The Matrix.org Foundation. Independent article; no vendor affiliation or endorsement.

Share this article

LinkedIn Email