【特別編】コピペで完了!AlmaLinux 9用 メールサーバー全自動構築スクリプト – Postfix+Dovecot+セキュリティ一括設定

「構築」は一瞬で終わらせ、「運用」に時間を使え

こんにちは!「リナックス先生」です。
全5回の連載、本当にお疲れ様でした。手動での構築を通じて、各設定の意味は十分に理解できたはずです。

コウ君

先生、正直に言います。
勉強にはなりましたけど、もう一回ゼロから手打ちで設定しろって言われたら、心が折れそうです…。
設定ファイル、書き換える場所が多すぎませんか?

リナックス先生

それが正常な感覚よ。
インフラエンジニアの美徳は「怠惰」であること。
一度理解した手順はスクリプト化して、次はコーヒーを飲んでいる間に終わらせるのがプロの流儀よ。
今回は、AlmaLinux 9 専用の「全自動構築スクリプト」をプレゼントするわ!

1. スクリプト実行前の重要確認事項

このスクリプトは便利ですが、魔法ではありません。
以下の環境条件を満たしていない場合、インストール中にエラーで停止したり、構築できても起動しない場合があります。必ず確認してください。

⚠️ 動作環境と注意点

  • OS: AlmaLinux 9 (クリーンインストール状態推奨)
  • メモリ: 最低 2GB 以上必須
    ※ClamAV(アンチウイルス)は非常にメモリを消費します。1GB以下のVPSではメモリ不足で起動に失敗します。スワップ領域を作成するか、プランを上げてください。
  • ポート開放: 事前にVPSの管理画面等で 80, 443, 25, 587, 993, 465 番ポートを開放してください。
  • DNS設定: 構築するドメインのAレコードが、サーバーのIPを向いていること(SSL取得に失敗します)。

2. 自動構築スクリプト (setup_mail.sh)

以下の手順でスクリプトを作成・実行してください。

スクリプトの作成

サーバーにrootでログインし、ファイルを作成します。

vi setup_mail.sh

以下のコードをコピー&ペーストしてください。
※冒頭の「設定エリア」は、必ずご自身の情報に書き換えてください。

#!/bin/bash

# ========================================================
#  AlmaLinux 9 メールサーバー自動構築スクリプト
#  (Postfix + Dovecot + OpenDKIM + SpamAssassin + ClamAV + Fail2Ban)
# ========================================================

# --- [設定エリア] 必ず書き換えてください ---
DOMAIN="example.com"             # あなたのドメイン名
HOSTNAME="mail.example.com"      # メールサーバーのホスト名(FQDN)
MAIL_USER="kou-kun"              # 作成するメールユーザー名
MAIL_PASS="StrongPass123"        # メールユーザーのパスワード
EMAIL_ADMIN="admin@example.com"  # SSL証明書登録用メールアドレス
# ---------------------------------------------

# エラーハンドリング
set -e

# カラー出力定義
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

echo -e "${GREEN}>>> 1. 基本ツールとリポジトリのセットアップ...${NC}"
dnf -y update
# CRBリポジトリ有効化のためにdnf-plugins-coreが必要
dnf -y install dnf-plugins-core epel-release
dnf config-manager --set-enabled crb
dnf -y install vim wget curl tar rsyslog policycoreutils-python-utils

echo -e "${GREEN}>>> 2. メール関連パッケージのインストール...${NC}"
dnf -y install postfix dovecot dovecot-pigeonhole \
    opendkim opendkim-tools \
    spamassassin clamav clamav-update amavisd-new \
    fail2ban fail2ban-systemd certbot cyrus-sasl cyrus-sasl-plain

# rsyslogを起動してログ出力を確保
systemctl enable --now rsyslog

echo -e "${GREEN}>>> 3. ホスト名とFirewall設定...${NC}"
hostnamectl set-hostname $HOSTNAME
firewall-cmd --add-service={http,https,smtp,smtps,smtp-submission,imap,imaps,pop3s} --permanent
firewall-cmd --reload

echo -e "${GREEN}>>> 4. SSL証明書の取得 (Let's Encrypt)...${NC}"
if [ ! -d "/etc/letsencrypt/live/$HOSTNAME" ]; then
    # 80番ポートが他で使われていないか簡易チェック
    if lsof -i :80 > /dev/null; then
        echo -e "${RED}Error: Port 80 is in use. Stop Web Server first.${NC}"
        exit 1
    fi
    certbot certonly --standalone -d $HOSTNAME --email $EMAIL_ADMIN --agree-tos -n
else
    echo "SSL Certificate already exists. Skipping."
fi

CERT_FULLCHAIN="/etc/letsencrypt/live/$HOSTNAME/fullchain.pem"
CERT_PRIVKEY="/etc/letsencrypt/live/$HOSTNAME/privkey.pem"

