Tags: #OpenBSD #security #Arch Linux #Nextcloud #DAV #WebDAV #CalDAV #CardDAV
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:
- applications prompt the server on the well known URI,
- the server redirects the traffic to the application server root,
- where the application is ready to handle the DAV request.
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:
- Evolution is the official personal information manager for GNOME with built-in support for iCal and vCard formats. Unfortunately, it lacks support for the Sieve/ManageSieve protocols, though.
- Mozilla Thunderbird lacks support of either Sieve protocol or iCal and vCard formats. Luckily, they can be installed using add-on plugins, though.
- Lightning provides CalDAV support.
- CardBook provides CardDAV support.
- There is also a plugin called SOGo Connector, which unfortunately has been buggy since 2014. In 2018, it behaves exactly as described in the bug. Totally, not recommended!
- In Apple macOS, the Mail App provides built-in support for iCal and vCard formats, but lacks support for the Sieve/ManageSieve protocols.
- Apple iOS, BlackBerry OS and Android provide built-in support for iCal and vCard formats. The lack of Sieve/ManageSieve protocols support does not seem to be a problem here.
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:
- A new Calendar can be added via menu:
File -> New -> Calendar
. - Selection of Locate your calendar:
On the Network
. - Selection of Format: CalDav, followed by setting the Location:
https://server.domain.tld/remote.php/dav/calendars/USERNAME/personal/
. - The credentials are taken from the associated e-mail account.
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:
- Account setup:
Settings -> Accounts
- Using buttons below:
Add Account -> Advanced -> CalDAV
- Account details to be filled as follows:
- Description:
NAME
- Username:
USERNAME
- Email Address:
USERNAME@DOMAIN.TLD
- Password:
PASSWORD
- Server Address:
https://server.domain.tld/remote.php/dav/principals/users/USERNAME/
- 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:
- First opening shows a wizard, which can be closed and skipped.
- The CardBook can be opened via menu:
Tools -> CardBook
. - The CardBook menu can be opened via the left “three lines” icon, and needs to be followed by:
Address Book -> New Address Book
. - Selection of Address book location:
Remote
- Selection of Type:
CardDav
, followed by setting the URL:https://server.domain.tld/
and appropriate credentials.
- Alternatively, the URL can be:
https://server.domain.tld/remote.php/dav/addressbooks/users/USERNAME/contacts/
- Confirmation by pressing Validate and Next.
- Format of vCard:
4.0
(or higher if available).
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:
- Account setup:
Settings -> Accounts
- Using buttons below:
Add Account -> Advanced -> CardDAV
- Account details to be filled as follows:
- Description:
NAME
- Username:
USERNAME
- Email Address:
USERNAME@DOMAIN.TLD
- Password:
PASSWORD
- Server Address:
https://server.domain.tld/remote.php/dav/principals/users/USERNAME/
- 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>