Mail Server Administration

メールサーバ管理 (Mail Server Administration) 包括ガイド

目次

  1. はじめに
  2. メールの基礎知識
  3. Postfix によるメール送信サーバ構築
  4. Dovecot による受信サーバ構築
  5. メールキュー管理
  6. スパム対策
  7. トラブルシューティング
  8. プロトコル・ポート比較表
  9. ベストプラクティス
  10. 参考文献

1. はじめに

メールサーバはインターネット基盤の中核を担うサービスであり、Linux システム管理者にとって不可欠なスキルである。本ガイドでは、MTA (Mail Transfer Agent) としての Postfix、MDA (Mail Delivery Agent) / IMAP/POP3 サーバとしての Dovecot を中心に、送受信サーバの構築・運用・トラブルシューティングを包括的に解説する。

主要コンポーネントの関係:

送信者 MUA  --->  MTA (Postfix)  --->  インターネット  --->  MTA (Postfix)
                                                                  |
                                                              MDA (Dovecot)
                                                                  |
                                                            受信者 MUA
略語正式名称役割代表例
MUAMail User AgentメールクライアントThunderbird, Outlook, mutt
MTAMail Transfer Agentメール転送Postfix, Sendmail, Exim
MDAMail Delivery Agentメールボックスへの配送Dovecot LDA, Procmail
MSAMail Submission Agentユーザからのメール受付Postfix (port 587)

2. メールの基礎知識

2.1 メール配送の仕組み

[送信者 MUA] --SMTP(587)--> [送信側 MTA] --SMTP(25)--> [受信側 MTA]
                                                            |
                                                     [MDA / LDA]
                                                            |
                                                      [メールボックス]
                                                            |
                                              [受信者 MUA] <--IMAP(993)/POP3(995)--
  1. 送信者が MUA でメールを作成し、MSA (ポート 587) に送信
  2. 送信側 MTA が受信側ドメインの MX レコードを DNS に問い合わせ
  3. 送信側 MTA が受信側 MTA にポート 25 で SMTP 接続しメールを転送
  4. 受信側 MTA が MDA を使ってメールボックスに配送
  5. 受信者が IMAP または POP3 でメールを取得

2.2 プロトコル概要 (SMTP, POP3, IMAP)

SMTP (Simple Mail Transfer Protocol)

$ telnet mail.example.com 25
Trying 192.168.1.10...
Connected to mail.example.com.
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
EHLO client.example.com
250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
MAIL FROM:<user@example.com>
250 2.1.0 Ok
RCPT TO:<dest@example.org>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: Test Mail
From: user@example.com
To: dest@example.org

This is a test message.
.
250 2.0.0 Ok: queued as ABC12345
QUIT
221 2.0.0 Bye

POP3 vs IMAP 比較

項目POP3IMAP
ポート (平文)110143
ポート (SSL/TLS)995993
メール保存場所クライアント側サーバ側
マルチデバイス不向き適している
フォルダ管理非対応対応
オフライン利用容易キャッシュ依存
サーバ負荷低い高い
帯域消費初回大きいヘッダのみ取得可
用途単一端末複数端末・組織利用

2.3 DNS とメール (MX レコード)

MX レコードはドメインのメール受信先を指定する DNS レコードである。

$ dig MX example.com +short
10 mail1.example.com.
20 mail2.example.com.

$ dig TXT example.com +short
"v=spf1 mx ip4:192.168.1.0/24 -all"

MX レコードの優先度: 数値が小さいほど優先度が高い。上記の例では mail1 が優先的に使用され、接続不可の場合に mail2 にフォールバックする。

2.4 メール認証技術 (SPF, DKIM, DMARC)

SPF (Sender Policy Framework)

送信元 IP アドレスの正当性を検証する仕組み。

;; DNS TXT レコード
example.com.  IN  TXT  "v=spf1 mx ip4:203.0.113.0/24 include:_spf.google.com -all"
修飾子意味動作
+Pass許可 (デフォルト)
-Fail拒否
~SoftFail受け入れるがマーク
?Neutral判定しない

DKIM (DomainKeys Identified Mail)

送信メールに電子署名を付与し、メールの改ざんを検知する仕組み。

;; DNS TXT レコード
selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."

