Radicale icon indicating copy to clipboard operation
Radicale copied to clipboard

Wrong nginx config in documentation

Open vigiraud opened this issue 6 years ago • 11 comments

Hi, thanks for Radicale, it's great !

I'm using it behind a reverse proxy. I use https on both internet->nginx and nginx->radicale.

In https://radicale.org/proxy/ , it is advised to add the following to the nginx configuration file for such a use :

location /radicale/ { # The trailing / is important!
    proxy_pass        http://localhost:5232/; # The / is important!
    proxy_set_header  X-Script-Name /radicale;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass_header Authorization;
}

However, this does not work : if one tries to connect on the subdomain (and not adress.url:5232), he will get a 403 Forbidden error :

2018-06-18 00:46:36,522 - [7f81c27c5700] INFO: Access to '/radicale/user/' denied for 'user'
2018-06-18 00:46:36,522 - [7f81c27c5700] INFO: PROPFIND response status for '/radicale/user/' with depth '1' in 0.004 seconds: 403 Forbidden

Authentication works if we remove the two last lines in the nginx config citation above :

location /radicale/ { # The trailing / is important!
    proxy_pass        http://localhost:5232/; # The / is important!
    proxy_set_header  X-Script-Name /radicale;
}

This issue is discussed here : https://serverfault.com/questions/839047/radicale-permissions

vigiraud avatar Jun 17 '18 23:06 vigiraud

Just wanted to add my bits here since some other might run into problems when configuring radicale behind nginx: You need to pass / and /radicale/ separately if you want to proxy both the webUI and the DAV endpoints. For example:

        # Web UI
        location / {
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for
                proxy_pass_header Authorization;
                proxy_pass       http://roobrealm:5232/;
        }

        # DAV
        location /radicale/ {
                proxy_set_header  X-Script-Name /radicale;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for
                proxy_pass_header Authorization;
                proxy_pass       http://roobrealm:5232/;
        }

nadiamoe avatar Feb 28 '19 13:02 nadiamoe

Thank you so much! I couldn’t get my authentication working before I found this!

fiee avatar Dec 09 '19 20:12 fiee

How do we get this updated in the documentation? Will they accept PR's?

Retro64XYZ avatar Dec 10 '19 22:12 Retro64XYZ

I think they will. Opening a PR can do no harm anyway.

vigiraud avatar Dec 11 '19 13:12 vigiraud

@roobre Thank you sooooo much! I was searching for hours...

Antidote00 avatar Dec 20 '19 21:12 Antidote00

@roobre Maybe if you have some time you could take a look at my problem.

I got a traefik-reverse-proxy in front of the radicale-server. Accessing everything without the proxy works fine so that's not the issue.

The way I want it to work is that I can access my radicale instance via sample.domain.com/calendar.

After some digging I now set the X-Script-Name-Header to /calendar/ as stated in the docs. Furthermore I strip the /calendar part of the HTTP-Call.

After I try to access the radicale-server under sample.domain.com/calendar I get redirected to sample.domain.com/.web which lacks the /calendar/ path and ofc my reverse-proxy doesn't know about /.web

If I directly access sample.domain.com/calendar/.web/ I can access the web intereface because I won't get redirected.

Radicale handles the request with this Debug-Information:

[7f737829bb20] INFO: GET request for '/' received from '192.168.178.29' (forwarded by 172.19.0.3) using 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0'
[7f737829bb20] DEBUG: Request headers:
{'CONTENT_LENGTH': '',
 'CONTENT_TYPE': 'text/plain',
 'GATEWAY_INTERFACE': 'CGI/1.1',
 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
 'HTTP_ACCEPT_LANGUAGE': 'de,en-US;q=0.7,en;q=0.3',
 'HTTP_DNT': '1',
 'HTTP_HOST': 'sample.domain.com',
 'HTTP_UPGRADE_INSECURE_REQUESTS': '1',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) '
                    'Gecko/20100101 Firefox/73.0',
 'HTTP_X_FORWARDED_FOR': '192.168.178.29',
 'HTTP_X_FORWARDED_HOST': 'sample.domain.com',
 'HTTP_X_FORWARDED_PORT': '80',
 'HTTP_X_FORWARDED_PREFIX': '/calendar',
 'HTTP_X_FORWARDED_PROTO': 'http',
 'HTTP_X_FORWARDED_SERVER': '1dd0c1be93e4',
 'HTTP_X_REAL_IP': '192.168.178.29',
 'HTTP_X_SCRIPT_NAME': '/calendar/',
 'PATH_INFO': '/',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '172.19.0.3',
 'REMOTE_HOST': '',
 'REQUEST_METHOD': 'GET',
 'SCRIPT_NAME': '',
 'SERVER_NAME': '92def7bf5bf8',
 'SERVER_PORT': '5232',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SOFTWARE': 'WSGIServer/0.2',
 'wsgi.errors': <_io.StringIO object at 0x7f73783034b0>,
 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>,
 'wsgi.input': <_io.BufferedReader name=6>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': True,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}
