• Wondering if the experts here can throw in some advice for me.

    I have a Traefik 2.3 Reverse Proxy in front of my Kopano Core installation including KDAV.

    The Traefik reverse proxy rewrites anything with .well_known/{card,cal}dav to the KDAV server.php which is hosted via Nginx and PHP-FPM.

    I can visit via my own web browser to dav.example.com being met with basic authentication to where I am able to enter my Kopano username and password with success being presented with the SabreDAV interface.

    Where things go sideways is trying to connect a client to the KDAV installation - Whether I use automatic configuration (based on trying to get information via .well-known hints) or manual where I am requesting https://dav.example.com/calendars/username/Calendar it fails. Looking at the web server logs the client issues a PROPFIND request to the server and then responds with a 200 OK response, with no details to give any more hints.

    Request:
    <d:propfind xmlns:d="DAV:"><d:prop><d:current-user-principal /></d:prop></d:propfind>
    
    Response:
    <?xml version="1.0" encoding="utf-8" ?>
    <D:multistatus xmlns:D="DAV:">
    <D:response>
    <D:href>/</D:href>
    <D:propstat>
    <D:prop>
    </D:prop>
    <D:status>HTTP/1.1 200 OK</D:status>
    </D:propstat>
    </D:response>
    </D:multistatus>
    

    I’m willing to bet that there’s something to do with my Nginx configuration here, so figured I’d let others see how I have configured it to see if anything jumps out as wrong, or if there is a better way to do this.

    site.conf

      server {
         server_name dav.example.com;
         listen 80;
         root /usr/share/kdav;
         index  server.php;
         dav_methods     PUT DELETE MKCOL COPY MOVE;
         dav_ext_methods PROPFIND OPTIONS;
         create_full_put_path on;
         dav_access user:rw group:rw all:r;
    
         location /server.php {
    
            access_log  /logs/nginx/kdav-access.log;
            error_log   /logs/nginx/kdav-error.log;
    
            try_files $uri $uri/ /?$args;
    
             location ~ \.php(/|$) {
                include /etc/nginx/nginx.conf.d/php-fpm.conf;
                fastcgi_split_path_info ^(.+?\.php)(/.+)$;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_index server.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             }
          }
    
    }
    

    Alternatively, here’s how it looks with curl.

    curl -Lv -X PROPFIND --header "Depth: 0" -u "username:password" https://dav.example.com/.well-known/carddav
    *   Trying 111.222.111.222:443...
    * Connected to dav.example.com (111.222.111.222) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: /etc/ssl/certs/ca-certificates.crt
      CApath: none
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
    * TLSv1.3 (IN), TLS handshake, Certificate (11):
    * TLSv1.3 (IN), TLS handshake, CERT verify (15):
    * TLSv1.3 (IN), TLS handshake, Finished (20):
    * TLSv1.3 (OUT), TLS handshake, Finished (20):
    * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: CN=dav.example.com
    *  start date: Oct  9 15:26:22 2020 GMT
    *  expire date: Jan  7 15:26:22 2021 GMT
    *  subjectAltName: host "dav.example.com" matched cert's "dav.example.com"
    *  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
    *  SSL certificate verify ok.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Server auth using Basic with user 'username'
    * Using Stream ID: 1 (easy handle 0x559b6e11aa70)
    > PROPFIND /.well-known/carddav HTTP/2
    > Host: dav.example.com
    > authorization: Basic ZGF2ZWNvbnJveTpUaXJlZG9mSVRcITIwMTk=
    > user-agent: curl/7.72.0
    > accept: */*
    > depth: 0
    > 
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
    < HTTP/2 308 
    < location: https://dav.example.com/
    < vary: Accept-Encoding
    < content-type: text/plain; charset=utf-8
    < content-length: 18
    < date: Fri, 09 Oct 2020 20:32:10 GMT
    < 
    * Ignoring the response-body
    * Connection #0 to host dav.example.com left intact
    * Issue another request to this URL: 'https://dav.example.com/'
    * Found bundle for host dav.example.com: 0x559b6e114760 [can multiplex]
    * Re-using existing connection! (#0) with host dav.example.com
    * Connected to dav.example.com (111.222.111.222) port 443 (#0)
    * Server auth using Basic with user 'username'
    * Using Stream ID: 3 (easy handle 0x559b6e11aa70)
    > PROPFIND / HTTP/2
    > Host: dav.example.com
    > authorization: Basic ZGF2ZWNvbnJveTpUaXJlZG9mSVRcITIwMTk=
    > user-agent: curl/7.72.0
    > accept: */*
    > depth: 0
    > 
    < HTTP/2 207 
    < content-type: text/xml; charset=utf-8
    < date: Fri, 09 Oct 2020 20:32:10 GMT
    < server: nginx/1.19.2
    < vary: Accept-Encoding
    < content-length: 424
    < 
    <?xml version="1.0" encoding="utf-8" ?>
    <D:multistatus xmlns:D="DAV:">
    <D:response>
    <D:href>/</D:href>
    <D:propstat>
    <D:prop>
    <D:displayname>/</D:displayname>
    <D:getlastmodified>Fri, 09 Oct 2020 20:09:04 GMT</D:getlastmodified>
    <D:resourcetype><D:collection/></D:resourcetype>
    <D:lockdiscovery/>
    <D:supportedlock>
    </D:supportedlock>
    </D:prop>
    <D:status>HTTP/1.1 200 OK</D:status>
    </D:propstat>
    </D:response>
    </D:multistatus>
    * Connection #0 to host dav.example.com left intact
    

    Even trying to go directly to the calendar as recommended in another thread:

    URL:
    https://dav.example.com/calendars/username/calendar/ (PROPFIND)
    
    Request:
    <d:propfind xmlns:d="DAV:"><d:prop><d:current-user-principal /></d:prop></d:propfind>
    
    Response:
    <?xml version="1.0" encoding="utf-8" ?>
    <D:multistatus xmlns:D="DAV:">
    <D:response>
    <D:href>/</D:href>
    <D:propstat>
    <D:prop>
    </D:prop>
    <D:status>HTTP/1.1 200 OK</D:status>
    </D:propstat>
    </D:response>
    </D:multistatus>
    

    KDAV config.php

    <?php
    define('MAPI_SERVER', 'file:///var/run/kopano/server.sock');
    define('SABRE_AUTH_REALM', 'DAV');
    define('DAV_ROOT_URI', '/');
    define('SYNC_DB', 'sqlite:/data/kdav/syncstate.db');
    define('MAX_SYNC_ITEMS', 1000);
    define('DEVELOPER_MODE', TRUE);
    

    When setting DEVELOPER_MODE to False I get the following in my logs and on screen when visiting https://dav.example.com thru a browser.

    ( ! ) Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /usr/share/kdav/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php on line 321
    Call Stack
    #	Time	Memory	Function	Location
    1	0.0013	395768	{main}( )	.../server.php:0
    2	0.1763	1101416	spl_autoload_call ( )	.../server.php:92
    3	0.1763	1101472	Composer\Autoload\ClassLoader->loadClass( )	.../server.php:92
    4	0.1763	1101584	Composer\Autoload\includeFile( )	.../ClassLoader.php:322
    3.2.2 Sabre\DAV\Exception\NotImplemented There was no plugin in the system that was willing to handle this GET method. Enable the Browser plugin to get a better result here.
    

    KDAV: master | Nginx 1.19.3 | PHP 7.3.20 | Traefik 2.3.1
    Any help would be appreciated!