Reverse Proxy Setup - Nginx
<= Back to Generic Deployment Guide
This guide shows you how to configure Nginx as a reverse proxy for Tuwunel with TLS support.
Installation
Install Nginx via your preferred method. Most distributions include Nginx in their package repositories:
# Debian/Ubuntu
sudo apt install nginx
# Red Hat/Fedora
sudo dnf install nginx
# Arch Linux
sudo pacman -S nginx
Configuration
Create a new configuration file at /etc/nginx/sites-available/tuwunel (or /etc/nginx/conf.d/tuwunel.conf on some distributions):
# Client-Server API over HTTPS (port 443)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name matrix.example.com;
# Nginx standard body size is 1MB, which is quite small for media uploads
# Increase this to match the max_request_size in your tuwunel.toml
client_max_body_size 100M;
# Forward requests to Tuwunel (listening on 127.0.0.1:8008)
location / {
proxy_pass http://127.0.0.1:8008;
# Preserve host and scheme - critical for proper Matrix operation
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
# TLS configuration (Let's Encrypt example using certbot)
ssl_certificate /etc/letsencrypt/live/matrix.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/matrix.example.com/privkey.pem;
}
# Matrix Federation over HTTPS (port 8448)
# Only needed if you want to federate with other homeservers
# Don't forget to open port 8448 in your firewall!
server {
listen 8448 ssl http2;
listen [::]:8448 ssl http2;
server_name matrix.example.com;
# Same body size increase for larger files
client_max_body_size 100M;
# Forward to the same local port as client-server API
location / {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}
# TLS configuration (same certificates as above)
ssl_certificate /etc/letsencrypt/live/matrix.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/matrix.example.com/privkey.pem;
}
Important Notes
- Replace
matrix.example.comwith your actual server name client_max_body_size: Must match or exceedmax_request_sizein yourtuwunel.toml- Do NOT use
$request_uriinproxy_pass- while some guides suggest this, it’s not necessary for Tuwunel and can cause issues - IPv6: The
listen [::]:443andlisten [::]:8448lines enable IPv6 support. Remove them if you don’t need IPv6
TLS Certificates
The example above uses Let’s Encrypt certificates via certbot. To obtain certificates:
sudo certbot certonly --nginx -d matrix.example.com
Certbot will automatically handle renewal. Make sure to reload Nginx after certificate renewal:
sudo systemctl reload nginx
Optional: Timeout Configuration
The default Nginx timeouts are usually sufficient for Matrix operations. Element’s long-polling /sync requests typically run for 30 seconds, which is within Nginx’s default timeouts.
However, if you experience federation retries or dropped long-poll connections, you can extend the timeouts by adding these lines inside your location / blocks:
location / {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
# Optional: Extend timeouts if experiencing issues
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
Enable the Configuration
If using sites-available/sites-enabled structure:
sudo ln -s /etc/nginx/sites-available/tuwunel /etc/nginx/sites-enabled/
Test the configuration:
sudo nginx -t
If the test passes, reload Nginx:
sudo systemctl reload nginx
Enable Nginx to start on boot:
sudo systemctl enable nginx
Verification
After configuring Nginx, verify it’s working by checking:
curl https://matrix.example.com/_tuwunel/server_version
curl https://matrix.example.com:8448/_tuwunel/server_version
Troubleshooting
Apache Compatibility Note
If you’re considering Apache instead of Nginx: Apache is not well-suited as a reverse proxy for Matrix homeservers. If you must use Apache, you need to use nocanon in your ProxyPass directive to prevent httpd from corrupting the X-Matrix authorization header, which will break federation.
Lighttpd is Not Supported
Lighttpd has known issues with the X-Matrix authorization header, making federation non-functional. We do not recommend using Lighttpd with Tuwunel.