[7f737829bb20] DEBUG: Script name overwritten by client: '/calendar/'
[7f737829bb20] DEBUG: Sanitized script name: '/calendar'
[7f737829bb20] DEBUG: Sanitized path: '/'
[7f737829bb20] DEBUG: Response content:
Redirected to .web
[7f737829bb20] INFO: GET response status for '/' in 0.000 seconds: 302 Found

I think I got the same issue as in #915 but since I'm by no way experienced in this domain I can't help myself.

Got any ideas? Any help is appreciated.

Edit: formatting Edit: clarifying the error Edit: additional information

vinerich avatar Mar 02 '20 15:03 vinerich

Hi @vinerich,

From the looks of it, this should be a bug/unimplemented feature in radicale., as it is acknowledging the existance of a script name prefix, but not appending it to the 302 response.

Nginx has a directive (proxy_redirect) that allows it to change Location headers sent by upstream servers. For traefik, based on a quick search, it seems that there is no equivalent, although you can use some regexes and achieve /more or less/ the same thing: https://www.google.com/search?q=traefik+proxy_redirect

My (probably unhelpful) advice would be to either try the regex things, or avoid using paths in reverse proxies entirely. They heavily rely on the proxied application to be aware of the proxy, and this is something that many apps do not support correctly.

nadiamoe avatar Mar 02 '20 15:03 nadiamoe

Hey @roobre thanks for the quick answer.

I thought the same about it, but since I got no experience I needed some kind of confirmation I think.

I don't know if this directive is working with traefik since the traefik structue is: Request->Endpoint->Router->Middleware->Service->Server IMO the proxy_redirect is also a middleware and can only be used one way and not back from the server but maybe I didn't take a close enough look. Edit: Modifying response-headers is totally possible. Maybe I'll try this thing then but we'll see and I'll report back here. Edit2: Please forgive all the editing. You can't modify response headers afaik, only replace them so I would state that PATH-Proxying is not an option.

Anyway I think I will go with the subdomain option. I tried using Paths for this cause then I don't need to register subdomains all the time but .. whatever.

Thanks again and I'll then open a new bug report for this so maybe it can be fixed.

vinerich avatar Mar 02 '20 15:03 vinerich

After a couple of hours of messing around, I finally found this issue to find out the mention reverse proxy configuration for nginx is still wrong on https://radicale.org/v3.html#reverse-proxy.

After making the changes suggested by roobre (https://github.com/Kozea/Radicale/issues/838#issuecomment-468266060) and fixing the typos in his post, it finally works now.

The corrected nginx reverse proxy configuration:

   # Web UI
    location / {
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_header Authorization;
            proxy_pass       http://127.0.0.1:5232/;
    }

    # DAV
    location /radicale/ {
            proxy_set_header  X-Script-Name /radicale;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_header Authorization;
            proxy_pass       http://127.0.0.1:5232/;
    }

enigma-x avatar Jan 01 '23 12:01 enigma-x

can you create a PR against "DOCUMENTATION.md" with the proposed changes?

pbiering avatar Jan 03 '23 05:01 pbiering

OMG that did cost me like 5h of my life. Thanks for https://github.com/Kozea/Radicale/issues/838#issuecomment-1368436739

RequestPrivacy avatar Jan 16 '24 15:01 RequestPrivacy

I confirmed that the example documented in https://radicale.org/v3.html#reverse-proxy is working well.

Web and DAV is served behind the leading URI part "/radicale"

For any other custom setups feel free to submit extensions to Wiki or docu.

BTW: I've created some diagnostics:

https://github.com/Kozea/Radicale/wiki/Reverse-Proxy-Diagnostics-Troubleshooting

pbiering avatar Mar 16 '24 15:03 pbiering