メールヘッダでの署名例:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
    d=example.com; s=selector1;
    h=from:to:subject:date:message-id;
    bh=ABC123...;
    b=XYZ789...

DMARC (Domain-based Message Authentication, Reporting and Conformance)

SPF と DKIM の結果を基にメールの処理ポリシーを定義する。

;; DNS TXT レコード
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensic@example.com; pct=100; adkim=s; aspf=s"
パラメータ説明
pポリシー: none / quarantine / reject
rua集約レポート送信先
rufフォレンジックレポート送信先
pctポリシー適用率 (%)
adkimDKIM アライメント: s(strict) / r(relaxed)
aspfSPF アライメント: s(strict) / r(relaxed)

認証チェックの全体フロー:

受信メール
    |
    +-- SPF チェック --> Pass/Fail
    |
    +-- DKIM チェック --> Pass/Fail
    |
    +-- DMARC 評価 (SPF + DKIM の結果)
            |
            +-- none: 何もしない
            +-- quarantine: 迷惑メールフォルダへ
            +-- reject: 受信拒否

3. Postfix によるメール送信サーバ構築

3.1 Postfix アーキテクチャ

Postfix はモジュール設計の MTA であり、複数のデーモンが協調動作する。

                    +---------+
  インターネット -->| smtpd   |--+
                    +---------+  |
                                 v
                    +---------+     +---------+     +---------+
  ローカル送信 --> | pickup   |--> | cleanup  |--> | qmgr    |
                    +---------+     +---------+     +---------+
                                                        |
                                        +---------------+---------------+
                                        |               |               |
                                   +---------+    +---------+    +---------+
                                   |  smtp   |    |  local  |    | virtual |
                                   +---------+    +---------+    +---------+
                                        |               |               |
                                   リモート配送    ローカル配送   仮想ユーザ配送
デーモン役割
smtpd受信 SMTP 接続の処理
pickupmaildrop ディレクトリからのメール取得
cleanupヘッダの正規化・重複チェック
qmgrキューマネージャ (配送スケジューリング)
smtpリモートサーバへの配送
localローカルメールボックスへの配送
virtual仮想ドメイン・ユーザへの配送

3.2 main.cf の主要設定

Postfix の中核設定ファイルは /etc/postfix/main.cf である。

# インストール
$ sudo dnf install postfix    # RHEL/Rocky/Alma
$ sudo apt install postfix    # Debian/Ubuntu

/etc/postfix/main.cf:

# ==============================
# 基本設定
# ==============================
# ホスト名とドメイン
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain

# ネットワーク設定
inet_interfaces = all
inet_protocols = ipv4

# 信頼するネットワーク
mynetworks = 127.0.0.0/8, 10.0.0.0/24

# バナー (バージョン情報を隠す)
smtpd_banner = $myhostname ESMTP

# ==============================
# 配送先設定
# ==============================
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

# メールボックス形式
home_mailbox = Maildir/

# メールサイズ制限 (50MB)
message_size_limit = 52428800

# メールボックスサイズ制限 (1GB)
mailbox_size_limit = 1073741824

# ==============================
# SMTP 認証 (SASL)
# ==============================
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname

# ==============================
# TLS 設定
# ==============================
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.example.com.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.example.com.key
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# ==============================
# 制限設定
# ==============================
smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    reject_invalid_hostname,
    reject_non_fqdn_hostname,
    reject_non_fqdn_sender,
    reject_non_fqdn_recipient,
    reject_unknown_sender_domain,
    reject_unknown_recipient_domain,
    reject_rbl_client zen.spamhaus.org,
    permit

smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks,
    reject_non_fqdn_helo_hostname,
    reject_invalid_helo_hostname,
    permit

# ==============================
# パフォーマンス
# ==============================
default_process_limit = 100
smtpd_client_connection_rate_limit = 10
smtpd_client_message_rate_limit = 100
maximal_queue_lifetime = 5d
bounce_queue_lifetime = 5d

/etc/postfix/master.cf (Submission ポート設定):

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd
submission inet  n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_tls_auth_only=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       n       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

設定の確認と反映:

# 設定の構文チェック
$ sudo postfix check
# (エラーがなければ何も出力されない)

# デフォルトと異なる設定値を表示
$ postconf -n
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
...

# 設定の反映 (再起動不要)
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system

