See also:
- Q&A: https://github.com/Kozea/Radicale/discussions/categories/q-a-reverse-proxy
- Reference configurations
Precondition "radicale" server is running fine and accessable
- Wiki: https://github.com/Kozea/Radicale/wiki/Server-Diagnostics---Troubleshooting
- Q&A: https://github.com/Kozea/Radicale/discussions/categories/q-a-server
Listen Status
Check whether "reverse proxy" is proper running
Webserver "Apache"
Example
netstat -nlpt | grep -E ":(80|443) "
tcp6 0 0 :::443 :::* LISTEN 1427/httpd
tcp6 0 0 :::80 :::* LISTEN 1427/httpd
Webserver "nginx"
Example (no TLS configured so far)
netstat -nlpt | grep -E ":(80|443) "
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1667/nginx: master
tcp6 0 0 :::80 :::* LISTEN 1667/nginx: master
Proxy connection to "radicale"
SELinux
In case of SELinux is active and and in "enforcing" mode, SELinux may block connection from "reverse proxy" to "radicale"
Current status of SELinux
sestatus | grep -E "(SELinux status|Current mode)"
SELinux status: enabled
Current mode: enforcing
Check SELinux toggle
At least supported on Enterprise & Fedora Linux
Example for prohibited connection from "reverse proxy" to other servers ("radicale" or any other)
getsebool httpd_can_network_connect
httpd_can_network_connect --> off
Permanent enabling
Systems not having extra SELinux policy for "radicale"
setsebool -P httpd_can_network_connect=1
getsebool httpd_can_network_connect
httpd_can_network_connect --> on
Send request via "reverse proxy"
If reverse proxy configuration for "radicale" is configured in the default web server, URI must be extended to avoid any overlap conflicts
Example config excerpt
# Apache
<Location /radicale>
ProxyPass http://localhost:5232/ retry=0
ProxyPassReverse http://localhost:5232/
...
</Location>
Example URLs to request
Radicale direct : http://localhost:5232/.web/
via reverse proxy : http://localhost:80/radicale/.web/
via reverse proxy (SSL): https://localhost:443/radicale/.web/
Only in case a dedicated virtual host (dedicated port or FQDN) is configured, the URI extension can be left-out in the reverse proxy configuration
Example config excerpt for dedicated port, for FQDN configure name-based virtual hosting.
# Apache
Listen 8080
<VirtualHost _default_:8080>
...
<Location />
ProxyPass http://localhost:5232/ retry=0
ProxyPassReverse http://localhost:5232/
...
</Location>
</VirtualHost>
Listen 8443 https
<VirtualHost _default_:8443>
...
<Location />
ProxyPass http://localhost:5232/ retry=0
ProxyPassReverse http://localhost:5232/
...
</Location>
</VirtualHost>
Example URLs to request
Radicale direct : http://localhost:5232/.web/
via reverse proxy : http://localhost:8080/.web/
via reverse proxy (SSL): https://localhost:8443/.web/
Webserver "Apache"
Example for unsuccessful request blocked by SELinux
curl -I http://localhost:80/radicale/.web/
HTTP/1.1 503 Service Unavailable
Date: Sat, 16 Mar 2024 15:41:29 GMT
Server: Apache/2.4.57 (AlmaLinux) OpenSSL/3.0.7 mod_fcgid/2.3.9 mod_qos/11.74 mod_wsgi/4.7.1 Python/3.9
Connection: close
Content-Type: text/html; charset=iso-8859-1
Example for successful request
curl -I http://localhost:80/radicale/.web/
HTTP/1.1 200 OK
Date: Sat, 16 Mar 2024 15:42:01 GMT
Server: WSGIServer/0.2 CPython/3.9.18
Content-Type: text/html; charset=UTF-8
Last-Modified: Wed, 13 Mar 2024 05:36:47 GMT
Content-Length: 8091
Webserver "nginx"
Example for unsuccessful request blocked by SELinux
curl -I http://localhost:80/radicale/.web/
HTTP/1.1 502 Bad Gateway
Server: nginx/1.20.1
Date: Sat, 16 Mar 2024 15:30:51 GMT
Content-Type: text/html
Content-Length: 3854
Connection: keep-alive
ETag: "652d1e3f-f0e"
Example for successful request
curl -I http://localhost:80/radicale/.web/
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Sat, 16 Mar 2024 15:32:56 GMT
Content-Type: text/html
Content-Length: 8091
Connection: keep-alive
Last-Modified: Wed, 13 Mar 2024 05:36:47 GMT
URI issue
In case one is serving "Radicale" not on /
, but e.g. on /radicale
, check whether "X-Script-Name" is set to main part of the URI to tell Radicale on which "hook" it is responsible for:
Apache example for "/radicale"
RequestHeader set X-Script-Name /radicale
nginx example for "/radicale"
proxy_set_header X-Script-Name /radicale;
Packet Capture
using ngrep
One can use ngrep
to watch traffic between reverse proxy and radicale (example) - but only senseful if this connection has no encryption active.
ngrep -d lo port 5232
Authorization Header suppressed
Reverse Proxy
Required option to use user authentication of radicale:
- Apache: (nothing-to-do, not blocked by default)
- nginx:
proxy_pass_header Authorization
See also example configurations:
Apache+WSGI
Required option to use user authentication of radicale: WSGIPassAuthorization On
See also example configurations:
MOVE not working
Test with
# MOVE
curl -u user:pass http://localhost/radicale/user/test3/test.ics --request MOVE -H "Destination: http://localhost/radicale/user/test2/test.ics"
MOVE Back
curl -u user:pass http://localhost/radicale/user/test2/test.ics --request MOVE -H "Destination: http://localhost/radicale/user/test3/test.ics"
General
Check for headers passed to Radicale
- X-Forwarded-Host
- X-Forwarded-Port
- X-Forwarded-Proto
Apache
See also
Note: X-Forwarded-Host
is added by default
RequestHeader set X-Forwarded-Port "%{SERVER_PORT}s"
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
nginx
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
Connection not working or flapping
In case connection from reverse proxy towards Radicale is not working or flapping check
- SELinux configuration above
- Listen socket of Radicale matches ProxyPass host configuration
System | ProxyPass host |
Radicale [server] hosts= |
Expected Result |
---|---|---|---|
IPv4-only | 127.0.0.1 | 127.0.0.1 | ok |
IPv4-only | localhost | 127.0.0.1 | ok |
IPv4-only | 127.0.0.1 | localhost | ok |
IPv4-only | localhost | localhost | ok |
IPv4+IPv6 | 127.0.0.1 | 127.0.0.1 | ok |
IPv4+IPv6 | localhost | 127.0.0.1 | flapping |
IPv4+IPv6 | 127.0.0.1 | localhost | ok |
IPv4+IPv6 | localhost | localhost | ok |