Extended Brain Storage

OpenBSD: NextCloud with WebDAV, CalDAV, CardDAV

A brief tutorial to provide Web Distributed Authoring and Versioning (WebDAV) service using NextCloud server in OpenBSD...

Introduction

HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV), defined in RFC4918, allows clients to perform remote Web content authoring operations (aka multiple users collaboration).

Calendaring Extensions to WebDAV (CalDAV) defines a standard way of accessing, managing, and sharing calendaring and scheduling information based on the iCalendar (iCal) format. It is specified in RFC4791.

vCard Extensions to WebDAV (CardDAV) defines a standard way of accessing and managing contact data (address books) based on the vCard format. It is specified in RFC6352.

The WebDAV protocol defines a new HTTP method called PROPFIND which can be used for service discovery. It can be further combined with newly introduced well-known uniform resource identifiers (URIs) aka well-known locations. The principle of the /.well-known/ path prefix is defined in RFC5785. Basically, the URIs should point to the root of the WebDAV application server as follows:

https://server.domain.tld/.well-known/caldav -> server root
https://server.domain.tld/.well-known/carddav -> server root

Hence, clients do not need to specify the whole URI rather than just the domain name of the server (e.g. https://server.domain.tld/), and the communication is as follows:

As an alternative method, it is also possible to use DNS to achieve the same thing using DNS SRV records. The labels, which are defined in RFC6764, are as follows:

_carddavs._tcp 86400 IN SRV 10 20 443 server.domain.tld.
_caldavs._tcp 86400 IN SRV 10 20 443 server.domain.tld.

Since the previous DNS records can only point to a domain name (and not a full path), DNS TXT records can be used to give the clients such information:

_caldavs._tcp     TXT path=/remote.php/dav
_carddavs._tcp    TXT path=/remote.php/dav

Note: The non-TLS (non-SSL) variants are not discussed here, as it is not recommended to use them anyway (due to the lack of encryption).


Well-known Locations Configuration

Considering that the Nextcloud server is running with httpd server in OpenBSD and was configured as per OpenBSD: Nextcloud, the necessary configuration (i.e. the location of root /remote.php/dav) is already present in /etc/httpd.conf.

As mentioned in the previously, setting the DAV URI as https://server.domain.tld (without path details) should negotiate the complete DAV path automatically. A web-server log can confirm CalDAV communication as follows:

$ tail -f /var/www/log/access.log
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND / HTTP/1.1" 405 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /.well-known/caldav HTTP/1.1" 301 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav HTTP/1.1" 207 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav/principals/users/USERNAME/ HTTP/1.1" 207 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav/calendars/USERNAME/personal/ HTTP/1.1" 207 0 "" "UserAgent"

...and CardDAV communication as follows

$ tail -f /var/www/log/access.log
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND / HTTP/1.1" 405 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /.well-known/carddav HTTP/1.1" 301 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav HTTP/1.1" 207 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav/principals/users/USERNAME/ HTTP/1.1" 207 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav/addressbooks/users/USERNAME/ HTTP/1.1" 207 0 "" "UserAgent"
server.domain.tld 192.0.2.4 - - [Date] "PROPFIND /remote.php/dav/addressbooks/users/USERNAME/contacts/ HTTP/1.1" 207 0 "" "UserAgent"

Note: Unfortunately, not all client applications adhere to the RFCs (such as Lightning); as a result of which, the specification of the server's domain name may not be sufficient and the whole URI needs to be specified instead.

Different operating systems provide different client software solutions. The following is just a very brief example of a couple of them:


WebDAV and DAVFS

Nextcloud provides apps for Android and Apple iOS as well as desktop clients for Windows, macOS and Linux. In the latter one, it is usually necessary to install appropriate driver in the client operating system. For Arch Linux, the following package needs to be installed:

$ pacman -S davfs2

There are several ways of accessing files using Linux. Considering the plain command-line interface, the USERNAME's remote Nextcloud (DAV-based) directory, located on the server.domain.tld server, can be temporarily mouted (e.g. in: /tmp/davfs) using the following command:

$ mkdir /tmp/davfs
$ mount -t davfs -o rw https://server.domain.tld/remote.php/dav/files/USERNAME /tmp/davfs

Should the following warning message occur:

/sbin/mount.davfs: warning: the server does not support locks

the use_locks 0 "cure" can be applied in /etc/davfs2/davfs2.conf as follows:

$ echo "use_locks 0" >> /etc/davfs2/davfs2.conf

In order to make the changes permanent for an unprivileged USERNAME:

$ mkdir ~/nextcloud
$ mkdir ~/.davfs2
$ cp /etc/davfs2/secrets ~/.davfs2/secrets
$ chown USERNAME:USERNAME ~/.davfs2/secrets
$ chmod 600 ~/.davfs2/secrets
$ echo "https://server.domain.tld/remote.php/dav/files/USERNAME/ USERNAME PASSWORD" >> ~/.davfs2/secrets

And finally, /etc/fstab needs to be updated as follows:

$ echo "https://server.domain.tld/remote.php/dav/files/USERNAME/ /home/USERNAME/nextcloud davfs user,rw,auto 0 0" >> /etc/fstab

The remote user's directory will be automatically mounted with the system start. If not desired, the auto parameter, can be changed to noauto. Naturally, the remote user's directory will need to be mounted and unmounted manually as follows:

$ mount ~/nextcloud
$ umount ~/nextcloud

CalDAV

When the Calendar App is activated by the administrator in Nextcloud, it can be accessed by users via web interface:

https://server.domain.tld/index.php/apps/calendar/

User's calendars (USERNAME) can be accessed by applications via the following WebDAV URL (personal is the default calendar name):

https://server.domain.tld/remote.php/dav/calendars/USERNAME/personal/

If desired, Mozilla Thunderbird's Lightning add-on can be set up as follows:

iOS and BlackBerry calendar apps do adhere to the standards. In case the "well-known" locations do not work, the URI can be manually specified as follows:

https://server.domain.tld/remote.php/dav/principals/users/USERNAME/

Example configuration for a new account in BlackBerry OS:

  1. Account setup: Settings -> Accounts
  2. Using buttons below: Add Account -> Advanced -> CalDAV
  3. Account details to be filled as follows:
  1. Confirmation by pressing Done.

CardDAV

When the Contacts App is activated by the administrator in Nextcloud, it can be accessed by users via web interface:

https://server.domain.tld/index.php/apps/contacts/

If desired, Mozilla Thunderbird's CardBook add-on can be set up as follows:

Note: Since the developer has not published the extension officialy in Mozilla Add-ons, it needs to be updated manually.

iOS and BlackBerry calendar apps do adhere to the standards. In case the "well-known" locations do not work, the URI can be manually specified as follows:

https://server.domain.tld/remote.php/dav/principals/users/USERNAME/

For Apple's Mail App in macOS, it takes up to a couple of minutes before it begins to finally download the contact from the server.

Example configuration for a new account in BlackBerry OS:

  1. Account setup: Settings -> Accounts
  2. Using buttons below: Add Account -> Advanced -> CardDAV
  3. Account details to be filled as follows:
  1. Confirmation by pressing Done.

Troubleshooting

Since WebDAV provide HTTP Extensions, it is easy to communicate with server using the HTTP(S). cURL is a command line tool and library for transferring data with URLs. It can be utilised for this purpose to connect to the CalDAV URI as follows:

$ curl -u USERNAME -X PROPFIND https://server.domain.tld/remote.php/caldav/principals/USERNAME/
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">
  <d:response>
    <d:href>/remote.php/caldav/principals/USERNAME/</d:href>
    <d:propstat>
      <d:prop>
        <d:resourcetype>
          <d:collection/>
          <d:principal/>
        </d:resourcetype>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

...or to connect to the calendar WebDAV URI as follows:

$ curl -u USERNAME -X PROPFIND https://server.domain.tld/remote.php/dav/calendars/USERNAME/personal/
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:href>/remote.php/dav/calendars/USERNAME/personal/</d:href>
    <d:propstat>
      <d:prop>
        <d:resourcetype>
          <d:collection/>
          <cal:calendar/>
        </d:resourcetype>
        <cs:getctag>http://sabre.io/ns/sync/11</cs:getctag>
        <s:sync-token>11</s:sync-token>
        <cal:supported-calendar-component-set>
          <cal:comp name="VEVENT"/>
          <cal:comp name="VTODO"/>
        </cal:supported-calendar-component-set>
        <cal:schedule-calendar-transp>
          <cal:opaque/>
        </cal:schedule-calendar-transp>
        <oc:owner-principal>principals/users/USERNAME</oc:owner-principal>
        <d:displayname>Personal</d:displayname>
        <x1:calendar-order xmlns:x1="http://apple.com/ns/ical/">0</x1:calendar-order>
        <x2:owner-displayname xmlns:x2="http://nextcloud.com/ns">USERNAME</x2:owner-displayname>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

It can be utilised for this purpose to connect to the CardDAV URI as follows:

$ curl -u USERNAME -X PROPFIND https://server.domain.tld/remote.php/carddav/principals/USERNAME/
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav">
  <d:response>
    <d:href>/remote.php/carddav/principals/USERNAME/</d:href>
    <d:propstat>
      <d:prop><d:resourcetype><d:collection/><d:principal/></d:resourcetype></d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

...or to connect to the calendar WebDAV URI as follows:

$ curl -u USERNAME -X PROPFIND https://server.domain.tld/remote.php/contacts/principals/USERNAME/ > output.xml
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav">
  <d:response>
    <d:href>/remote.php/contacts/principals/USERNAME/</d:href>
    <d:propstat>
      <d:prop>
        <d:resourcetype>
          <d:collection/>
          <d:principal/>
        </d:resourcetype>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

Tags: #OpenBSD #security #Arch Linux #Nextcloud #DAV #WebDAV #CalDAV #CardDAV

⏴ Previous Post Next Post ⏵