# Postfix の起動と自動起動
$ sudo systemctl enable --now postfix

3.3 仮想ドメインと仮想ユーザ

複数のドメインを 1 台のサーバでホスティングする場合に仮想ドメインを使用する。

/etc/postfix/main.cf (追加設定):

# 仮想メールボックスドメイン
virtual_mailbox_domains = hash:/etc/postfix/virtual_domains
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox
virtual_alias_maps = hash:/etc/postfix/virtual_alias
virtual_minimum_uid = 1000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

/etc/postfix/virtual_domains:

example.com    OK
example.org    OK
example.net    OK

/etc/postfix/virtual_mailbox:

user1@example.com       example.com/user1/Maildir/
user2@example.com       example.com/user2/Maildir/
info@example.org        example.org/info/Maildir/
admin@example.net       example.net/admin/Maildir/

/etc/postfix/virtual_alias:

postmaster@example.com  admin@example.com
abuse@example.com       admin@example.com
sales@example.org       user1@example.com, user2@example.com
# ハッシュ DB の作成
$ sudo postmap /etc/postfix/virtual_domains
$ sudo postmap /etc/postfix/virtual_mailbox
$ sudo postmap /etc/postfix/virtual_alias

# 仮想メールユーザの作成
$ sudo groupadd -g 5000 vmail
$ sudo useradd -g vmail -u 5000 -d /var/mail/vhosts -s /sbin/nologin vmail
$ sudo mkdir -p /var/mail/vhosts/{example.com,example.org,example.net}
$ sudo chown -R vmail:vmail /var/mail/vhosts

$ sudo postfix reload

3.4 トランスポートマップ

特定のドメイン宛メールの配送経路をカスタマイズする。

/etc/postfix/main.cf:

transport_maps = hash:/etc/postfix/transport

/etc/postfix/transport:

# 内部ドメインは特定サーバへ
internal.example.com    smtp:[10.0.0.50]:25
# サブドメインはリレー経由
.partner.com            relay:[relay.partner.com]:587
# 特定ドメインは破棄
blackhole.example.com   discard:
# ローカル配送を強制
local.example.com       local:
$ sudo postmap /etc/postfix/transport
$ sudo postfix reload

3.5 リレーホスト設定

すべての外部メールを特定のリレーサーバ経由で送信する場合の設定。

/etc/postfix/main.cf:

# すべての外部メールをリレー
relayhost = [smtp-relay.example.com]:587

# リレーホストへの SASL 認証
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt

/etc/postfix/sasl_passwd:

[smtp-relay.example.com]:587    relay_user:relay_password
$ sudo postmap /etc/postfix/sasl_passwd
$ sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
$ sudo postfix reload

3.6 TLS/SSL 設定

Let's Encrypt 証明書の取得と設定:

# Certbot のインストールと証明書取得
$ sudo dnf install certbot
$ sudo certbot certonly --standalone -d mail.example.com

# 証明書ファイルの確認
$ sudo ls -la /etc/letsencrypt/live/mail.example.com/
total 4
lrwxrwxrwx 1 root root  40 Apr  1 10:00 cert.pem -> ../../archive/mail.example.com/cert1.pem
lrwxrwxrwx 1 root root  41 Apr  1 10:00 chain.pem -> ../../archive/mail.example.com/chain1.pem
lrwxrwxrwx 1 root root  45 Apr  1 10:00 fullchain.pem -> ../../archive/mail.example.com/fullchain1.pem
lrwxrwxrwx 1 root root  43 Apr  1 10:00 privkey.pem -> ../../archive/mail.example.com/privkey1.pem

/etc/postfix/main.cf (TLS 強化設定):

# 受信側 TLS
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, KRB5-DES, CBC3-SHA
smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem

# 送信側 TLS
smtp_tls_security_level = may
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_ciphers = high

# TLS セッションキャッシュ
smtpd_tls_session_cache_timeout = 3600s
# DH パラメータの生成 (時間がかかる)
$ sudo openssl dhparam -out /etc/postfix/dh2048.pem 2048

# TLS 接続のテスト
$ openssl s_client -connect mail.example.com:25 -starttls smtp
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
...
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
...

3.7 スパムフィルタリングとアクセス制御

/etc/postfix/main.cf:

