#!/usr/bin/env bash # # install_stalwart_mailserver.sh v2.3 # -------------------------------------------------------- # ✅ 安装 Stalwart Mail Server(Rust版,官方 install.sh) # ✅ SMTPS(465) + IMAPS(993),全程 TLS-only # ✅ 支持 S3 / MinIO 存储 # ✅ 支持 JSON 用户认证(默认) # ✅ 自动生成 DKIM + SPF/DMARC DNS 模板 # ✅ Systemd 管理 # ✅ 无 WebUI(由外部 Dashboard 对接) # -------------------------------------------------------- # Author: Pan Haitao @ svc.plus # set -euo pipefail DOMAIN="svc.plus" HOSTNAME="mail.${DOMAIN}" SERVER_IP="$(curl -s https://api.ipify.org || echo 127.0.0.1)" CERT_DIR="/etc/ssl" CERT="${CERT_DIR}/${DOMAIN}.pem" KEY="${CERT_DIR}/${DOMAIN}.key" STALWART_DIR="/etc/stalwart" STALWART_BIN="/usr/local/bin/stalwart-mail" STALWART_CFG="${STALWART_DIR}/stalwart.toml" DKIM_KEY_DIR="${STALWART_DIR}/dkim" DKIM_SELECTOR="mail" SERVICE_USER="stalwart" SERVICE_GROUP="stalwart" ACTION="${1:-help}" # S3 存储参数 S3_ENDPOINT="https://minio.svc.plus:9000" S3_BUCKET="svcplus-mail" S3_ACCESS_KEY="MINIO_ACCESS_KEY" S3_SECRET_KEY="MINIO_SECRET_KEY" ADMIN_EMAIL="admin@${DOMAIN}" log(){ echo -e "\033[1;36m$*\033[0m"; } die(){ echo "❌ $*"; exit 1; } check_root(){ [ "$EUID" -eq 0 ] || die "请以 root 运行"; } # ------------------ 依赖 ------------------ ensure_packages(){ log "📦 安装依赖..." apt update -qq apt install -y curl openssl jq dnsutils opendkim opendkim-tools swaks tar } # ------------------ 安装 Stalwart ------------------ install_stalwart(){ if ! command -v stalwart-mail &>/dev/null; then log "⬇️ 通过官方脚本安装 Stalwart Mail Server..." curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh -o /tmp/install.sh bash /tmp/install.sh else log "✅ 已检测到 Stalwart:$(stalwart-mail --version)" fi } # ------------------ 证书 ------------------ verify_cert(){ mkdir -p "$CERT_DIR" if [[ -f "$CERT" && -f "$KEY" ]]; then log "🔐 使用现有证书" else log "⚠️ 未检测到证书,生成自签..." openssl req -x509 -nodes -newkey rsa:2048 -days 365 \ -subj "/CN=${HOSTNAME}" -keyout "$KEY" -out "$CERT" fi } # ------------------ DKIM ------------------ deploy_dkim(){ log "🔏 生成 DKIM 密钥..." mkdir -p "${DKIM_KEY_DIR}" cd "${DKIM_KEY_DIR}" if [ ! -f "${DKIM_SELECTOR}.private" ]; then opendkim-genkey -s "${DKIM_SELECTOR}" -d "${DOMAIN}" chmod 600 "${DKIM_SELECTOR}.private" fi } # ------------------ 配置文件 ------------------ generate_config(){ log "⚙️ 生成 stalwart.toml..." mkdir -p "${STALWART_DIR}" cat >"${STALWART_CFG}" <"${STALWART_DIR}/users.json" </etc/systemd/system/stalwart.service </dev/null || useradd -r -s /bin/false "${SERVICE_USER}" chown -R "${SERVICE_USER}:${SERVICE_GROUP}" "${STALWART_DIR}" /var/lib/stalwart || true systemctl daemon-reload systemctl enable --now stalwart.service } # ------------------ DNS 模板 ------------------ show_dns_record(){ log "🌐 DNS 模板(SPF / DKIM / DMARC / rDNS)" local DKIM_FILE="${DKIM_KEY_DIR}/${DKIM_SELECTOR}.txt" local DKIM_VAL="<未生成>" [[ -f "$DKIM_FILE" ]] && DKIM_VAL=$(grep -v '^;' "$DKIM_FILE" | tr -d '\n' | sed -E 's/.*p=//;s/"//g') cat < ${HOSTNAME}) HELO (应输出 ${HOSTNAME}) ---------------------------------------------------------- EOF } # ------------------ 应用端配置 ------------------ show_app_config(){ cat <