Skip to content

Reverse Proxy Diagnostics Troubleshooting

Peter Bieringer edited this page Nov 17, 2024 · 10 revisions

See also:

Precondition "radicale" server is running fine and accessable

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

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