# Postscreen (ゾンビ/ボット対策)
postscreen_access_list = permit_mynetworks
postscreen_dnsbl_sites =
    zen.spamhaus.org*2
    bl.spamcop.net*1
    b.barracudacentral.org*1
postscreen_dnsbl_threshold = 3
postscreen_greet_action = enforce

# ヘッダチェック
header_checks = regexp:/etc/postfix/header_checks
body_checks = regexp:/etc/postfix/body_checks

# Milter (SpamAssassin, OpenDKIM 連携)
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:opendkim/opendkim.sock, unix:spamass/spamass.sock
non_smtpd_milters = unix:opendkim/opendkim.sock

/etc/postfix/header_checks:

/^Subject:.*viagra|cialis|lottery/i    REJECT Spam content detected
/^From:.*@known-spam-domain\.com$/     REJECT Known spam domain
/^X-Mailer:.*mass.mailer/i            REJECT Bulk mailer rejected

/etc/postfix/access (送信元制御):

# ドメイン単位の制御
example.com         OK
spammer.com         REJECT
192.168.1           OK
10.0.0.5            REJECT You are not allowed to send mail

# CIDR 形式
check_client_access cidr:/etc/postfix/client_access

4. Dovecot による受信サーバ構築

4.1 Dovecot アーキテクチャ

Dovecot は IMAP/POP3 サーバとして広く使用されており、高性能かつセキュアな設計が特徴である。

[MUA] --IMAP/POP3--> [Dovecot] ---> [メールボックス (Maildir/mbox)]
                          |
                     [認証バックエンド]
                     (PAM / LDAP / SQL / passwd)
# インストール
$ sudo dnf install dovecot     # RHEL/Rocky/Alma
$ sudo apt install dovecot-imapd dovecot-pop3d   # Debian/Ubuntu

4.2 IMAP/POP3 設定

/etc/dovecot/dovecot.conf:

# 有効にするプロトコル
protocols = imap pop3 lmtp

# リッスンするアドレス
listen = *, ::

/etc/dovecot/conf.d/10-master.conf:

service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }
}

service pop3-login {
  inet_listener pop3 {
    port = 110
  }
  inet_listener pop3s {
    port = 995
    ssl = yes
  }
}

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

# Postfix SASL 認証連携
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
  }
  user = dovecot
}

service auth-worker {
  user = vmail
}

4.3 メールボックス形式 (Maildir vs mbox)

項目Maildirmbox
構造1メール1ファイル1ファイルに全メール
ロック不要必要
破損リスク低い高い (ロック失敗時)
NFS 互換性良好問題あり
バックアップ差分が容易ファイル全体
パフォーマンス大量メールに強い少数メールに有利
ディスク使用量やや多い少ない
推奨用途サーバ環境小規模/レガシー

/etc/dovecot/conf.d/10-mail.conf:

# Maildir 形式 (推奨)
mail_location = maildir:/var/mail/vhosts/%d/%n/Maildir

# mbox 形式の場合
# mail_location = mbox:~/mail:INBOX=/var/mail/%u

# メールボックスの自動作成
namespace inbox {
  inbox = yes
  
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Archive {
    auto = subscribe
    special_use = \Archive
  }
}

# メールプロセスのユーザ
mail_uid = vmail
mail_gid = vmail
mail_privileged_group = vmail

# メールボックスサイズの上限
mail_max_userip_connections = 20

Maildir ディレクトリ構造:

/var/mail/vhosts/example.com/user1/Maildir/
├── cur/          # 既読メール
├── new/          # 未読メール
├── tmp/          # 配送中の一時ファイル
├── .Drafts/
│   ├── cur/
│   ├── new/
│   └── tmp/
├── .Sent/
│   ├── cur/
│   ├── new/
│   └── tmp/
├── .Trash/
│   ├── cur/
│   ├── new/
│   └── tmp/
└── dovecot-uidlist

4.4 認証設定

/etc/dovecot/conf.d/10-auth.conf:

# 認証メカニズム
auth_mechanisms = plain login

# 平文認証は SSL 接続時のみ許可
disable_plaintext_auth = yes

# パスワードスキーム
# {SSHA512}, {BLF-CRYPT}, {SHA512-CRYPT} 等
auth_default_realm = example.com

