leafee98-blog/content/posts/部署davical到apache2.md

183 lines
8.7 KiB
Markdown
Raw Normal View History

2022-04-28 06:40:02 +00:00
---
title: "部署davical到apache2"
date: 2021-01-02T12:21:45+08:00
tags: [ linux, apache, caldav ]
categories: [ tech ]
weight: 50
show_comments: true
2022-04-28 06:40:02 +00:00
draft: false
---
起源于 radicale 的 well-known 自动配置不能与 thunderbird 的 tbsync 插件和平地工作, 以及使用 python 实现的 radicale 在过去的半年中失去响应了 3 次, 所以决定找一个可能更稳定一些, 更加通用一些的支持 caldav 的服务程序, 最终选定了 davical .
这里将在 debian 系统 apache2 上部署 davical , 同时会配置好 well-known 的重定向, 此外还会有一些实现方式的小推测.
关于软件依赖等事项不再赘述, 这里只讨论使用 apache 部署 davical 站点的过程.
## 目录
- [目录](#目录)
- [部署 davical 站点](#部署-davical-站点)
- [使用 VirtualHost 部署 davical 为一个新的站点](#使用-virtualhost-部署-davical-为一个新的站点)
- [使用软链接方式部署 davical 到一个 http 子目录](#使用软链接方式部署-davical-到一个-http-子目录)
- [使用别名(Alias)方式部署 davical 到一个 http 子目录](#使用别名alias方式部署-davical-到一个-http-子目录)
- [well-known 的配置](#well-known-的配置)
- [使用 Rewrite 部署 well-known](#使用-rewrite-部署-well-known)
- [客户端的访问体验](#客户端的访问体验)
- [使用 Redirect 部署 well-known](#使用-redirect-部署-well-known)
- [客户端的访问体验](#客户端的访问体验-1)
- [关于 Rewrite 的一些解释](#关于-rewrite-的一些解释)
- [关于 Redirect 时有无后缀斜杠的区别](#关于-redirect-时有无后缀斜杠的区别)
- [一个关于 URI 后缀斜杠并在重定向时被替换的例子](#一个关于-uri-后缀斜杠并在重定向时被替换的例子)
- [一个重定向与直接获取网页文档同时工作的例子](#一个重定向与直接获取网页文档同时工作的例子)
## 部署 davical 站点
部署 davical 有两大类别, 分别是部署为一个新的站点和部署为一个网站的子目录.
部署为新的站点比较方便, 而且不会对未来可能的新目录产生冲突, 但建议配合 DNS 来使用, 以免浪费一个 80 端口, 此外客户端的配置也十分简单.
部署为一个 http 子目录兼容性则会更好一些, 适用于更多场景.
### 使用 VirtualHost 部署 davical 为一个新的站点
部署为一个新的站点只需要创建一个新的 VirtualHost 条目, 并指定网页根目录 DocumentRoot 即可. 比如将新站点监听在本机所有 IP 的 81 端口, 只需要在 VirualHost 条目中通配指定所有 IP , 再指定端口 81 即可.
需要注意的是那个比较容易被忽略的 `Listen 81` 的指令, 这个指令要求 apache2 在运行时监听 81 端口, 如果没有这条指令则会发现站点无法正常使用, 表现为无法建立连接, 在服务器主机上也会发现没有任何进程监听 81 端口.
```
Listen 81
<VirtualHost *:81>
DocumentRoot /usr/share/davical/htdocs
</VirtualHost>
```
使用这种方式配置以后, 在客户端的配置中需要指定 caldav/carddav 的目录为根目录或忽略不写路径即可.
### 使用软链接方式部署 davical 到一个 http 子目录
这种配置方式不需要去为了建立站点或重定向来修改配置文件, 只需要在当前的站点的 DocumentRoot 的文件目录中建立一个指向 davical 的 `htdocs` 的目录的软链接即可.
```
# ls -l
total 2
-rw-r--r-- 1 root root 10701 Dec 27 23:39 index.html
lrwxrwxrwx 1 root root 26 Dec 28 02:25 davical-link -> /usr/share/davical/htdocs/
```
### 使用别名(Alias)方式部署 davical 到一个 http 子目录
在需要部署的站点 (VirtualHost) 中添加 `Alias` 指令就可以实现和建立软链接相同的效果.
需要注意是否在第一个参数 URI 中后缀一个斜杠, `Alias` 对于 URI 后缀斜杠的行为与 `Redirect` 类似, 具体在[关于 Redirect 时有无后缀斜杠的区别](#关于-redirect-时有无后缀斜杠的区别)中描述.
```
Alias "/davical" "/usr/share/davical/htdocs/"
```
## well-known 的配置
well-known 是一个将各种可能在网页文档某个路径的服务另外在路径 `/.well-known/` 下为指定名称的文档请求返回跳转响应的约定.
> 比如 caldav 服务部署在 `/davical/caldav.php` 路径, 若配置好 well-known 则访问 `/.well-known/caldav` URI 时, 会在得到一个响应头, 其中 `location` 字段为 `/davical/caldav.php`, 状态码为任意一个跳转状态码 (如 301 或 302), 随后客户端会根据得到的 URI 去再一次请求服务.
对于 davical 的 well-known 的配置可以参见其 [wiki (Well-known URLs)](https://wiki.davical.org/index.php/Well-known_URLs) , 下面也会进行简短的复述.
davical 的 well-known 工作机制要求 well-known 的访问被 `/davical-base/caldav.php/.well-known/caldav` 处理, 处理结果中, GET 请求会直接在此 URI 的网页文档下处理, **而 caldav 中用到的 PROPFIND 等请求会返回一个重定向响应, 响应路径为 `/davical-base/caldav.php`** .
在 apache 的配置当中, **一切配置的目的都是将访问到 `/.well-known/caldav` 到请求重定向到 `/davical-base/caldav.php/.well-known/caldav`**, 实现这一目的的手段有对用户透明的 `Rewrite` 和用户可见的 `Redirect` 两种.
### 使用 Rewrite 部署 well-known
假设 davical 被部署在 `/davical-base/` 下, 使用 `Rewrite` 需要先引入模块 `mod_rewrite`, 仅重写 caldav 服务的情况时, 配置如下.
```
RewriteEngine On
RewriteRule ^/\.well-known/caldav$ /davical-base/caldav.php/.well-known/caldav [NC,L]
```
#### 客户端的访问体验
```
Request: PROPFIND http://hostname/.well-known/caldav
Response: 301 location=/davical-base/caldav.php
Request: PROPFIND http://hostname/davical-base/caldav.php
Response: ... ... ... ...
```
### 使用 Redirect 部署 well-known
假设 davical 被部署在同一位置, 仅重写 caldav 服务时, 配置如下.
```
Redirect /.well-known/caldav /davical-base/caldav.php/.well-known/caldav
```
#### 客户端的访问体验
```
Request: PROPFIND http://hostname/.well-known/caldav
Response: 302 location=/davical-base/caldav.php/.well-known/caldav
Request: PROPFIND http://hostname/davical-base/caldav.php/.well-known/caldav
Response: 301 location=/davical-base/caldav.php
Request: PROPFIND http://hostname/davical-base/caldav.php
Response: ... ... ... ...
```
## 关于 Rewrite 的一些解释
`Rewrite` 是简单的修改 URI , 然后将修改后的 URI 中的资源作为响应返回给请求, **这一过程对于客户端是透明的**.
## 关于 Redirect 时有无后缀斜杠的区别
Redirect 只是一个普通的查找替换, 相当于将 URI 中特定前缀替换为第二个参数表述的字符串以后, 将修改之后的 URI 作为响应头中的 location 字段值并以 301 作为状态码返回给浏览器.
此外, 对于目录文件, 如果 URI 的目标刚好是一个目录文件, 在匹配唯一的情况下, 是否后缀斜杠以及后缀多少个斜杠对于目录项来说没有区别, 即 `/dir``/dir/` `/dir//` 没有区别. 而对于普通文档, 则后缀一个额外的斜杠以后会无法访问该文档.
### 一个关于 URI 后缀斜杠并在重定向时被替换的例子
所以对于是否加上斜杠, 应考虑是否需要要以斜杠的方式访问. 如网页根目录内容以及目标为 `tmp-file` 的重定向如下.
```
# content of the DocumentRoot
-rw-r--r-- 1 root root 9 Jan 2 00:09 tmp-file
# directive in VirtualHost
Redirect /redirect-file/ /tmp-file
```
浏览器访问 URI 为 `http://hostname/redirect-file/` 的网页时, 得到的响应头如下.
```
HTTP/1.1 302 Found
Date: Sat, 02 Jan 2021 06:43:49 GMT
Server: Apache/2.4.38 (Debian)
Location: http://hostname/tmp-file
Content-Length: 296
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
```
随后浏览器跳转到 `http://hostname/tmp-file` 最终获取到真正的网页.
请留意 302 跳转时浏览器访问时提供的 URI 中后缀的斜杠, 以及重定向指令中的源 URI 中的斜杠.
当访问的 URI 中没有后缀斜杠时, 即访问时提供的 URI 为 `http://hostname/redirect-file` 时, 此重定向指令将不会生效, 最终浏览器得到一个 404 的响应.
### 一个重定向与直接获取网页文档同时工作的例子
```
# content of the DocumentRoot
-rw-r--r-- 1 root root 9 Jan 2 00:09 redirect-dir
drw-r--r-- 1 root root 9 Jan 2 00:09 tmp-dir
# directive in VirtualHost
Redirect /redirect-dir/ /tmp-dir
```
当如上配置时, URI 为 `http://hostname/redirect-dir` 时, 会直接获取到文件 `redirect-dir` 的内容, 当 URI 为 `http://hostname/redirect-dir/` 时, 会访问到**目录** `tmp-dir` 的内容.