echo -e "${GREEN}>>> 5. Postfix設定 (main.cf)...${NC}"
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak

# postconfを使って安全に設定値を変更
postconf -e "myhostname = $HOSTNAME"
postconf -e "mydomain = $DOMAIN"
postconf -e "myorigin = \$mydomain"
postconf -e "inet_interfaces = all"
postconf -e "inet_protocols = ipv4"
postconf -e "mydestination = \$myhostname, localhost.\$mydomain, localhost, \$mydomain"
postconf -e "home_mailbox = Maildir/"
# SMTP-Auth
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "smtpd_sasl_type = cyrus"
postconf -e "smtpd_sasl_path = smtpd"
postconf -e "smtpd_sasl_security_options = noanonymous"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
# TLS
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtpd_tls_cert_file = $CERT_FULLCHAIN"
postconf -e "smtpd_tls_key_file = $CERT_PRIVKEY"
postconf -e "smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache"
# OpenDKIM & Amavisd 連携
postconf -e "smtpd_milters = unix:/run/opendkim/opendkim.sock"
postconf -e "non_smtpd_milters = \$smtpd_milters"
postconf -e "milter_default_action = accept"
postconf -e "content_filter = smtp-amavis:[127.0.0.1]:10024"

echo -e "${GREEN}>>> 6. Postfix設定 (master.cf)...${NC}"
# Submissionポート開放 (sedで置換)
sed -i 's/^#submission/submission/' /etc/postfix/master.cf
sed -i 's/^#  -o smtpd_tls_security_level=encrypt/  -o smtpd_tls_security_level=encrypt/' /etc/postfix/master.cf
sed -i 's/^#  -o smtpd_sasl_auth_enable=yes/  -o smtpd_sasl_auth_enable=yes/' /etc/postfix/master.cf

# Amavisd連携設定の追記 (重複防止のためgrepチェック)
if ! grep -q "smtp-amavis" /etc/postfix/master.cf; then
cat <> /etc/postfix/master.cf

# --- Amavisd Integration ---
smtp-amavis unix - - n - 2 smtp
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20

127.0.0.1:10025 inet n - n - - smtpd
    -o content_filter=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o mynetworks=127.0.0.0/8
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
EOF
fi

echo -e "${GREEN}>>> 7. Dovecot設定...${NC}"
# local.confを作成して設定を上書き(sedより安全かつ確実)
cat < /etc/dovecot/local.conf
protocols = imap pop3
listen = *, ::
mail_location = maildir:~/Maildir
disable_plaintext_auth = yes
auth_mechanisms = plain login
ssl = required
ssl_cert = <$CERT_FULLCHAIN
ssl_key = <$CERT_PRIVKEY
EOF

echo -e "${GREEN}>>> 8. OpenDKIM設定...${NC}"
mkdir -p /etc/opendkim/keys/$DOMAIN
# 2048bitで鍵生成
opendkim-genkey -s default -d $DOMAIN -D /etc/opendkim/keys/$DOMAIN --bits=2048
chown -R opendkim:opendkim /etc/opendkim/keys
chmod 640 /etc/opendkim/keys/$DOMAIN/default.private

# opendkim.conf
cat < /etc/opendkim.conf
Mode    sv
Socket  local:/run/opendkim/opendkim.sock
PidFile /run/opendkim/opendkim.pid
UserID  opendkim:opendkim
KeyTable      refile:/etc/opendkim/KeyTable
SigningTable  refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
EOF

# マッピングファイル作成
echo "default._domainkey.$DOMAIN $DOMAIN:default:/etc/opendkim/keys/$DOMAIN/default.private" > /etc/opendkim/KeyTable
echo "*@$DOMAIN default._domainkey.$DOMAIN" > /etc/opendkim/SigningTable
echo -e "127.0.0.1\n::1\nlocalhost\n$HOSTNAME\n$DOMAIN" > /etc/opendkim/TrustedHosts

# 権限修正: Postfixがソケットを読めるようにグループ追加
usermod -aG opendkim postfix
# ソケットディレクトリの権限調整
mkdir -p /run/opendkim
chown opendkim:opendkim /run/opendkim
chmod 750 /run/opendkim

echo -e "${GREEN}>>> 9. Amavisd & ClamAV設定...${NC}"
# ClamAV定義ファイル更新 (初回は失敗することがあるので || true)
freshclam || true
# Amavisd設定調整 (ドメイン名)
sed -i "s/\$mydomain = 'example.com';/\$mydomain = '$DOMAIN';/" /etc/amavisd/amavisd.conf
# ウイルス/スパムチェック有効化コメント解除
sed -i "s/^@bypass_virus_checks_maps = (1);/# @bypass_virus_checks_maps = (1);/" /etc/amavisd/amavisd.conf
sed -i "s/^@bypass_spam_checks_maps  = (1);/# @bypass_spam_checks_maps  = (1);/" /etc/amavisd/amavisd.conf