# 認証バックエンド
!include auth-system.conf.ext
# !include auth-sql.conf.ext
# !include auth-ldap.conf.ext
# !include auth-passwdfile.conf.ext

/etc/dovecot/conf.d/auth-passwdfile.conf.ext (ファイルベース認証):

passdb {
  driver = passwd-file
  args = scheme=SHA512-CRYPT /etc/dovecot/users
}

userdb {
  driver = passwd-file
  args = /etc/dovecot/users
  default_fields = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

/etc/dovecot/users:

user1@example.com:{SHA512-CRYPT}$6$rounds=5000$salt$hashedpassword
user2@example.com:{SHA512-CRYPT}$6$rounds=5000$salt$hashedpassword
# パスワードハッシュの生成
$ doveadm pw -s SHA512-CRYPT
Enter new password:
Retype new password:
{SHA512-CRYPT}$6$rounds=656000$abc123...$xyz789...

/etc/dovecot/conf.d/auth-sql.conf.ext (SQL 認証):

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

/etc/dovecot/dovecot-sql.conf.ext:

driver = mysql
connect = host=localhost dbname=mailserver user=dovecot password=secret

default_pass_scheme = SHA512-CRYPT

password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'
user_query = SELECT 5000 AS uid, 5000 AS gid, CONCAT('/var/mail/vhosts/', maildir) AS home FROM virtual_users WHERE email='%u'

4.5 SSL/TLS 設定

/etc/dovecot/conf.d/10-ssl.conf:

ssl = required

ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem

# 最小 TLS バージョン
ssl_min_protocol = TLSv1.2

# 暗号スイート
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

# DH パラメータ
ssl_dh = </etc/dovecot/dh.pem

# サーバ側の暗号優先
ssl_prefer_server_ciphers = yes
# DH パラメータ生成
$ sudo openssl dhparam -out /etc/dovecot/dh.pem 4096

# Dovecot の起動と自動起動
$ sudo systemctl enable --now dovecot

# SSL 接続のテスト
$ openssl s_client -connect mail.example.com:993
CONNECTED(00000003)
...
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE ...] Dovecot ready.

5. メールキュー管理

5.1 mailq / postqueue

# キューの一覧表示
$ mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
A1B2C3D4E5*    2048 Fri Apr 10 09:30:00  sender@example.com
                                         recipient@example.org

B2C3D4E5F6     4096 Fri Apr 10 09:31:00  user@example.com
          (connect to mx.example.net[203.0.113.10]:25: Connection timed out)
                                         dest@example.net

C3D4E5F6G7!    1024 Fri Apr 10 09:32:00  admin@example.com
                                         info@example.org

-- 3 Kbytes in 3 Requests.

キュー ID の記号の意味:

記号意味
*アクティブキュー (配送中)
!ホールドキュー (保留中)
なし遅延キュー (再試行待ち)
# キューの統計表示
$ postqueue -p | tail -1
-- 156 Kbytes in 42 Requests.

# 特定キューの詳細表示
$ postcat -q A1B2C3D4E5
*** ENVELOPE RECORDS A1B2C3D4E5 ***
message_size:      2048         206           1
message_arrival_time: Fri Apr 10 09:30:00 2026
create_time: Fri Apr 10 09:30:00 2026
named_attribute: rewrite_context=local
sender: sender@example.com
recipient: recipient@example.org
*** MESSAGE CONTENTS A1B2C3D4E5 ***
...

# キュー内の全メールを即時再送
$ sudo postqueue -f

# 特定ドメイン宛のキューを即時再送
$ sudo postqueue -s example.org

5.2 postsuper によるキュー操作

# 特定メールの削除
$ sudo postsuper -d A1B2C3D4E5
postsuper: A1B2C3D4E5: removed
postsuper: Deleted: 1 message

# 全キューの削除 (注意して使用)
$ sudo postsuper -d ALL
postsuper: Deleted: 42 messages

# 遅延キューのみ削除
$ sudo postsuper -d ALL deferred
postsuper: Deleted: 30 messages

# メールをホールドキューに移動
$ sudo postsuper -h A1B2C3D4E5
postsuper: A1B2C3D4E5: placed on hold
postsuper: Held: 1 message

# ホールドキューから解放
$ sudo postsuper -H A1B2C3D4E5
postsuper: A1B2C3D4E5: released from hold
postsuper: Released: 1 message

