mailcow dttb: спам-фикс, SSL, апдейт 2026-05c, BIMI+подпись, Roundcube, сбор почты
- фикс входящего спама: No-SNAT на OpenWrt (видел все письма как 10.0.0.1) - SSL mail-портов: cert из NPM + cron-синхрон на Proxmox - апдейт mailcow 2026-01 -> 2026-05c; урок: forward-zone unbound обязателен (RKN режет рекурсию) - логотип UI, BIMI-SVG (Tiny PS) + хостинг, HTML-подпись - Roundcube на /rc (bind-mount, public_html) - внешний сбор почты Яндексом (IMAP/POP3) - snippets: sync-mailcow-cert.sh, dttb-mail-branding/ Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
8
snippets/dttb-mail-branding/dttb-bimi.svg
Normal file
8
snippets/dttb-mail-branding/dttb-bimi.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
||||
<title>dttb</title>
|
||||
<rect width="1024" height="1024" fill="#2A6FDB"/>
|
||||
<g transform="translate(232 222) scale(4.827586)" fill="none" stroke="#ffffff" stroke-width="7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="6" y="20" width="104" height="76" rx="14"/>
|
||||
<path d="M10 28 L58 64 L106 28"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 414 B |
BIN
snippets/dttb-mail-branding/dttb-sig-logo.png
Normal file
BIN
snippets/dttb-mail-branding/dttb-sig-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
13
snippets/dttb-mail-branding/signature.html
Normal file
13
snippets/dttb-mail-branding/signature.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<table style="border-collapse:collapse;font-family:Arial,Helvetica,sans-serif;color:#161616;font-size:13px">
|
||||
<tr>
|
||||
<td style="padding-right:14px;vertical-align:middle">
|
||||
<img src="https://mail.dttb.ru/bimi/dttb-logo.png" width="56" height="56" alt="dttb"
|
||||
style="display:block;border-radius:12px;border:0">
|
||||
</td>
|
||||
<td style="vertical-align:middle;border-left:3px solid #2A6FDB;padding-left:14px">
|
||||
<div style="font-weight:700;font-size:15px;line-height:1.2">Олег Батлаев</div>
|
||||
<div style="color:#555;line-height:1.4">dttb.ru</div>
|
||||
<div style="line-height:1.4"><a href="mailto:support@dttb.ru" style="color:#2A6FDB;text-decoration:none">support@dttb.ru</a></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
50
snippets/sync-mailcow-cert.sh
Normal file
50
snippets/sync-mailcow-cert.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
# sync-mailcow-cert.sh
|
||||
# Копирует LE-сертификат mail.dttb.ru из NPM (LXC 103) в mailcow (VM 107)
|
||||
# и перезагружает почтовые сервисы ТОЛЬКО при изменении сертификата.
|
||||
# Причина: mailcow с SKIP_LETS_ENCRYPT=y не продлевает cert сам; cert владеет NPM.
|
||||
# История: cert на mail-портах протух 2026-06-02, чинили вручную 2026-06-27.
|
||||
set -euo pipefail
|
||||
|
||||
NPM_CTID=103
|
||||
NPM_DIR="/data/compose/2/letsencrypt/live/npm-106"
|
||||
MC_HOST="root@10.0.0.107"
|
||||
MC_KEY="/root/.ssh/mailcow_sync"
|
||||
MC_SSL="/opt/mailcow-dockerized/data/assets/ssl"
|
||||
SSHMC="ssh -i $MC_KEY -o StrictHostKeyChecking=no -o ConnectTimeout=10 $MC_HOST"
|
||||
|
||||
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
|
||||
|
||||
pct exec "$NPM_CTID" -- cat "$NPM_DIR/fullchain.pem" > "$TMP/cert.pem"
|
||||
pct exec "$NPM_CTID" -- cat "$NPM_DIR/privkey.pem" > "$TMP/key.pem"
|
||||
|
||||
# sanity-проверки
|
||||
openssl x509 -in "$TMP/cert.pem" -noout >/dev/null 2>&1 || { echo "$(date '+%F %T') ERR: битый cert из NPM"; exit 1; }
|
||||
[ -s "$TMP/key.pem" ] || { echo "$(date '+%F %T') ERR: пустой key из NPM"; exit 1; }
|
||||
CPUB=$(openssl x509 -in "$TMP/cert.pem" -noout -pubkey | openssl md5)
|
||||
KPUB=$(openssl pkey -in "$TMP/key.pem" -pubout 2>/dev/null | openssl md5)
|
||||
[ "$CPUB" = "$KPUB" ] || { echo "$(date '+%F %T') ERR: cert и key не пара"; exit 1; }
|
||||
|
||||
NEW=$(openssl x509 -in "$TMP/cert.pem" -noout -fingerprint -sha256)
|
||||
CUR=$($SSHMC "openssl x509 -in $MC_SSL/cert.pem -noout -fingerprint -sha256" 2>/dev/null || echo none)
|
||||
if [ "$NEW" = "$CUR" ]; then
|
||||
echo "$(date '+%F %T') cert не изменился — пропуск"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$(date '+%F %T') обнаружен новый cert — деплой"
|
||||
scp -i "$MC_KEY" -o StrictHostKeyChecking=no "$TMP/cert.pem" "$TMP/key.pem" "$MC_HOST:/tmp/"
|
||||
$SSHMC "
|
||||
set -e
|
||||
cd /opt/mailcow-dockerized
|
||||
TS=\$(date +%Y%m%d-%H%M%S)
|
||||
cp $MC_SSL/cert.pem $MC_SSL/cert.pem.bak-\$TS
|
||||
cp $MC_SSL/key.pem $MC_SSL/key.pem.bak-\$TS
|
||||
mv /tmp/cert.pem $MC_SSL/cert.pem
|
||||
mv /tmp/key.pem $MC_SSL/key.pem
|
||||
chmod 644 $MC_SSL/cert.pem; chmod 600 $MC_SSL/key.pem
|
||||
docker compose exec -T postfix-mailcow postfix reload >/dev/null 2>&1 || docker compose restart postfix-mailcow
|
||||
docker compose exec -T dovecot-mailcow dovecot reload >/dev/null 2>&1 || docker compose restart dovecot-mailcow
|
||||
docker compose exec -T nginx-mailcow nginx -s reload >/dev/null 2>&1 || true
|
||||
"
|
||||
echo "$(date '+%F %T') задеплоен: $NEW"
|
||||
Reference in New Issue
Block a user