#!/usr/bin/env bash # # install_postfix_sendonly.sh v1.0 # Postfix + OpenDKIM + SPF + DMARC(Send-Only 模式) # -------------------------------------------------------- # ✅ 自动部署轻量级 Postfix 发信服务(仅 587 STARTTLS) # ✅ 集成 DKIM 签名、SPF/DMARC/rDNS/HELO 校验模板 # ✅ 兼容阿里云 / Cloudflare DNS 输出格式 # ✅ 适配 Ubuntu / Debian / RHEL 系列系统 # -------------------------------------------------------- # Author: Pan Haitao @ svc.plus # set -euo pipefail DOMAIN="svc.plus" HOSTNAME="smtp.${DOMAIN}" SERVER_IP="52.196.108.28" EMAIL="no-reply@${DOMAIN}" CERT="/etc/ssl/${DOMAIN}.pem" KEY="/etc/ssl/${DOMAIN}.key" DKIM_SELECTOR="mail" DKIM_KEY_DIR="/etc/opendkim/keys/${DOMAIN}" TMP_PASS="$(openssl rand -base64 12)" ACTION="${1:-help}" log(){ echo -e "\033[1;36m$*\033[0m"; } die(){ echo "❌ $*"; exit 1; } check_root(){ [ "$EUID" -eq 0 ] || die "请用 root 运行"; } # ------------------ 应用端配置 ------------------ show_app_config(){ cat <" tls: mode: "auto" insecureSkipVerify: false auth: "login" ---------------------------------------------------------- EOF echo "首发密码(仅本次显示):${TMP_PASS}" } check_send_email(){ local SMTP_HOST="${HOSTNAME}" local SMTP_PORT=587 local SMTP_USER="${EMAIL}" local SMTP_PASS="${TMP_PASS}" local TEST_TO="${1:-${EMAIL}}" local SUBJECT="📨 SMTP Deliverability Test — $(date '+%Y-%m-%d %H:%M:%S')" local BODY="✅ Automated deliverability test from ${SMTP_HOST} Environment: - HELO: $(hostname -f) - Source IP: $(curl -s ifconfig.me 2>/dev/null || echo 'unknown') - TLS: STARTTLS on ${SMTP_PORT} - Auth: LOGIN (${SMTP_USER}) If you received this message intact, DKIM/DMARC/SPF validation succeeded." echo "🔍 Testing outbound mail via ${SMTP_HOST}:${SMTP_PORT}" echo "-------------------------------------------------------------" swaks --server "${SMTP_HOST}:${SMTP_PORT}" \ --tls --protocol ESMTP \ --auth LOGIN \ --auth-user "${SMTP_USER}" \ --auth-password "${SMTP_PASS}" \ --from "${SMTP_USER}" \ --to "${TEST_TO}" \ --header "From: XControl Mail System <${SMTP_USER}>" \ --header "Subject: ${SUBJECT}" \ --body "${BODY}" \ --timeout 15 --quit-after "." echo "-------------------------------------------------------------" } # ------------------ 依赖 ------------------ ensure_packages(){ log "📦 安装 Postfix + OpenDKIM..." export DEBIAN_FRONTEND=noninteractive apt update -qq apt install -y postfix opendkim opendkim-tools mailutils swaks dnsutils openssl curl } # ------------------ SSL ------------------ verify_cert(){ if [[ -f "$CERT" && -f "$KEY" ]]; then log "🔐 使用自有 SSL 证书:$CERT" openssl x509 -noout -subject -dates -in "$CERT" || true else log "⚠️ 未检测到 ${CERT}/${KEY},生成自签证书..." mkdir -p /etc/ssl openssl req -x509 -nodes -newkey rsa:2048 -days 365 \ -subj "/CN=${HOSTNAME}" -keyout "$KEY" -out "$CERT" fi } # ------------------ DKIM ------------------ deploy_dkim(){ log "🔏 配置 OpenDKIM..." mkdir -p "${DKIM_KEY_DIR}" cd "${DKIM_KEY_DIR}" if [ ! -f "${DKIM_SELECTOR}.private" ]; then opendkim-genkey -s "${DKIM_SELECTOR}" -d "${DOMAIN}" chown opendkim:opendkim "${DKIM_SELECTOR}.private" "${DKIM_SELECTOR}.txt" chmod 600 "${DKIM_SELECTOR}.private" fi cat >/etc/opendkim.conf </etc/opendkim/key.table </etc/opendkim/signing.table </etc/opendkim/trusted.hosts </dev/null 2>&1 || die "Postfix 未安装" # 主配置(禁用入站、仅发信) postconf -e "myhostname = ${HOSTNAME}" postconf -e "myorigin = ${DOMAIN}" postconf -e "mydestination = " postconf -e "relayhost = " postconf -e "inet_interfaces = all" postconf -e "inet_protocols = all" postconf -e "biff = no" postconf -e "append_dot_mydomain = no" postconf -e "readme_directory = no" postconf -e "smtpd_banner = ${HOSTNAME} ESMTP" postconf -e "compatibility_level = 2" postconf -e "mydomain = ${DOMAIN}" postconf -e "smtp_helo_name = ${HOSTNAME}" postconf -e "alias_maps = hash:/etc/aliases" postconf -e "alias_database = hash:/etc/aliases" postconf -e "mynetworks = 127.0.0.0/8 [::1]/128" postconf -e "relay_domains = ${DOMAIN}" # TLS & DKIM postconf -e "smtpd_tls_cert_file = ${CERT}" postconf -e "smtpd_tls_key_file = ${KEY}" postconf -e "smtpd_tls_security_level = may" postconf -e "smtp_tls_security_level = may" postconf -e "smtp_use_tls = yes" postconf -e "smtp_tls_note_starttls_offer = yes" postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" postconf -e "smtpd_tls_auth_only = yes" postconf -e "milter_default_action = accept" postconf -e "milter_protocol = 6" postconf -e "smtpd_milters = inet:localhost:8891" postconf -e "non_smtpd_milters = inet:localhost:8891" # 禁用 25 端口入站,仅启用 587 cat >/etc/postfix/master.cf <