# キューの再構築 (破損時)
$ sudo postsuper -r ALL

5.3 キュー監視とアラート

#!/bin/bash
# /usr/local/bin/check_mailqueue.sh
# メールキュー監視スクリプト

WARN_THRESHOLD=50
CRIT_THRESHOLD=200
QUEUE_COUNT=$(mailq | grep -c "^[A-F0-9]")

if [ "$QUEUE_COUNT" -ge "$CRIT_THRESHOLD" ]; then
    echo "CRITICAL: Mail queue has $QUEUE_COUNT messages"
    exit 2
elif [ "$QUEUE_COUNT" -ge "$WARN_THRESHOLD" ]; then
    echo "WARNING: Mail queue has $QUEUE_COUNT messages"
    exit 1
else
    echo "OK: Mail queue has $QUEUE_COUNT messages"
    exit 0
fi
# 遅延キューのドメイン別集計
$ mailq | grep -oP '(?<=@)[a-zA-Z0-9.-]+' | sort | uniq -c | sort -rn | head -10
     15 problematic-domain.com
      8 slow-server.org
      5 example.net
      3 mail.example.com

6. スパム対策

6.1 SpamAssassin

# インストール
$ sudo dnf install spamassassin
$ sudo systemctl enable --now spamassassin

/etc/mail/spamassassin/local.cf:

# スパム判定の閾値 (デフォルト: 5.0)
required_score 5.0

# スパムヘッダの書き換え
rewrite_header Subject [SPAM]

# レポート形式
report_safe 0

# Bayesian フィルタ
use_bayes 1
bayes_auto_learn 1
bayes_auto_learn_threshold_nonspam 0.1
bayes_auto_learn_threshold_spam 12.0

# ネットワークテスト
skip_rbl_checks 0
use_razor2 1
use_pyzor 1

# カスタムルール
score URIBL_BLACK 3.0
score RCVD_IN_SORBS_SPAM 2.0

# ホワイトリスト
whitelist_from *@trusted-partner.com
whitelist_from_rcvd *@example.com example.com

Postfix との連携 (spamass-milter):

$ sudo dnf install spamass-milter

/etc/sysconfig/spamass-milter:

EXTRA_FLAGS="-m -r 15"

/etc/postfix/main.cf に追加:

smtpd_milters = unix:spamass/spamass.sock
non_smtpd_milters = unix:spamass/spamass.sock
milter_default_action = accept
# SpamAssassin のテスト
$ spamassassin -t < /usr/share/doc/spamassassin/sample-spam.txt
...
Content analysis details:   (1000.0 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
1000 GTUBE                  BODY: Generic Test for Unsolicited Bulk Email
...

# Bayesian データベースの学習
$ sa-learn --spam /path/to/spam-folder/
Learned tokens from 150 message(s) (150 message(s) examined)

$ sa-learn --ham /path/to/ham-folder/
Learned tokens from 500 message(s) (500 message(s) examined)

# ルールの更新
$ sudo sa-update

6.2 OpenDKIM

# インストール
$ sudo dnf install opendkim opendkim-tools

/etc/opendkim.conf:

Mode                 sv
Syslog               yes
SyslogSuccess        yes
LogWhy               yes

Canonicalization     relaxed/simple
Domain               example.com
Selector             mail2026
KeyFile              /etc/opendkim/keys/example.com/mail2026.private

Socket               local:/var/spool/postfix/opendkim/opendkim.sock

PidFile              /run/opendkim/opendkim.pid
OversignHeaders      From
TrustAnchorFile      /usr/share/dns/root.key

# 複数ドメイン対応
KeyTable             refile:/etc/opendkim/KeyTable
SigningTable         refile:/etc/opendkim/SigningTable
InternalHosts        refile:/etc/opendkim/TrustedHosts
ExternalIgnoreList   refile:/etc/opendkim/TrustedHosts
# DKIM 鍵の生成
$ sudo mkdir -p /etc/opendkim/keys/example.com
$ sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s mail2026 -v
opendkim-genkey: generating private key
opendkim-genkey: private key written to mail2026.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to mail2026.txt

# 公開鍵の確認 (DNS に設定する内容)
$ cat /etc/opendkim/keys/example.com/mail2026.txt
mail2026._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
    "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." )

