Apple iCalendar's buggy SNI
TL:DR If you use Apple’s calendar client software, do not run the server on an IP and port shared with any other SSL/TLS services.
I run my own CalDAV calendar server for my family and for myself. For a very
long time I used DAViCal, but it’s always been a slight annoyance to set
up on Apple devices because they don’t like DAViCal’s
https://example.com/davical/caldav.php/majid
URLs. What’s more, recent
versions of iCalendar would pop up password prompts at random, and after
re-entering the password a couple of times (once is not enough), would finally
go on and work. The various devices would also all too often get out of sync,
sometimes with the inscrutable error:
Server responded with “500” to operation CalDAVAccountRefreshQueueableOperation
requiring deleting the calendar account and recreating it by hand.
I tried replacing DAViCal with Radicale today, with the same flaky user
experience, and I finally figured out why: Apple uses at least a couple of
daemons to manage calendar and sync, including dataaccessd
, accountsd
and
remindd
(also CalendarAgent
depending on your OS version). It seems some
or all of them do not implement Server Name Indication (SNI)
consistently. SNI is the mechanism by which a TLS client indicates what server
it is trying to connect to during the TLS handshake, so multiple servers can
share the same IP address and port, and is an absolutely vital part of the
modern web. For example many servers use Amazon Web Services’ Elastic Load
Balancer or CloudFront services, which are used by multiple clients, if Amazon
had to dedicate a separate IP address for each, it would break their business
model1.
Sometimes, those daemons will not use SNI, which means they will get your
default server. In my case, it’s password-protected with a different password
than the CalDAV one, which is what triggers the “enter password” dialog. At
other times, they will call your CalDAV server with dubious URLs like
/.well-known/caldav
, /principals/
, /dav/principals/
, /caldav/v2
and if
your server has a different HTTP password for that and sends back a HTTP 401
status code instead of a 404 Not Found
, well, that will also trigger a
reauthentication prompt.
Big Sur running on my M1 MacBook Air seems to be more consistent about using SNI, but will still poke around on those URLs, triggering the reauthentication prompts.
In other words, the only way to get and Apple-compatible calendar server
running reliably is to dedicate an IP and port to it that is not shared with
anything else. I only have one IP address at home where the server runs, and I
run other vital services behind HTTPS, so I can’t dedicate 443 to a CalDAV
server. Fortunately, the configuration will accept the syntax
example.org:8443
to use a non-standard port (make sure you use the Advanced
option, not Automatic), but this is incredibly sloppy of Apple.
-
Amazon does in fact have a Legacy Clients Support option, but they charge a $600/month fee for that, and if you need more than two, they will demand written justification before approving your request. ↩︎