Compare commits

...

3 Commits

Author SHA1 Message Date
1d070f1f05 update memos 2026-01-22 02:13:05 +01:00
6600f2e9c8 update vvenc.md 2026-01-22 00:20:01 +01:00
67869d7316 update mail-service.md 2026-01-21 23:50:04 +01:00
5 changed files with 210 additions and 53 deletions
+1 -10
View File
@@ -124,9 +124,7 @@
它的作用是解压一个只含有一个顶层目录的 tarballcd 进入解压后得到的目录,生成一个 shell并在这个 shell 退出时清理先前解压得到的文件。 它的作用是解压一个只含有一个顶层目录的 tarballcd 进入解压后得到的目录,生成一个 shell并在这个 shell 退出时清理先前解压得到的文件。
另外还有对于在 LFS 与 BLFS 中编译包的一些通用建议: 另外还有对于在 LFS 与 BLFS 中编译包的一些通用建议:
1. 通常来说,应该(或者说请务必)在编译和安装一个包后完全删除它的目录,仅有少数例外: 1. 通常来说,应该(或者说请务必)在编译和安装一个包后完全删除它的目录,仅有少数例外:
- linux保留构建树可以缩短重新构建耗时或至少保留 config 便于复原配置) - linux保留构建树可以缩短重新构建耗时或至少保留 config 便于复原配置)
- blfs-bootscripts在 BLFS 中) - blfs-bootscripts在 BLFS 中)
@@ -135,7 +133,6 @@
2. 通常来说,建议将所有相关的 tarball 和 patch 下载在同一个目录中,并且将 tarball 也解压在这个目录中。如果目录层级与该默认情况不一致的话必须修改 LFS 书中提供的命令中对应的相对路径。 2. 通常来说,建议将所有相关的 tarball 和 patch 下载在同一个目录中,并且将 tarball 也解压在这个目录中。如果目录层级与该默认情况不一致的话必须修改 LFS 书中提供的命令中对应的相对路径。
3. 如果和我一样使用 UEFI 引导,那么大概率将会在 [8.64. GRUB-2.12](https://www.linuxfromscratch.org/lfs/view/stable/chapter08/grub.html) 第一次接触 BLFS。和 LFS 不同BLFS 中大多数包都是可选的,一个包可能会依赖其他包,这些依赖分为三个层级: 3. 如果和我一样使用 UEFI 引导,那么大概率将会在 [8.64. GRUB-2.12](https://www.linuxfromscratch.org/lfs/view/stable/chapter08/grub.html) 第一次接触 BLFS。和 LFS 不同BLFS 中大多数包都是可选的,一个包可能会依赖其他包,这些依赖分为三个层级:
- Required - Required
- Recommended - Recommended
- Optional - Optional
@@ -203,7 +200,6 @@
- [8.64. GRUB-2.12](https://www.linuxfromscratch.org/lfs/view/stable/chapter08/grub.html) - [8.64. GRUB-2.12](https://www.linuxfromscratch.org/lfs/view/stable/chapter08/grub.html)
对于 UEFI 引导的系统,此时需要跳转 BLFS 安装 GRUB。为避免过早地陷入依赖地狱建议仅按照顺序安装以下包 对于 UEFI 引导的系统,此时需要跳转 BLFS 安装 GRUB。为避免过早地陷入依赖地狱建议仅按照顺序安装以下包
1. [efivar-39](https://www.linuxfromscratch.org/blfs/view/12.4/postlfs/efivar.html) 1. [efivar-39](https://www.linuxfromscratch.org/blfs/view/12.4/postlfs/efivar.html)
2. [Popt-1.19](https://www.linuxfromscratch.org/blfs/view/12.4/general/popt.html) 2. [Popt-1.19](https://www.linuxfromscratch.org/blfs/view/12.4/general/popt.html)
3. [efibootmgr-18](https://www.linuxfromscratch.org/blfs/view/12.4/postlfs/efibootmgr.html) 3. [efibootmgr-18](https://www.linuxfromscratch.org/blfs/view/12.4/postlfs/efibootmgr.html)
@@ -222,7 +218,6 @@
- [10.3. Linux-6.16.1](https://www.linuxfromscratch.org/lfs/view/stable/chapter10/kernel.html) - [10.3. Linux-6.16.1](https://www.linuxfromscratch.org/lfs/view/stable/chapter10/kernel.html)
内核配置是整本 LFS 书中最具有挑战的环节。对此我可以总结出几点建议: 内核配置是整本 LFS 书中最具有挑战的环节。对此我可以总结出几点建议:
- 复刻并裁剪现有配置 - 复刻并裁剪现有配置
如果将要使用正在构建的 LFS 系统的机器和 Host 完全相同,并且内核版本相同或相近,可以将 Host 现在运行的内核的配置文件搬过来,同时仅启用当前 Host 加载的内核模块,这将极大地减小配置难度和缩短构建耗时: 如果将要使用正在构建的 LFS 系统的机器和 Host 完全相同,并且内核版本相同或相近,可以将 Host 现在运行的内核的配置文件搬过来,同时仅启用当前 Host 加载的内核模块,这将极大地减小配置难度和缩短构建耗时:
@@ -266,12 +261,10 @@
- `<*>` or `<M>` - `<*>` or `<M>`
对于大多数选项建议选择模块化M而非内置\*)。这将显著减少内核体积,并且提高灵活性。但有几种情况例外,例如: 对于大多数选项建议选择模块化M而非内置\*)。这将显著减少内核体积,并且提高灵活性。但有几种情况例外,例如:
- 引导相关的选项(例如 EFI 支持)必须内置,否则无法引导。 - 引导相关的选项(例如 EFI 支持)必须内置,否则无法引导。
- 一些必要的文件系统(例如 ext4建议内置否则可能无法挂载根文件系统。 - 一些必要的文件系统(例如 ext4建议内置否则可能无法挂载根文件系统。
也有必须模块化的情况,例如: 也有必须模块化的情况,例如:
- 需要固件支持的驱动程序(如 i915除非使用 initrd 或将固件内置到内核中。 - 需要固件支持的驱动程序(如 i915除非使用 initrd 或将固件内置到内核中。
- [10.4. Using GRUB to Set Up the Boot Process](https://www.linuxfromscratch.org/lfs/view/stable/chapter10/grub.html) - [10.4. Using GRUB to Set Up the Boot Process](https://www.linuxfromscratch.org/lfs/view/stable/chapter10/grub.html)
@@ -297,7 +290,6 @@
BLFS 并不像 LFS 那样有线性的章节顺序,但仍建议先顺序阅读直到 [After LFS Configuration Issues](https://www.linuxfromscratch.org/blfs/view/stable/postlfs/config.html) 章节**结束**再按自己的需要安装各种包。 BLFS 并不像 LFS 那样有线性的章节顺序,但仍建议先顺序阅读直到 [After LFS Configuration Issues](https://www.linuxfromscratch.org/blfs/view/stable/postlfs/config.html) 章节**结束**再按自己的需要安装各种包。
- `su: must be run from a terminal` - `su: must be run from a terminal`
1. What? 1. What?
这通常发生在 chroot 后使用 `su` 切换到普通用户,再使用 `su` 试图切换回 root 时。 这通常发生在 chroot 后使用 `su` 切换到普通用户,再使用 `su` 试图切换回 root 时。
@@ -344,7 +336,6 @@
``` ```
其中: 其中:
- `-D gallium-drivers=iris,llvmpipe` - `-D gallium-drivers=iris,llvmpipe`
- 不包含 NVIDIA 相关的参数,因为 NVIDIA 专有驱动自带完整的 OpenGL 支持,不需要 Mesa 提供。 - 不包含 NVIDIA 相关的参数,因为 NVIDIA 专有驱动自带完整的 OpenGL 支持,不需要 Mesa 提供。
- 同时启用 llvmpipe 用于 OpenGL 上下文中的软件渲染以防万一。 - 同时启用 llvmpipe 用于 OpenGL 上下文中的软件渲染以防万一。
@@ -437,7 +428,7 @@
</details> </details>
原因是源文件显式包含了多余的 moc 文件,和自动生成的元对象代码冲突,导致重复定义。出问题的源文件有两个,可以通过以下命令修复: 原因是源文件显式 include 了多余的 moc 文件,和自动生成的相同作用的代码冲突,导致重复定义。出问题的源文件有两个,可以通过以下命令修复:
```bash ```bash
sed -i -E 's|\s*#include "moc_.*|// &|g' qtpositioning/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.cpp qtpositioning/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp sed -i -E 's|\s*#include "moc_.*|// &|g' qtpositioning/src/plugins/position/geoclue2/qgeopositioninfosourcefactory_geoclue2.cpp qtpositioning/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp
+191 -39
View File
@@ -4,11 +4,66 @@
> >
> 仅记录我的折腾过程, 并非指南, 并非推荐, 并非技术文档. > 仅记录我的折腾过程, 并非指南, 并非推荐, 并非技术文档.
## 目录
- [目录](#目录)
- [要做什么](#要做什么)
- [需要什么](#需要什么)
- [放开那个端口!](#放开那个端口)
- [注册 SMTP 中继服务](#注册-smtp-中继服务)
- [配置 DNS 和 rDNS](#配置-dns-和-rdns)
- [在 DNS 服务商处](#在-dns-服务商处)
- [在云服务器商处](#在云服务器商处)
- [在服务器上](#在服务器上)
- [配置邮件服务器](#配置邮件服务器)
- [搞定 SSL](#搞定-ssl)
- [创建 compose.yaml](#创建-composeyaml)
- [创建邮箱账号](#创建邮箱账号)
- [配置 SPF](#配置-spf)
- [配置 DKIM](#配置-dkim)
- [配置 DMARC](#配置-dmarc)
- [启动!](#启动)
- [Rspamd Web UI](#rspamd-web-ui)
- [配置邮件客户端](#配置邮件客户端)
- [exim4: 我呢?](#exim4-我呢)
- [Catch'em All!](#catchem-all)
- [Extra Notes](#extra-notes)
- [MTA-STS](#mta-sts)
- [查看报告](#查看报告)
- [邮件传输链路](#邮件传输链路)
- [为什么要做自建邮局?](#为什么要做自建邮局)
## 要做什么 ## 要做什么
一个概览.
1. 在自己的服务器上配置邮件服务器, 直接接收邮件; 1. 在自己的服务器上配置邮件服务器, 直接接收邮件;
2. 使用 SMTP 中继服务发送邮件; 2. 配置邮件服务器通过 SMTP 中继服务发送邮件;
> 或者也可以让邮件服务器直接发信, 但要额外做好以下准备:
>
> - 出入站均畅通无阻的 25 端口
>
> 大多数云服务商默认封锁 25 端口的出站流量, 需要联系或付费解封.
>
> - 良好的 IP 声誉
>
> 可以通过 [mxtoolbox](https://mxtoolbox.com) 或类似网站检查 IP 是否在任意黑名单中. 如果在的话也不是没救, 可以查查对应黑名单的影响范围, 有些其实根本无人在意.
>
> - 绝对完善的安全策略
>
> 很多对于使用 SMTP 中继服务时可选的配置在自己发信的场景下是基本要求, 例如 rDNS, DKIM 等. 可以通过 [mail-tester.com](https://www.mail-tester.com) 或 [Hardenize](https://www.hardenize.com/) 等网站检查配置是否完善.
>
> - 耗费数周乃至数月培养 IP 声誉的时间与物质成本
>
> 多少沾点玄学. 举个例子, 在这个过程中需要持续向多个公共邮箱平台的多个邮箱发送**有效**邮件, 什么样的邮件是"有效"的? 不知道. 发送多少封才能被认为"无害"? 也不知道. 发送到多少封会被认为"滥用"? 不知道. 不同平台具体采取什么样的评估标准? 还是不知道. 对于纯良的个人邮局来说这无疑是最大的挑战
>
> - IP 长期保活的持久战准备
>
> 及时在上面的一点中成功培养了良好的初始声誉, 如果后续不进行长期维护仍然可能会回到垃圾箱. 这不是短期努力可以解决的, 而需要长期坚持.
>
> 如果确实觉得没问题, 那么可以忽略下文中所有有关 SMTP 中继相关的内容. 其实就本文包含的步骤而言区别并没有很大, 下文中相关的地方会以引用的形式进行标注.
3. 配置 SPF/DKIM/DMARC/MTA-STS 等等. 3. 配置 SPF/DKIM/DMARC/MTA-STS 等等.
@@ -25,36 +80,26 @@
3. SMTP 中继服务. 3. SMTP 中继服务.
也就是帮发邮件的服务商, 详见后续章节. 也就是帮发邮件的服务商, 详见后续章节.
> 或者也可以自己发, 但要额外做好以下准备:
>
> - 出入站均畅通无阻的 25 端口
> - 良好的 IP 声誉
> - 绝对完善的安全策略
> - 耗费数周乃至数月培养 IP 声誉的时间与物质成本
> - 为 IP 长期保活的持久战准备
>
> 如果确实觉得没问题, 那么可以忽略下文中所有有关 SMTP 中继相关的内容, 就本文包含的内容而言步骤区别并没有很大.
4. 一个拥有公网 IP 和充足空闲资源的服务器, 并且(至少)需要开通以下 TCP 端口: 4. 一个拥有公网 IP 和充足空闲资源的服务器, 并且(至少)需要开通以下 TCP 端口:
| 端口 | 用途 | 出站 | 入站 | 说明 | | 端口 | 用途 | 出站 | 入站 | 说明 |
| ---- | --------------- | ---- | ---- | --------------------------------------------------- | | ---- | --------------- | ---- | ---- | --------------------------------------------------- |
| 25 | SMTP | | ✅ | 核心传输端口. 如果使用 SMTP 中继服务, 则不需要出站 | | 25 | SMTP | ⚠️ | ✅ | 核心传输端口. 如果使用 SMTP 中继服务, 则出站可选 |
| 993 | IMAPS | ❌ | ✅ | 用于邮件客户端收信 | | 993 | IMAPS | ❌ | ✅ | 用于邮件客户端收信 |
| 587 | SMTP Submission | | ✅ | 支持 STARTTLS. 如果使用 SMTP 中继服务, 则也需要出站 | | 587 | SMTP Submission | ⚠️ | ✅ | 支持 STARTTLS. 如果使用 SMTP 中继服务, 则也需要出站 |
| 465 | SMTPS | ❌ | ✅ | 支持 Implicit SSL/TLS. | | 465 | SMTPS | ❌ | ✅ | 支持 Implicit SSL/TLS |
很多云服务商会默认屏蔽 25 端口的出站方向流量, 但这对于使用 SMTP 中继服务的场景来说并不重要, 因为发信时直接连接收件方服务器的并非自己的服务器. 很多云服务商会默认屏蔽 25 端口的出站方向流量, 但这对于使用 SMTP 中继服务的场景来说并不重要, 因为发信时直接连接收件方服务器的并非自己的服务器.
同时, 最好支持 rDNS, 也就是把 IP 反解析到域名. IPv4 和 IPv6 用到哪个就配置哪个, 都用得到就都配置. 同时, 最好支持 rDNS, 也就是把 IP 反解析到域名. IPv4 和 IPv6 用到哪个就配置哪个, 都用得到就都配置.
> 如果不使用 SMTP 中继服务, 则必须配置 rDNS > 如果选择直接发信不使用 SMTP 中继服务, 则必须配置 rDNS
下文中将使用 `1.14.5.14` 作为服务器的公网 IP 地址. 下文中将使用 `1.14.5.14` 作为服务器的公网 IP 地址.
## 放开那个 25 端口! ## 放开那个端口!
1. 检测 25 端口是否真的开放: 1. 检测 25 端口是否真的开放:
@@ -92,7 +137,7 @@
2. 解决占用: 2. 解决占用:
我的服务器是 Debian 13 系统, 默认使用 `exim4` 作为邮件传输代理(MTA). 它监听 127.0.0.1:25, 因此除了在防火墙里放行 25 端口外, 还需要禁用 `exim4`. 我的服务器是 Debian 13 系统, 默认使用 `exim4` 作为邮件传输代理(MTA). 不出意外的话 25 端口已经在它手里攥了很久了. 因此除了在防火墙里放行 25 端口外, 还需要禁用 `exim4`.
```bash ```bash
sudo systemctl disable --now exim4 sudo systemctl disable --now exim4
@@ -102,7 +147,9 @@
## 注册 SMTP 中继服务 ## 注册 SMTP 中继服务
此类服务可以大致理解为"帮你发邮件的中介", 他们有一大堆 IP 地址, 这些地址的声誉都不错, 因此用他们发信的话, 邮件更容易送达收件箱而不是自动进入垃圾箱. 并且也可以避免 25 端口出站被封的问题. > 如果选择直接发信不使用 SMTP 中继服务, 则**跳过**本节内容.
此类服务可以大致理解为"帮忙发邮件的中介", 他们通常有很多 IP 地址, 这些地址的声誉都不错, 配置也很完善, 因此用他们发信的话, 邮件更容易送达收件箱而不是自动被扔进垃圾箱. 并且这也可以避免 25 端口出站被封的问题.
我此次用的是 [Resend](https://resend.com), 其他类似服务还有 Amazon SES, Mailgun 等等. 我此次用的是 [Resend](https://resend.com), 其他类似服务还有 Amazon SES, Mailgun 等等.
@@ -129,7 +176,11 @@
- 值: `mail.domain.tld` - 值: `mail.domain.tld`
- 优先级: `10` - 优先级: `10`
这将会是邮件的接收和发送服务器. 这将会是邮件的接收和发送服务器的域名.
> [!TIP]
>
> 如果乐意的话可以把收信域名, 发信域名, 乃至退信域名等等都拆分开来配置, 但这超过了本文的讨论范围且配置大同小异, 因此不做另外说明 ~~主要是懒~~ :)
- A 记录: - A 记录:
- 主机名: `mail` - 主机名: `mail`
@@ -137,12 +188,14 @@
指向邮件服务器的公网 IP 地址. 指向邮件服务器的公网 IP 地址.
其他记录会在启动邮件服务器后配置. 其他记录会在启动邮件服务器后配置.
### 在云服务器商处 ### 在云服务器商处
将服务器 ip 的 rDNS 设置为 `mail.domain.tld`. 虽然未来主要使用 Resend 发信, 但是收信时一些发信方也可能会检查 rDNS, 因此最好设置正确, 有备无患. 将服务器 ip 的 rDNS 设置为 `mail.domain.tld`. 虽然未来主要使用 Resend 发信, 但是收信时一些发信方也可能会检查 rDNS, 因此最好设置正确, 有备无患.
> 如果选择直接发信不使用 SMTP 中继服务, 则**必须**配置 rDNS
### 在服务器上 ### 在服务器上
同时, `/etc/hosts` 最好也包含 `mail.domain.tld`. 同时, `/etc/hosts` 最好也包含 `mail.domain.tld`.
@@ -166,12 +219,12 @@
或者也可以让 `docker-mailserver` 自己申请证书, 但是我的服务器的 `80` 和 `443` 端口都是 `openresty` 的, 并且恰好有合适的证书, 不想折腾了. 或者也可以让 `docker-mailserver` 自己申请证书, 但是我的服务器的 `80` 和 `443` 端口都是 `openresty` 的, 并且恰好有合适的证书, 不想折腾了.
### 创建 `compose.yaml` ### 创建 compose.yaml
```yaml ```yaml
services: services:
mailserver: mailserver:
image: docker.io/mailserver/docker-mailserver:latest image: docker.io/mailserver/docker-mailserver:15.1.0
container_name: mailserver container_name: mailserver
restart: unless-stopped restart: unless-stopped
cap_add: cap_add:
@@ -228,11 +281,12 @@ services:
以上配置中**必须**修改的地方有: 以上配置中**必须**修改的地方有:
- `domain.tld`: 替换为真实域名. - `domain.tld`: 替换为真实域名.
- `resend`: 替换为在 SMTP 服务商处创建的真实用户名.
- `res_some_random_api_key`: 替换为在 SMTP 服务商处创建的 SMTP 凭据或 API Key. - `res_some_random_api_key`: 替换为在 SMTP 服务商处创建的 SMTP 凭据或 API Key.
一些 environment 的解释: 一些 environment 的解释:
- 如果机器性能孱弱或很在意占用的资源, 可以关掉 [Raspamd](https://docker-mailserver.github.io/docker-mailserver/latest/config/security/rspamd/) 使用老东西: - 如果机器性能孱弱或很在意占用的资源, 可以关掉 [Rspamd](https://docker-mailserver.github.io/docker-mailserver/latest/config/security/rspamd/) 使用老东西:
- `ENABLE_AMAVIS=1` - `ENABLE_AMAVIS=1`
- `ENABLE_OPENDKIM=1` - `ENABLE_OPENDKIM=1`
- `ENABLE_OPENDMARC=1` - `ENABLE_OPENDMARC=1`
@@ -241,11 +295,6 @@ services:
- `ENABLE_RSPAMD=0` - `ENABLE_RSPAMD=0`
- `RSPAMD_LEARN=0` - `RSPAMD_LEARN=0`
- 如果不需要 SMTP 中继服务, 可以删除以下环境变量:
- `DEFAULT_RELAY_HOST=[smtp.resend.com]:587`
- `RELAY_USER=resend`
- `RELAY_PASSWORD=res_some_random_api_key`
- 如果垃圾邮件实在太多: - 如果垃圾邮件实在太多:
- `RSPAMD_GREYLISTING=1` - `RSPAMD_GREYLISTING=1`
@@ -265,7 +314,13 @@ services:
- `POSTFIX_INET_PROTOCOLS=ipv4`: - `POSTFIX_INET_PROTOCOLS=ipv4`:
如果服务器的 IPv6 配置不完善, 可以强制 Postfix 仅使用 IPv4. 如果服务器的 IPv6 配置不完善, 可以强制 Postfix 仅使用 IPv4. 反之也可以只支持 IPv6.
> 如果选择直接发信不使用 SMTP 中继服务, **必须**删除以下环境变量:
>
> - `DEFAULT_RELAY_HOST=[smtp.resend.com]:587`
> - `RELAY_USER=resend`
> - `RELAY_PASSWORD=res_some_random_api_key`
如果要进行进一步配置, 必须先启动容器. 此时会报错, 因为还没有创建邮箱账号. 但不用管, 先让它跑着. 如果要进行进一步配置, 必须先启动容器. 此时会报错, 因为还没有创建邮箱账号. 但不用管, 先让它跑着.
@@ -295,17 +350,24 @@ SPF 记录用于指定哪些服务器被允许代表该域名发送邮件.
- SPF 记录 (TXT 记录): - SPF 记录 (TXT 记录):
- 主机名: `@` - 主机名: `@`
- 值: `v=spf1 mx include:resend.com -all` (假设使用 Resend 作为 SMTP 服务商) - 值: `v=spf1 include:resend.com -all` (假设使用 Resend 作为 SMTP 服务商)
解释: 解释:
- `v=spf1`: 指定 SPF 版本. - `v=spf1`: 指定 SPF 版本.
- `mx`: 允许通过 MX 记录指定的服务器发送邮件. - `include:resend.com`: 允许 Resend 的服务器以此域名的名义发送邮件.
- `include:resend.com`: 允许 Resend 的服务器发送邮件.
- `-all`: 硬失败, 未授权的服务器发送邮件时拒绝. 因为发行渠道只有 Resend, 所以这样设置是合理的. 如果希望软失败, 即接受但标记为可疑, 可以使用 `~all`. - `-all`: 硬失败, 未授权的服务器发送邮件时拒绝. 因为发行渠道只有 Resend, 所以这样设置是合理的. 如果希望软失败, 即接受但标记为可疑, 可以使用 `~all`.
> 如果选择直接发信不使用 SMTP 中继服务, 则**需要**将 `include:resend.com` 替换为自己的邮件服务器的 IP 地址或域名, 例如:
>
> `v=spf1 a:mail.domain.tld -all`
>
> 详细语法参见 [SPF 规范](https://datatracker.ietf.org/doc/html/rfc7208).
### 配置 DKIM ### 配置 DKIM
DKIM (DomainKeys Identified Mail) 用于验证邮件的完整性和真实性. DKIM (DomainKeys Identified Mail) 用于验证邮件的完整性和真实性. 对于使用 SMTP 中继服务的场景, DKIM 通常由服务商负责配置和签署, 但仍推荐在自建服务器侧进行签名以保证邮件从源头开始的完整性.
> 如果选择直接发信而非使用 SMTP 中继服务, 则本节内容是**必须的**.
1. 生成 DKIM 密钥: 1. 生成 DKIM 密钥:
@@ -397,7 +459,7 @@ docker compose up -d
## 配置邮件客户端 ## 配置邮件客户端
我并非 TUI 重度爱好者, 日常用 Thunderbird 当客户端. 我并非 TUI 重度爱好者, 日常用 Thunderbird 当客户端. 这里只涉及这一种客户端的配置方法, 当然其他的也大同小异.
1. 在添加邮箱的第一个页面, 点击 `MANUAL CONFIGURATION`. 1. 在添加邮箱的第一个页面, 点击 `MANUAL CONFIGURATION`.
@@ -502,7 +564,11 @@ docker compose up -d
echo "This is a test email from the system." | mail -s "Test Email" root echo "This is a test email from the system." | mail -s "Test Email" root
``` ```
如果一切正常, 应该会在前面配置的邮箱客户端中收到这封测试邮件. 如果一切正常, 应该会在前面配置的邮箱客户端中收到这封测试邮件.
> [!NOTE]
>
> 此时可将 msmtp 看作 mailserver 的客户端, 因此 `/etc/msmtprc` 中配置的邮件服务器并不一定要部署在本机, 甚至可以是公共邮箱服务.
## Catch'em All! ## Catch'em All!
@@ -514,7 +580,13 @@ docker exec -it mailserver setup alias add @domain.tld me@domain.tld
将其中 `me@domain.tld` 替换为希望接收这些邮件的真实邮箱地址即可. 将其中 `me@domain.tld` 替换为希望接收这些邮件的真实邮箱地址即可.
## 更进一步 > [!WARNING]
>
> 完全按照上述步骤配置通配符邮箱别名可能会导致后续添加其他邮箱时邮件仍然发到上面指定的 catch-all 邮箱而不是新创建的邮箱. 更好的实践是用到什么邮箱名再创建对应的别名.
## Extra Notes
### MTA-STS
**MTA-STS** (Mail Transfer Agent Strict Transport Security) 通过强制要求发送方使用加密连接发送邮件防止中间人攻击, 对个人邮箱来讲~~看起来其实没啥大用但总归~~是个加分项, 并且确实会让邮箱服务变得更酷. **MTA-STS** (Mail Transfer Agent Strict Transport Security) 通过强制要求发送方使用加密连接发送邮件防止中间人攻击, 对个人邮箱来讲~~看起来其实没啥大用但总归~~是个加分项, 并且确实会让邮箱服务变得更酷.
@@ -583,14 +655,94 @@ docker exec -it mailserver setup alias add @domain.tld me@domain.tld
- 从支持 MTA-STS 的邮箱服务商 (例如 Gmail) 发送测试邮件, 查看 Postfix 日志来验证入站时 TLS 握手等流程是否符合预期. 至于 MTA-STS 是否真的生效, 可以稍后查看 TLS-RPT 报告邮箱收到的相关报告来确认. - 从支持 MTA-STS 的邮箱服务商 (例如 Gmail) 发送测试邮件, 查看 Postfix 日志来验证入站时 TLS 握手等流程是否符合预期. 至于 MTA-STS 是否真的生效, 可以稍后查看 TLS-RPT 报告邮箱收到的相关报告来确认.
### 查看报告
上述配置中的 DMARC 和 TLS-RPT 都会发送报告到指定邮箱. 可以定期查看这些报告以了解邮件传输的安全状况和潜在问题, 推荐部署 [Parsedmarc](https://github.com/domainaware/parsedmarc) 或类似工具进行自动化处理.
### 邮件传输链路
> 一些术语简写:
>
> - `MTA`: Mail Transfer Agent, 邮件传输代理, 负责在邮件服务器之间传输邮件. 例如 Postfix.
> - `MDA`: Mail Delivery Agent, 邮件投递代理, 负责将邮件存储到用户邮箱中. 例如 Dovecot.
> - `MSA`: Mail Submission Agent, 邮件提交代理, 负责接收来自邮件客户端的邮件并将其传递给 MTA. 例如 Postfix.
> - `MUA`: Mail User Agent, 邮件用户代理, 即邮件客户端. 例如 Thunderbird.
>
> 以及位置:
>
> - `Local`: 自建邮件服务器.
> - `Source`: 外部邮件服务器, 发送方.
> - `Destination`: 外部邮件服务器, 接收方.
> - `Relay`: SMTP 中继服务.
以本文配置为例:
- 收信
1. 外部投递 (Source MTA to Local MTA):
- 连接方: 外部邮件服务器.
- 被连接方: 自建邮件服务器公网 IP.
- 目标端口: 25.
- 说明: 标准的 SMTP 传输. 这也是为什么需要开放 25 端口入站.
2. 本地分发 (Local MTA to Local MDA):
- 连接方: 自建邮件服务器.
- 被连接方: 自建邮件服务器本地存储.
- 端口: 本地通信, 无需端口.
- 说明: Postfix (MTA) 接收邮件后,转交给 Dovecot (MDA) 将邮件存入磁盘.
3. 客户端拉取 (MUA to Local MDA):
- 连接方: 邮件客户端 (例如 Thunderbird).
- 被连接方: 自建邮件服务器公网 IP.
- 目标端口: 993 (IMAPS).
- 说明: 使用 IMAPS 拉取邮件.
- 发信
1. 客户端提交 (MUA to Local MSA):
- 连接方: 邮件客户端 (例如 Thunderbird).
- 被连接方: 自建邮件服务器公网 IP.
- 目标端口: 587 (STARTTLS) 或 465 (SSL/TLS).
- 说明: 把邮件上传到服务器队列中.
2. 中继转发 (Local MTA to Relay MTA):
- 连接方: 自建邮件服务器.
- 被连接方: SMTP 中继服务.
- 目标端口: 587 (STARTTLS).
- 说明: 自建邮件服务器根据 `DEFAULT_RELAY_HOST` 配置, 验证账号密码后将邮件转交给中继商.
3. 最终投递 (Relay MTA to Destination MTA):
- 连接方: SMTP 中继服务.
- 被连接方: 外部邮件服务器.
- 目标端口: 25.
- 说明: 这一步由中继商完成. 收件人会看到类似"由 xxx@send.domain.tld 代发" 的信息.
--- ---
> What, Why, How. 以上是 What 和 How, 接下来是... > What, Why, How. 以上是 What 和 How, 接下来是...
## 为什么要做自建邮局? ## 为什么要做自建邮局?
排除利益驱动, 我能想到的最合适的口就是"隐私". 可是如果登陆 Resend 的后台看一眼, 就会发现我写的邮件被一份份明晃晃地不加掩饰地放在那里, 所有的内容都以明文的方式被看得一清二楚. 此时和使用公共邮箱服务唯一的区别似乎也就只剩"有一个很酷的后缀"这一点了. 即便真的解决了 25 端口问题 (是的, 写完上述内容的几天后我确实做到了) 从而得以摆脱 SMTP 中继服务, 在惊讶于明明 Mail-Tester 给出了 10/10 的满分评价但还是被 Gmail 扔进垃圾箱的残酷现实之余, 我也意识到自建邮局这条路仅靠热情是绝对走不通的. 一是预热 IP 需要花费的时间成本乃至金钱成本远超我的想象, 二是无论如何邮件内容也会被收件方的平台以算法评估一遍的事实彻底击碎了对于"隐私"乌托邦最后的妄想. 即使有这么多复杂的安全措施, 补齐了传输过程中的每一个可能的安全漏洞, 但真正和我点对点沟通的从来都只是靠着一条条既定规则维系的平台, 而不是我在写下收件地址时心中所想的一个个鲜活的人. 排除利益驱动, 我能想到的最合适的口就是"隐私". 可是如果登陆 Resend 的后台看一眼, 就会发现我写的邮件被一封封明晃晃地不加掩饰地放在那里, 所有的内容都以明文的方式被看得一清二楚. 此时和使用公共邮箱服务唯一的区别似乎也就只剩"有一个很酷的后缀"这一点了. 即便真的解决了 25 端口问题 (是的, 写完上述内容的几天后我确实做到了) 从而得以摆脱 SMTP 中继服务, 在惊讶于明明 Mail-Tester 给出了 10/10 的满分评价但还是被 Gmail 扔进垃圾箱的残酷现实之余, 我也意识到自建邮局这条路仅靠热情是绝对走不通的. 一是预热 IP 需要花费的时间成本乃至金钱成本远超我的想象, 二是无论如何邮件内容也会被收件方的平台以算法评估一遍的事实彻底击碎了对于"隐私"乌托邦最后的妄想. 即使有这么多复杂的安全措施, 补齐了传输过程中的每一个可能的安全漏洞, 但真正和我点对点沟通的从来都只是靠着一条条既定规则维系的平台, 而不是我在写下收件地址时心中所想的一个个鲜活的人.
那么做这一切的目的到底是什么呢? 或许也只剩"酷"了吧, 除此之外我唯一能想到的好处就是在仅需要邮箱就能注册账号的平台注册无穷无尽的小号. 那么做这一切的目的到底是什么呢? 或许也只剩"酷"了吧, 除此之外我唯一能想到的好处就是在仅需要邮箱就能注册账号的平台注册无穷无尽的小号.
Anyway, 确实是我拥有域名和服务器以来部署过最复杂, 折腾时间最久, 也可能是最无用的服务. 仅论过程还是很有意思的, 至少能让我理解现代电子邮箱系统到底是如何运作的. ~~闲的没事的话~~还是很值得试一试的 :) Anyway, 确实是我拥有域名和服务器以来部署过最复杂, 折腾时间最久, 也可能是最无用的服务. 仅论过程还是很有意思的, 至少能让我理解现代电子邮箱系统到底是如何运作的. ~~闲的没事的话~~还是很值得试一试的 :)
EOF
+2
View File
@@ -1,3 +1,5 @@
de 布局太全能了
<img src="https://upload.wikimedia.org/wikipedia/commons/3/3e/KB_Germany_Linux.svg" alt="Deutsche Tastaturbelegung unter Linux"/> <img src="https://upload.wikimedia.org/wikipedia/commons/3/3e/KB_Germany_Linux.svg" alt="Deutsche Tastaturbelegung unter Linux"/>
``` ```
+3 -3
View File
@@ -6,11 +6,11 @@
> >
> sddm: `cachyos-v3/sddm 0.21.0-8` > sddm: `cachyos-v3/sddm 0.21.0-8`
SDDM shows a blank screen (only with mouse cursor and tty cursor) after booting into graphical target, but starts normally after restarting the SDDM service. SDDM shows a blank screen (possibly only with mouse cursor and tty cursor) after booting into graphical target, but starts normally after restarting the SDDM service.
## Why ## Why
SDDM starts before the NVIDIA driver is fully initialized, causing the greeter session to fail to display properly. SDDM started before the NVIDIA driver is fully initialized, causing the greeter session to fail to display anything.
<details> <details>
<summary>evidence</summary> <summary>evidence</summary>
@@ -114,7 +114,7 @@ sddm[1150]: Greeter session started successfully
## How ## How
The key is to avoid timing race between NVIDIA initialization and SDDM start. There are multiple ways to achieve this, two for example: The key is to avoid timing race between NVIDIA initialization and SDDM startup. There are multiple ways to achieve this, here are two:
### Early KMS: ### Early KMS:
+13 -1
View File
@@ -206,8 +206,20 @@ mail_success
- `--fga 0`: Disable "film grain analysis" (default disabled). fga in current version of VVenC (1.13.1) is kinda buggy and may lead to crashes in CQP mode. Enable with caution. - `--fga 0`: Disable "film grain analysis" (default disabled). fga in current version of VVenC (1.13.1) is kinda buggy and may lead to crashes in CQP mode. Enable with caution.
- `--maxrate` or `-m` can be used to set a maximum bitrate. However, `--qpa 1` is required for this to take effect. With these two parameters enabled, this certain pattern is theoretically called **CQF** (Constant Quality Factor) and is noticeably different from CQP. - `--maxrate` or `-m` can be used to set a maximum bitrate. However, `--qpa 1` is required for this to take effect. With these two parameters enabled, this certain pattern of rc theoretically becomes **CQF** (Constant Quality Factor) and behaves noticeably differently comparing to CQP.
## Extra notes
- Remux 266 bare stream into MKV:
```bash
ffmpeg -i input.266 -c:v copy -bsf:v setts=ts='N*(1001/24000)/TB' output.mkv
```
The `bsf:v setts` part is necessary to set correct timestamps, replace `1001/24000` with the reciprocal of the actual frame rate.
## References ## References
- [Usage - fraunhoferhhi/vvenc Wiki](https://github.com/fraunhoferhhi/vvenc/wiki/Usage) - [Usage - fraunhoferhhi/vvenc Wiki](https://github.com/fraunhoferhhi/vvenc/wiki/Usage)
- [setts - FFmpeg Bitstream Filters Documentation](https://ffmpeg.org/ffmpeg-bitstream-filters.html#setts)