$ sudo chown -R opendkim:opendkim /etc/opendkim/keys/

/etc/opendkim/KeyTable:

mail2026._domainkey.example.com    example.com:mail2026:/etc/opendkim/keys/example.com/mail2026.private

/etc/opendkim/SigningTable:

*@example.com    mail2026._domainkey.example.com

/etc/opendkim/TrustedHosts:

127.0.0.1
::1
10.0.0.0/24
mail.example.com
example.com

/etc/postfix/main.cf に追加:

smtpd_milters = unix:opendkim/opendkim.sock
non_smtpd_milters = unix:opendkim/opendkim.sock
milter_default_action = accept
milter_protocol = 6
$ sudo systemctl enable --now opendkim
$ sudo postfix reload

# DKIM 署名の検証テスト
$ opendkim-testkey -d example.com -s mail2026 -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'mail2026._domainkey.example.com'
opendkim-testkey: key OK

6.3 Postscreen と Greylisting

/etc/postfix/master.cf (Postscreen 有効化):

# 標準の smtpd を Postscreen に置き換え
smtp      inet  n       -       n       -       1       postscreen
smtpd     pass  -       -       n       -       -       smtpd
dnsblog   unix  -       -       n       -       0       dnsblog
tlsproxy  unix  -       -       n       -       0       tlsproxy

/etc/postfix/main.cf (Postscreen 設定):

postscreen_access_list = permit_mynetworks, cidr:/etc/postfix/postscreen_access.cidr
postscreen_blacklist_action = drop
postscreen_greet_action = enforce
postscreen_dnsbl_action = enforce
postscreen_dnsbl_sites =
    zen.spamhaus.org*2
    bl.spamcop.net*1
    b.barracudacentral.org*1
postscreen_dnsbl_threshold = 3
postscreen_dnsbl_whitelist_threshold = -1
postscreen_cache_map = btree:$data_directory/postscreen_cache
postscreen_greet_wait = ${stress?2}${stress:6}s

7. トラブルシューティング

ログの確認

# メールログの確認
$ sudo tail -f /var/log/maillog          # RHEL 系
$ sudo tail -f /var/log/mail.log         # Debian 系
$ sudo journalctl -u postfix -f          # systemd

# 特定のメール ID を追跡
$ sudo grep "A1B2C3D4E5" /var/log/maillog
Apr 10 09:30:00 mail postfix/smtpd[12345]: A1B2C3D4E5: client=unknown[192.168.1.100]
Apr 10 09:30:00 mail postfix/cleanup[12346]: A1B2C3D4E5: message-id=<abc@example.com>
Apr 10 09:30:01 mail postfix/qmgr[12347]: A1B2C3D4E5: from=<sender@example.com>, size=2048, nrcpt=1 (queue active)
Apr 10 09:30:02 mail postfix/smtp[12348]: A1B2C3D4E5: to=<recipient@example.org>, relay=mx.example.org[203.0.113.20]:25, delay=2, delays=0.5/0.1/1/0.4, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued)
Apr 10 09:30:02 mail postfix/qmgr[12347]: A1B2C3D4E5: removed

よくある問題と対処法

症状原因対処法
Connection timed outファイアウォール / ポートブロックfirewall-cmd --add-service=smtp
Relay access deniedリレー設定不備mynetworks / SASL 認証の確認
Recipient address rejected宛先ドメイン未設定mydestination / virtual_mailbox_domains の確認
TLS handshake failed証明書の問題証明書の期限・パスを確認
Authentication failed認証設定不備Dovecot 認証設定・SASL パスの確認
Mail loop detectedMX レコードがループDNS 設定の確認
Mailbox fullディスク容量不足クォータ設定・ディスク空き容量の確認
Host or domain name not foundDNS 解決失敗/etc/resolv.conf・DNS サーバの確認

診断コマンド集

# Postfix の設定値を確認
$ postconf -d | grep mynetworks       # デフォルト値
$ postconf -n | grep mynetworks       # 変更された値

# SMTP 接続テスト
$ telnet mail.example.com 25
$ openssl s_client -connect mail.example.com:465
$ openssl s_client -connect mail.example.com:587 -starttls smtp

