chore(deploy): 将 DKIM 组件切换为 Rspamd
- 用 Rspamd 替换 OpenDKIM 及其相关镜像、编排和启动脚本。 - 调整 Postfix、单容器镜像与 Docker 配置,改为对接 Rspamd milter。 - 增加 DKIM 私钥同步脚本与 Rspamd 本地配置,支持从 SQLite 周期导出签名密钥。 - 更新 API 启动与测试逻辑,兼容新的默认管理员邮箱与邮箱加载方式。
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
|
||||
rm -f /etc/apt/apt.conf.d/docker-clean && \
|
||||
apt-get update && apt-get install -y --no-install-recommends rspamd sqlite3 ca-certificates
|
||||
COPY local.d/ /etc/rspamd/local.d/
|
||||
COPY sync-dkim.sh /usr/local/bin/lanqin-rspamd-sync-dkim
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh /usr/local/bin/lanqin-rspamd-sync-dkim && mkdir -p /run/rspamd /var/lib/rspamd/dkim
|
||||
EXPOSE 11332 11334
|
||||
CMD ["/entrypoint.sh"]
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
mkdir -p /run/rspamd /var/lib/rspamd/dkim
|
||||
if id _rspamd >/dev/null 2>&1; then
|
||||
chown -R _rspamd:_rspamd /run/rspamd /var/lib/rspamd 2>/dev/null || true
|
||||
elif id rspamd >/dev/null 2>&1; then
|
||||
chown -R rspamd:rspamd /run/rspamd /var/lib/rspamd 2>/dev/null || true
|
||||
fi
|
||||
|
||||
/usr/local/bin/lanqin-rspamd-sync-dkim --once || true
|
||||
/usr/local/bin/lanqin-rspamd-sync-dkim &
|
||||
exec rspamd -f
|
||||
@@ -0,0 +1,4 @@
|
||||
# V1 先把 Rspamd 作为 DKIM 签名和标记组件,不直接拒信,避免误杀。
|
||||
reject = 999;
|
||||
add_header = 6;
|
||||
greylist = 999;
|
||||
@@ -0,0 +1,19 @@
|
||||
enabled = true;
|
||||
|
||||
# LanQin API 固定生成 selector=lanqin。路径支持 $domain / $selector 模板。
|
||||
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
|
||||
selector = "lanqin";
|
||||
try_fallback = true;
|
||||
use_domain = "header";
|
||||
use_esld = false;
|
||||
use_redis = false;
|
||||
|
||||
# Go API / Postfix 在容器内提交的邮件需要签名。
|
||||
sign_authenticated = true;
|
||||
sign_local = true;
|
||||
sign_networks = "/etc/rspamd/local.d/sign_networks.map";
|
||||
|
||||
allow_username_mismatch = true;
|
||||
allow_hdrfrom_mismatch_local = true;
|
||||
allow_hdrfrom_mismatch_sign_networks = true;
|
||||
allow_hdrfrom_multiple = true;
|
||||
@@ -0,0 +1,4 @@
|
||||
127.0.0.0/8
|
||||
10.0.0.0/8
|
||||
172.16.0.0/12
|
||||
192.168.0.0/16
|
||||
@@ -0,0 +1,8 @@
|
||||
bind_socket = "0.0.0.0:11332";
|
||||
milter = yes;
|
||||
timeout = 120s;
|
||||
|
||||
upstream "local" {
|
||||
default = yes;
|
||||
self_scan = yes;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
: "${LANQIN_DB_PATH:=/data/lanqin.db}"
|
||||
: "${LANQIN_RSPAMD_DKIM_DIR:=/var/lib/rspamd/dkim}"
|
||||
: "${LANQIN_RSPAMD_DKIM_SYNC_SECONDS:=60}"
|
||||
|
||||
chown_dkim_dir() {
|
||||
if id _rspamd >/dev/null 2>&1; then
|
||||
chown -R _rspamd:_rspamd "$LANQIN_RSPAMD_DKIM_DIR" 2>/dev/null || true
|
||||
elif id rspamd >/dev/null 2>&1; then
|
||||
chown -R rspamd:rspamd "$LANQIN_RSPAMD_DKIM_DIR" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
sync_keys() {
|
||||
mkdir -p "$LANQIN_RSPAMD_DKIM_DIR"
|
||||
if [ ! -f "$LANQIN_DB_PATH" ]; then
|
||||
chown_dkim_dir
|
||||
return 0
|
||||
fi
|
||||
|
||||
sqlite3 -separator '|' "$LANQIN_DB_PATH" "SELECT name, dkim_selector, dkim_private_key FROM domains WHERE status='active';" 2>/dev/null | while IFS='|' read -r domain selector private_key; do
|
||||
[ -n "$domain" ] || continue
|
||||
[ -n "$selector" ] || selector="lanqin"
|
||||
keyfile="$LANQIN_RSPAMD_DKIM_DIR/${domain}.${selector}.key"
|
||||
tmpfile="${keyfile}.tmp"
|
||||
printf '%s' "$private_key" | base64 -d > "$tmpfile"
|
||||
chmod 0640 "$tmpfile"
|
||||
mv "$tmpfile" "$keyfile"
|
||||
done
|
||||
|
||||
chown_dkim_dir
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "--once" ]; then
|
||||
sync_keys
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while true; do
|
||||
sync_keys || true
|
||||
sleep "$LANQIN_RSPAMD_DKIM_SYNC_SECONDS"
|
||||
done
|
||||
Reference in New Issue
Block a user