echo -e "${GREEN}>>> 10. Fail2Ban設定...${NC}"
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
cat <> /etc/fail2ban/jail.local

[postfix]
enabled = true
mode    = aggressive
port    = smtp,465,submission
backend = systemd
maxretry = 3
bantime  = 86400

[dovecot]
enabled = true
port    = pop3,pop3s,imap,imaps,submission,465,sieve
backend = systemd
maxretry = 5
bantime  = 86400
EOF

echo -e "${GREEN}>>> 11. ユーザー作成とサービス起動...${NC}"
if ! id "$MAIL_USER" &>/dev/null; then
    useradd -s /sbin/nologin $MAIL_USER
    echo "$MAIL_USER:$MAIL_PASS" | chpasswd
    echo "User $MAIL_USER created."
fi

# サービス有効化と起動
systemctl enable --now saslauthd
systemctl enable --now clamd@amavisd
systemctl enable --now amavisd
systemctl enable --now opendkim
systemctl enable --now dovecot
systemctl enable --now postfix
systemctl enable --now fail2ban

echo -e "${GREEN}=====================================================${NC}"
echo -e "${GREEN}   構築完了しました!${NC}"
echo -e "${GREEN}=====================================================${NC}"
echo "【重要】以下のDNSレコード(TXT)を追加してください"
echo "-----------------------------------------------------"
echo "--- SPF Record ---"
echo "Host: @"
echo "Value: v=spf1 ip4:$(curl -s ifconfig.me) -all"
echo ""
echo "--- DKIM Record ---"
cat /etc/opendkim/keys/$DOMAIN/default.txt
echo "-----------------------------------------------------"
echo "※ DNS反映後、メール送受信テストを行ってください。"

3. スクリプトの実行方法

Step 1: 権限付与と実行

作成したファイルに実行権限を与えて実行します。

chmod +x setup_mail.sh
./setup_mail.sh

実行すると、自動的にパッケージのインストールや設定が進みます。
(ClamAVの定義ファイル更新などで、5分〜10分程度かかる場合があります)

Step 2: DNSレコードの登録(必須)

スクリプト完了時に表示される「SPF Record」「DKIM Record」を、必ずDNSに登録してください。
これを忘れると、メールは正常に機能しても、相手側にスパムとして弾かれます。

4. よくあるエラーと対処法

Q. ClamAV / Amavisd が起動しない

A. メモリ不足です。
ClamAVはウイルス定義ファイルを読み込むために大量のメモリ(1GB以上)を消費します。
systemctl status clamd@amavisdOOM Kill 等のログが出ていないか確認してください。
メモリの増設か、スワップファイルの作成(dd if=/dev/zero of=/swapfile...)が必要です。

Q. SSL証明書の取得に失敗する

A. DNSかファイアウォールの問題です。
スクリプト実行前に、DNS(Aレコード)がサーバーのIPを向いているか、そして80番ポートが開放されているかを確認してください。


まとめ:自動化で「確実性」を手に入れる

手動でやれば1時間以上かかる作業が、このスクリプトなら数分で完了します。
また、手入力によるスペルミスも防げるため、結果としてサーバーの安定性が向上します。

コウ君

すごすぎます先生!
DNSの設定だけして実行したら、トイレに行ってる間に終わってました!
最後にDKIMの鍵まで表示してくれるなんて親切設計ですね。

リナックス先生

便利でしょう?
でも、このスクリプトが何をしているか理解できているのは、君がこれまで手動構築の勉強をしたからよ。
中身がブラックボックスのまま使うのと、理解して使うのとでは、トラブルが起きた時の対応力が違うわ。
このスクリプトをベースに、自分好みに改造してみるのも勉強になるわよ!

▼スクリプトテストに最適なVPS

「失敗してもすぐやり直せる」のがスクリプトのいいところ。OS再インストールが数秒で終わり、メモリ不足の心配もないハイスペックVPSはこちらです。

【2026年最新】Linuxサーバー構築におすすめのVPS比較3選!現役エンジニアが速度とコスパで厳選
Linuxの勉強、まだ「自分のPC」でやって消耗していませんか?「Linuxを覚えたいけど、環境構築でエラーが出て先に進めない…」「VirtualBoxを入れたらパソコンが重くなった…」これは、Linux学習を始める9割の人がぶつかる壁です...

コメント