# メール配送テスト
$ echo "Test mail" | mail -s "Test Subject" user@example.com

# Dovecot の設定確認
$ doveconf -n
$ doveadm mailbox list -u user@example.com
INBOX
Drafts
Sent
Trash
Junk
Archive

# メール認証の検証
$ dig TXT example.com +short              # SPF
$ dig TXT mail2026._domainkey.example.com +short  # DKIM
$ dig TXT _dmarc.example.com +short       # DMARC

# ポートの確認
$ ss -tlnp | grep -E '(25|110|143|465|587|993|995)'
LISTEN  0  100  *:25     *:*  users:(("master",pid=1234,fd=13))
LISTEN  0  100  *:587    *:*  users:(("master",pid=1234,fd=14))
LISTEN  0  100  *:993    *:*  users:(("dovecot",pid=2345,fd=20))
LISTEN  0  100  *:995    *:*  users:(("dovecot",pid=2345,fd=22))

# Postfix のプロセス状態
$ sudo postfix status
postfix/postfix-script: the Postfix mail system is running: PID: 1234

8. プロトコル・ポート比較表

プロトコルポート暗号化用途
SMTP25STARTTLS (オプション)MTA 間のメール転送
SMTP Submission587STARTTLS (必須)MUA からの送信
SMTPS465暗黙的 TLSMUA からの送信 (レガシー/復活)
POP3110STARTTLS (オプション)メール受信
POP3S995暗黙的 TLSメール受信 (暗号化)
IMAP143STARTTLS (オプション)メール受信
IMAPS993暗黙的 TLSメール受信 (暗号化)
LMTP24なしローカル配送

ファイアウォール設定:

# 必要なポートの開放
$ sudo firewall-cmd --permanent --add-service=smtp
$ sudo firewall-cmd --permanent --add-service=smtps
$ sudo firewall-cmd --permanent --add-port=587/tcp
$ sudo firewall-cmd --permanent --add-service=imaps
$ sudo firewall-cmd --permanent --add-service=pop3s
$ sudo firewall-cmd --reload

# 確認
$ sudo firewall-cmd --list-all
public (active)
  services: smtp smtps imaps pop3s
  ports: 587/tcp

9. ベストプラクティス

セキュリティ

  1. TLS を必須化する - Submission (587) と IMAP/POP3 への平文アクセスを禁止する
  2. TLSv1.2 以上を強制する - 古いプロトコルは無効化する
  3. SPF + DKIM + DMARC を全て設定する - 段階的にポリシーを強化する (none -> quarantine -> reject)
  4. Postscreen を有効化する - ボットからの接続を早期に遮断する
  5. Fail2ban を導入する - 認証失敗の繰り返しを検知しブロックする
  6. オープンリレーを絶対に許可しない - mynetworkssmtpd_recipient_restrictions を適切に設定する

運用

  1. 証明書の自動更新 - certbot の cron/timer を設定する
  2. キュー監視 - 閾値ベースのアラートを設定する
  3. ログローテーション - /var/log/maillog のローテーションを確認する
  4. バックアップ - 設定ファイルとメールボックスの定期バックアップ
  5. DNS の冗長化 - MX レコードに複数のサーバを設定する (優先度を分ける)
  6. レート制限 - 送信レートを適切に制限し、ブラックリスト登録を防ぐ

パフォーマンス

  1. Maildir を使用する - mbox よりロック競合が少なく拡張性が高い
  2. 接続プール - smtp_destination_concurrency_limit を調整する
  3. DNS キャッシュ - ローカルに unbound 等のキャッシュ DNS を設置する
  4. メールボックスクォータ - ユーザごとのディスク使用量を制限する

監視項目

監視対象閾値例ツール
メールキュー数Warning: 50, Critical: 200Nagios, Zabbix
ディスク使用率Warning: 80%, Critical: 95%df, Prometheus
SMTP 応答時間Warning: 5s, Critical: 15scheck_smtp
認証失敗回数5回/分 以上Fail2ban, Prometheus
送信メール数異常増加を検知pflogsumm
TLS 証明書期限30日前に警告check_ssl_cert

10. 参考文献


注記: 本ドキュメントは学習・参考目的で作成されたものであり、本番環境への適用時には各組織のセキュリティポリシーやネットワーク構成に合わせた調整が必要である。