「Google社・米国Yahoo社が2024年2月よりメール受信の厳格化」に対応するためのまとめ 【SPF、DKIM、DMARC、ARC、SRS全対応】 Poftfix

迷惑メールや不正行為の対応するための手段として、SPF、DKIM、DMARC等の技術が使われてきました。
今までは、比較的容易に対応可能なSPFだけ対応していれば問題なく利用できていましたが、SPFに加えてDKIM、DMARCの運用も求められるようになってきます。

重要: Gmail では 2024 年 2 月以降、Gmail アカウントに 1 日あたり 5,000 件以上のメールを送信する送信者に対し、1. 送信メールを認証すること、2. 未承諾のメールまたは迷惑メールを送信しないようにすること、3. 受信者がメールの配信登録を容易に解除できるようにすること、の 3 つが義務付けられます。詳しくは、1 日あたり 5,000 件以上のメールを送信する場合の要件をご覧ください。

https://support.google.com/mail/answer/81126?hl=ja

Google では、メールが認証されていることを確認するために、Gmail アカウントに送信されたメールのチェックを行います。メールが確実に配信されるようにするには、ドメインに SPFDKIMDMARC を常に設定することをおすすめします。

当ブログでも、メールサーバーの構築としてSPF、DKIM、DMARC対応の記事を書いてきましたが、それぞれの記事を個別に見ていても実際の構築する段階では、全てが Postfixと連動して動作するため最終形の設定ファイルの情報がないと分かりにくいかと思いました。特に、DKIMやDMARCの記事のアクセスが急増していることから急ぎ対応に迫られている方も多いかと思います。
そこで、取り急ぎSPF、DKIM、DMARC、ARC全てに対応するPostfixの設定についてまとめてみます。
個々の細かいパラーメータ等の説明を省き、構築のポイントだけに絞り全部まとめて構築完了して初めて動作するものとなります。詳細は個別記事を参照下さい。

また、メールをGmailに転送するような運用も多いかと思います。転送メールの場合、送信メールアドレスと転送元のメールサーバーのSPFが一致せずに転送メールが受信拒否されることもあります。転送メールには、基本的にはSRSでSPF対応、DKIM再署名、ARCで認証情報伝搬などで対応することができます。

目次

前提条件

この記事の検証環境と仕様は以下の通りです。

  • GMOインターネットさまのConoHa VPSを利用しています。
  • Alma Linux9.2 テンプレート
  • Postfixは MariaDBと連携させる(API連携などがしやすいため)
  • Dovecot、ManegeSieve連携
  • DNSは、PowerDNSを使用する(レコード追加するだけなので特に指定なし)
  • ドメインは blue.int-design.jp で構築します。ご自身のドメインに置き換えてください。
    サーバーのFQDNは sv1.blue.int-design.jp とします。
    ご自身のドメインに置き換えてご利用ください。
  • メールアドレスは ○○○@blue.int-design.jp, ○○○@red.int-design.jp, ○○○@green.int-design.jp でVirtualDomainとします。SNIで複数の証明書を使用します。

<<ご注意>>
メールサーバーのホスト名(FQDN)は、 sv1.blue.int-design.jp のようにドメインにホスト名を付けるようにしてください。ネーキッドドメイン(blue.int-design.jp)でも、構築はできますが、メールパイプ等を行う場合に、これが原因で期待した動作をしないことがありますので、無用なトラブルを避けるためにもホスト名を付けて運用されることをおすすめします。

Postfixのmain.cfで myhostnameとmydomainが同じような場合です。

myhostname = your_hostname.your_domain
mydomain = your_domain

事前準備

MySQL(MariaDB)と連携してアカウント等を管理する準備

MariaDBと管理用にphpMyAdminを導入しています。個々の説明は、以下の記事を参考にしてください。
phpMyAdminを使用するには、PHPやApache等のWebサーバーも必要になってきます。
CLIでも問題なく構築できますので、必須ではありません。

あわせて読みたい
MariaDB(MySQL) の導入 MariaDBは、MySQLをベースに開発されたオープンソースのデータベース管理システムです。MySQLからのリレーショナルデータベース管理システムMariaDBは、性能の向上や新...
あわせて読みたい
phpMyAdmin の導入 phpMyAdminは、Webベースのインターフェースを利用してMySQLやMariaDBデータベースを管理するためのオープンソースのツールです。PHPで書かれており、主にデータベース...

DNSサーバーの構築

あわせて読みたい
DNSサーバー PowerDNS の導入 PowerDNSは、高性能で安定したDNSサーバソフトウェアです。オープンソースのプロジェクトとして開発されており広く普及しています。 【特徴】 モジュール式アーキテクチ...

DNSサーバーに関しては、自前で構築しなくてもドメイン取得されたところで、DNSサービスが利用できるかと思います。DNSのTXTレコードが自由に設定できるようであれば、そちらを利用したいただくことをお勧めします。

EPELリポジトリとRemiリポジトリの追加

EPELリポジトリとRemiリポジトリを追加し、最新バージョンのPHPをインストールできるようにします。

sudo yum -y install epel-release
sudo yum -y install https://rpms.remirepo.net/enterprise/remi-release-9.2.rpm

almalinux-crb.repo の有効化

sendmail-milter をインストールするために必要です。

dnf config-manager --set-enabled crb
dnf repolist --all | grep crb
crb                           AlmaLinux 9 - CRB                         enabled
crb-debuginfo                 AlmaLinux 9 - CRB - Debug                 disabled
crb-source                    AlmaLinux 9 - CRB - Source                disabled

その他必要なモジュールのインストール

必要なモジュールをインストールしておきます。

sudo yum -y install wget unzip php-mbstring
sudo yum -y install postfix-pcre

DMARCでレポート送信に必要なモジュールをインストールします。
確認がでたら[YES]エンターですすめてください。少々時間がかかります・・・

sudo yum -y install cpan
sudo yum -y install mariadb-devel

sudo cpan Switch
sudo cpan JSON
sudo cpan -T DBD::mysql
sudo cpan HTTP::Request

dig等のDNS関連のツールをインストール

sudo dnf install -y bind-utils

その他の調整

ファイアウォールの設定

firewalldを有効化します。

sudo systemctl start firewalld
sudo systemctl enable firewalld

メールサーバー用のポートを開放します。

sudo firewall-cmd --add-service=pop3s --permanent
sudo firewall-cmd --add-service=imaps --permanent
sudo firewall-cmd --add-service=smtp --permanent
sudo firewall-cmd --add-service=smtps --permanent
sudo firewall-cmd --permanent --add-port=587/tcp

sudo firewall-cmd --reload

インストール済みのパッケージを全てアップデートします。

sudo yum -y update

ホスト名を変更します

sudo hostnamectl set-hostname sv1.blue.int-design.jp
あわせて読みたい
Apache, PHP 8.3 (PHP-FPM) の導入 更新:PHP8.2からPHP8.3へ変更しました。 PHP8.2の場合は 8.3を8.2に置き換えるだけです。CentOSでApache, PHP 8.3 (PHP-FPM) とMariaDBを使用してセキュアなWEBサーバ...
あわせて読みたい
Let’s Encryptの導入 (SAN証明書, ワイルドカード証明書) Let's Encrypt とは、無料でSSL証明書を発行するための認証局 (CA: Certificate Authority) で、ウェブサイトのセキュリティを簡単かつ手頃な価格で向上させること...

パッケージのインストール

DKIM, DMARC, ARC等の連携設定は後でまとめて行いますので、ここでは各種連携は省略します。
いったんパッケージのインストールと有効化を行っていきます。
関連記事は以下ですが、特に読めなくても進められます。

あわせて読みたい
Postfix, PostfixAdmin, Dovecot の導入 (MariaDB連携, SMTP-Auth, Sieve) https://int-design.jp/content/spf-dkim-dmarc-arc-gmail/ Postfixは、オープンソースの高速かつセキュアなSMTPサーバーです。主にメールの送信機能(MTA:Mail Transf...

SMTP-Auth の導入

SMTP-Auth のパッケージをインストールして有効にします。

sudo yum -y install cyrus-sasl cyrus-sasl-plain cyrus-sasl-md5
sudo systemctl enable saslauthd
sudo systemctl start saslauthd

Postfix の導入

sudo yum -y install postfix
sudo yum -y install postfix-mysql
sudo systemctl enable postfix
sudo systemctl start postfix

Dovecot の導入

Dovecotのモジュールをインストールして有効化します。

sudo yum -y install dovecot dovecot-mysql
sudo yum -y install dovecot-pigeonhole
sudo systemctl enable dovecot

## 設定が完了してから起動します。
# /run/dovecot/stats-writer の ownerに影響がでるため
#sudo systemctl start dovecot

OpenDKIM の導入

OpenDKIMのモジュールをインストールして有効化します。

sudo yum -y install opendkim opendkim-tools
sudo systemctl enable opendkim
sudo systemctl start opendkim

libmilter.so が無い場合は、依存関係のエラーが出力されます。

dnf config-manager –set-enabled crb
でalmalinux-crb.repoを有効にしておけば、sendmail-milterが導入され以下のエラーは解消されます。

sudo yum -y installopendkim opendkim-tools
Last metadata expiration check: 0:16:00 ago on Mon 18 Dec 2023 06:43:26 PM JST.
Error: 
 Problem 1: conflicting requests
  - nothing provides libmilter.so.1.0()(64bit) needed by opendkim-2.11.0-0.36.el9.x86_64 from epel
  - nothing provides libmemcached.so.11()(64bit) needed by opendkim-2.11.0-0.36.el9.x86_64 from epel
 Problem 2: conflicting requests
  - nothing provides libmemcached.so.11()(64bit) needed by opendkim-tools-2.11.0-0.36.el9.x86_64 from epel
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

SRS (Sender Rewriting Scheme)の導入

必要なパッケージをインストールして有効化します。

sudo yum -y install postsrsd
sudo systemctl enable postsrsd
sudo systemctl start postsrsd

OpenARC の導入

必要なパッケージをインストールして有効化します。

sudo yum -y install openarc 
sudo systemctl enable openarc
sudo systemctl start openarc

OpenDMARC の導入

必要なパッケージをインストールして有効化します。

sudo yum -y install opendmarc
sudo systemctl enable opendmarc
sudo systemctl start opendmarc

OpenDMARC の設定

MariaDB に opendmarc データベースとユーザーを作成

mysql -u root -p
CREATE DATABASE opendmarc;
GRANT ALL ON opendmarc.* TO 'opendmarc'@'localhost' IDENTIFIED BY 'ここにパスワード';
FLUSH PRIVILEGES;

OpenDMARC スキーマをインポート

そのままではインポート時にエラーが発生しますので、スキーマファイルを修正します。

mysql -u opendmarc -p opendmarc < /usr/share/opendmarc/db/schema.mysql
Enter password: 
ERROR 1067 (42000) at line 58: Invalid default value for 'lastsent'

MySQL のバージョンによって、最初の ‘TIMESTAMP’ カラムは常に ‘CURRENT_TIMESTAMP’ をデフォルトとして使用するため、lastsent TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00' がエラーを引き起こします。

この問題を解決するために、lastsent カラムの型を DATETIME に変更し、デフォルト値を ‘1970-01-01 00:00:00’ に設定することができます。修正後の CREATE TABLE 文は次のようになります。

sudo vi /usr/share/opendmarc/db/schema.mysql
-- A table for logging reporting requests
CREATE TABLE IF NOT EXISTS requests (
        id INT NOT NULL AUTO_INCREMENT,
        domain INT NOT NULL,
        repuri VARCHAR(255) NOT NULL DEFAULT '',
        adkim TINYINT NOT NULL DEFAULT '0',
        aspf TINYINT NOT NULL DEFAULT '0',
        policy TINYINT NOT NULL DEFAULT '0',
        spolicy TINYINT NOT NULL DEFAULT '0',
        pct TINYINT NOT NULL DEFAULT '0',
        locked TINYINT NOT NULL DEFAULT '0',
        firstseen TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        lastsent DATETIME NOT NULL DEFAULT '1970-01-01 00:00:00',

        PRIMARY KEY(id),
        KEY(lastsent),
        UNIQUE KEY(domain)
);
mysql -u opendmarc -p opendmarc < /usr/share/opendmarc/db/schema.mysql

OpenDMARC の設定

/etc/opendmarc.conf ファイルを編集します。

sudo vi /etc/opendmarc.conf
AuthservID blue.int-design.jp
PidFile /var/run/opendmarc/opendmarc.pid

Syslog true
TrustedAuthservIDs blue.int-design.jp
UMask 0002

UserID opendmarc:opendmarc

#IgnoreHosts /etc/opendmarc/ignore.hosts
HistoryFile /var/run/opendmarc/opendmarc.dat

Socket inet:8893@localhost
SoftwareHeader true

主な変更箇所は以上です。
ここで特に重要なのが Socket のポート番号です。Postfixに設定する時に関係してきます。
OpenDMARCのポート番号は明示的に決められていませんので任意で構いませんが、他と重複しないように特に問題なければ Socket inet:8893@localhostで構築します。
AuthservIDTrustedAuthservIDsに、自身のサーバーのFQDNを登録してください。

Postfixにも連携するための設定が必要ですが最後にまとめて行います。

# systemctl status opendmarc.service 
● opendmarc.service - Domain-based Message Authentication, Reporting & Conformance (DMARC) Milter
     Loaded: loaded (/usr/lib/systemd/system/opendmarc.service; enabled; preset: disabled)
     Active: active (running) since Mon 2023-12-18 23:20:22 JST; 7s ago
       Docs: man:opendmarc(8)
             man:opendmarc.conf(5)
             man:opendmarc-import(8)
             man:opendmarc-reports(8)
             http://www.trusteddomain.org/opendmarc/
   Main PID: 122599 (opendmarc)
      Tasks: 3 (limit: 11135)
     Memory: 2.5M
        CPU: 4ms
     CGroup: /system.slice/opendmarc.service
             └─122599 /usr/sbin/opendmarc -f -c /etc/opendmarc.conf

Dec 18 23:20:22 sv1.blue.int-design.jp systemd[1]: Started Domain-based Message Authentication, Reporting & Conformance (DMARC) Milter.
Dec 18 23:20:22 sv1.blue.int-design.jp opendmarc[122599]: OpenDMARC Filter v1.4.2 starting (args: -f -c /etc/opendmarc.conf)
Dec 18 23:20:22 sv1.blue.int-design.jp opendmarc[122599]: additional trusted authentication services: blue.int-design.jp

DNS に DMARC レコードを追加

DNS に DMARC レコードを追加するために、以下のような TXT レコードを作成します。
ここでは、blue.int-design.jpを設定していますが、自身のドメインに置き換えてください。
メールアドレスは、実際にメールが届きますので受け取れるものであれば別のドメインでも構いません。

_dmarc.blue.int-design.jp.  IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@blue.int-design.jp; ruf=mailto:dmarc@blue.int-design.jp; fo=1"

これで、Postfix と MariaDB を使用して DMARC に対応する方法が完了です。
ここで指定したメールアドレス宛にレポートメールが送信されてきます。
例えば Gmailであれば From: noreply-dmarc-support@google.com からzipファイル届きます。

OpenDKIM の設定

OpenDKIMの設定ファイル(/etc/opendkim.conf など)を編集し、必要な設定を行います。

sudo vi /etc/opendkim.conf

設定ファイルを以下のように変更してください。
デフォルト値のものは省略しています。

Domain                  blue.int-design.jp

#Canonicalization       relaxed/relaxed
Canonicalization        relaxed/simple

ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
KeyTable                refile:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable

#Mode                   v
Mode                    sv
PidFile                 /var/run/opendkim/opendkim.pid

Socket                  inet:8891@localhost

##コメントアウトOversignHeaders
#OversignHeaders        From
##追加
SignHeaders Date,From,To,Subject,Message-ID

# 転送メール目的 追加
On-BadSignature         accept
RemoveOldSignatures     no
#PreserveExistingSignature no

Postfix の主設定ファイル /etc/postfix/main.cf でも opendkim との通信方法を追加する必要がありますが、後でまとめて設定を行います。

# systemctl status opendkim
● opendkim.service - DomainKeys Identified Mail (DKIM) Milter
     Loaded: loaded (/usr/lib/systemd/system/opendkim.service; enabled; preset: disabled)
     Active: active (running) since Mon 2023-12-18 23:19:34 JST; 1min 48s ago
       Docs: man:opendkim(8)
             man:opendkim.conf(5)
             man:opendkim-genkey(8)
             man:opendkim-genzone(8)
             man:opendkim-testadsp(8)
             man:opendkim-testkey
             http://www.opendkim.org/docs.html
   Main PID: 122499 (opendkim)
      Tasks: 3 (limit: 11135)
     Memory: 1.5M
        CPU: 8ms
     CGroup: /system.slice/opendkim.service
             └─122499 /usr/sbin/opendkim -f -x /etc/opendkim.conf

Dec 18 23:19:34 sv1.blue.int-design.jp systemd[1]: Started DomainKeys Identified Mail (DKIM) Milter.
Dec 18 23:19:34 sv1.blue.int-design.jp opendkim[122499]: OpenDKIM Filter v2.11.0 starting (args: -f -x /etc/opendkim.conf)

OpenDKIM のディレクトリとファイルの作成

必要なディレクトリとファイルを作成し、アクセス権限を設定します。
※パッケージをインストールした時点で作成されているかと思います。

sudo mkdir /etc/opendkim
sudo chown opendkim:opendkim /etc/opendkim

sudo mkdir /etc/opendkim/keys
sudo chown opendkim:opendkim /etc/opendkim/keys

sudo touch /etc/opendkim/SigningTable
sudo touch /etc/opendkim/KeyTable
sudo touch /etc/opendkim/TrustedHosts

sudo chown opendkim:opendkim /etc/opendkim/{KeyTable,SigningTable,TrustedHosts}

信頼できるホスト(TrustedHosts)の設定

/etc/opendkim/TrustedHosts ファイルを編集し、信頼できるホスト(ローカルホストおよびドメインサブネット)を追加します。

sudo vi /etc/opendkim/TrustedHosts

以下の内容をファイルに追加します。

127.0.0.1
localhost
::1
*.blue.int-design.jp
*.red.int-design.jp
*.green.int-design.jp

## 転送メールに強制的に再署名を行う場合
## 強制再署名するには、更に /etc/opendkim/SigningTable で ワイルドカードで特定の証明書にマッチさせる必要があります。
0.0.0.0/0

blue.int-design.jp を自身のドメイン名に置き換えます。

Gmail等にメールを転送するような場合、不特定多数の送信元IPに対して強制DKIM再署名を行うため 0.0.0.0/0 のように全てのIPを許可する必要があります。
転送で拒否されるのを回避する手段は、DKIM以外にもSPFのSRS等もあります。

DKIM 鍵ペアの生成

ドメインごとに DKIM 鍵ペアを生成します。<selector> は任意の文字列ですが、一般的に default や mail などを使います。

まず、キーディレクトリを作成します。

sudo -u opendkim mkdir -p /etc/opendkim/keys/<your_domain>

## 複数ドメインで Virtual運用する場合は、SNIで個別の証明書をを設定することもできます。
## 1つの証明書で全てのドメインを署名することもできます。
sudo -u opendkim mkdir -p /etc/opendkim/keys/blue.int-design.jp
sudo -u opendkim mkdir -p /etc/opendkim/keys/red.int-design.jp
sudo -u opendkim mkdir -p /etc/opendkim/keys/green.int-design.jp

次に、鍵ペアを生成します。

sudo -u opendkim opendkim-genkey -b 2048 -d <your_domain> -D /etc/opendkim/keys/<your_domain> -s <selector> -v

## 複数ドメインで Virtual運用する場合は、SNIで個別の証明書をを設定することもできます。
## 1つの証明書で全てのドメインを署名することもできます。
sudo -u opendkim opendkim-genkey -b 2048 -d blue.int-design.jp -D /etc/opendkim/keys/blue.int-design.jp -s default -v
sudo -u opendkim opendkim-genkey -b 2048 -d red.int-design.jp -D /etc/opendkim/keys/red.int-design.jp -s default -v
sudo -u opendkim opendkim-genkey -b 2048 -d green.int-design.jp -D /etc/opendkim/keys/green.int-design.jp -s default -v

このようなファイルが作成されます。

 ll /etc/opendkim/keys/blue.int-design.jp
total 8
-rw------- 1 opendkim opendkim 1704 Dec 18 23:54 default.private
-rw------- 1 opendkim opendkim  504 Dec 18 23:54 default.txt

default.txtの内容をDNSのTXTレコードに記述します。

KeyTable と SigningTable の設定

ドメインとその署名鍵に関する情報を保持しています。KeyTableファイルは、各ドメインごとにどのセレクタと秘密鍵ファイルを使用するかを指定します。
<selector> は任意の文字列ですが、一般的に default などを使います。

<selector>._domainkey.<your_domain> <your_domain>:<selector>:/etc/opendkim/keys/<your_domain>/<selector>.private
  • <selector>._domainkey.example.com は、公開鍵レコードが保存されるDNSのテキスト(TXT)レコードです。
  • <your_domain>は、署名対象となるドメインです。
  • <selector> は、鍵ペアを識別するための名前です。
  • /etc/opendkim/keys/<your_domain>/<selector>.private は、秘密鍵ファイルへのパスです。

/etc/opendkim/keytable ファイルを編集

sudo vi /etc/opendkim/KeyTable

以下の行を追加し、<selector> と <your_domain> を実際の値に置き換えて、以下の行を追加します。

<selector>._domainkey.<your_domain> <your_domain>:<selector>:/etc/opendkim/keys/<your_domain>/<selector>.private

default._domainkey.blue.int-design.jp blue.int-design.jp:default:/etc/opendkim/keys/blue.int-design.jp/default.private
default._domainkey.red.int-design.jp blue.int-design.jp:default:/etc/opendkim/keys/red.int-design.jp/default.private
default._domainkey.green.int-design.jp blue.int-design.jp:default:/etc/opendkim/keys/green.int-design.jp/default.private

/etc/opendkim/SigningTable ファイルの編集

sudo vi /etc/opendkim/SigningTable

以下の行を追加し、<selector> , <your_domain> を実際の値に置き換えます。

*@<your_domain> <selector>._domainkey.<your_domain>

##自ドメインから送信するメールにだけ署名する場合
*@blue.int-design.jp default._domainkey.blue.int-design.jp
*@red.int-design.jp default._domainkey.red.int-design.jp
*@green.int-design.jp default._domainkey.green.int-design.jp

## 転送メールに再署名する場合はワイルドカードにする
* default._domainkey.blue.int-design.jp

DNSに公開鍵を追加する

生成された公開鍵を DNS TXT レコードに追加する必要があります。/etc/opendkim/keys/<your_domain>/<selector>.txt ファイルに記載されている内容を確認します。

sudo cat /etc/opendkim/keys/<your_domain>/<selector>.txt

sudo cat /etc/opendkim/keys/blue.int-design.jp/default.txt

出力されたレコードをドメインの DNS 設定に追加します。TXT レコード名は <selector>._domainkey で、値はファイルの内容を使用します(括弧や改行なし)。

例:

default._domainkey      IN      TXT     "v=DKIM1; k=rsa;""p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0GCczxhT+nmdkQcmyhnCF3aZzGBK4N9+Nmuqm5L3nllXSUwwZdHmPThsqiBujLKoiMSZzc""zdh4zvvgJxlm+Z/mqjr8AZ67RTaserdvUkaJDMlJFdJGJkhooAm+DrKPbCDHVf9exg/+JpmuLwLUOyKXRp2F74xL0XTl6glgBT""GuhPEwufLY/CMC+NVhQ0PguYAuOJJz8didQkWa15jpYWQjfUq5xrU7D9JLL3ElBQ+sQ9r+c1RxTqrmoXjjnkZFPvQKhR4qzzNf""7EAd/kZC73H36fQUS5wu1dDm1dt945J/0FiGf0EDbFzPD5U/VwgUFpzh8nwNkGQmJz9rClRUKgCQIDAQAB"

これで、default._domainkey に正しく長いDKIMレコードが登録されます。
bindであれば、そのまま貼り付けるだけです。
登録後は必ず dig や nslookupで正しく DNSが参照できるか確認するようにしてください。

DNSのTXTレコードの最大長は 255 文字です。しかし、1つのTXTレコード内で複数の255文字以下の文字列を持つことが可能です。これらの各文字列はダブルクォーテーション(")で囲まれます。

例えば、次のような記述が可能です。

v=DKIM1; k=rsa; p=ASDF...(255文字)...ZXCV

この記述を2つの255文字以下の文字列に分けると次のようになります。

"v=DKIM1; k=rsa; p=ASDF...(一部)..."
"...(残りの部分)...ZXCV"

これらの文字列は全て連結され、1つの値として解釈されます。
DNSサービスの仕様で、長い文字列をそのまま貼り付けて分割できるものもありますが、内部的には分割されて保存されています。

OpenARC の設定

OpenARC の設定ファイルを編集します。

sudo vi /etc/openarc.conf

ここでは、ドメインとしてblue.int-design.jpを設定していますが、自身のドメインに置き換えてください。

PidFile /var/run/openarc/openarc.pid
Socket  inet:8892@localhost
Mode    sv

AuthservID blue.int-design.jp
Selector   default
Domain     blue.int-design.jp
KeyFile /etc/openarc/keys/blue.int-design.jp/default.private

SignHeaders to,subject,message-id,date,from,mime-version,dkim-signature
PeerList /etc/openarc/PeerList
MilterDebug 6
EnableCoredumps yes

次に、秘密鍵を作成します。

mkdir /etc/ssl/private/
openssl genrsa -out /etc/ssl/private/arc.key.pem 2048

Postfixとの連携の設定は後でまとめて行います。

ARC 鍵ペアの用意

鍵ペアは、OpenDKIMで生成したものを使用します。

sudo cp -r /etc/opendkim/keys/ /etc/openarc
sudo chown -R openarc.openarc /etc/openarc/keys

ファイルの所有者とグループを openarc に変更しておきます。

#シンボリックではエラーで起動しないかと思います。

DKIM/ARCレコードをDNSに追加

公開鍵をDNSに追加するため、 以下のレコードを追加します。(<selector> と <your_public_key> は実際の値に置き換えてください)。
すでに、DKIMを導入している場合は、登録されているはずです。

<selector>._domainkey IN TXT "v=DKIM1; k=rsa; p=<your_public_key>"

default._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAybKP7Xq1j607g1y/8JJR+zIQqzYU5cGx0wguZJwk39JLjukFSlfY8Nsdj 37QDGtKz0HuWxPM3xauLfYEY0kJv0s0V3706y/1glvHcx5YnkRnDbktoYWmL+KGOvXsAPyduy/9mY8eT9incFsUgbYp8EFUArWrb0oubaMHOc6uEhU FW6XMinYZkRsKZpmLEl9" "y6elmu/8TJAGBzBAEBoMqJJcPajTUV6fiCcDwJ3c4J/g/yW4cCDRdfwTPWgWSGyW1uDxjzxSzkkKDP1GCMxvCn8OGwYArs+BufPIZfnhtHNHQ+VMeZyve0 o4N/BFzBx2javjDXM8jPqih1VK7l+CEfwIDAQAB"

OpenARCの設定の確認

rootアカウントで1行で実行する場合は、sudosuコマンドを組み合わせて使用します。以下のコマンドで、openarcユーザーとしてopenarc -nを実行できます。

sudo su -s /bin/bash openarc -c "openarc -n"

鍵が作成されていないと以下のようなエラーになります。

sudo su -s /bin/bash openarc -c "openarc -n"
openarc: /etc/openarc.conf: /etc/openarc/keys/blue.int-design.jp/default.private: open(): No such file or directory
systemctl status openarc
● openarc.service - Authenticated Receive Chain (ARC) Milter
     Loaded: loaded (/usr/lib/systemd/system/openarc.service; disabled; preset: disabled)
     Active: active (running) since Tue 2023-12-19 00:09:06 JST; 29s ago
       Docs: man:openarc(8)
             man:openarc.conf(5)
             http://www.trusteddomain.org/openarc/
    Process: 123136 ExecStartPost=/sbin/restorecon -r -F /run/openarc (code=exited, status=0/SUCCESS)
   Main PID: 123135 (openarc)
      Tasks: 3 (limit: 11135)
     Memory: 2.9M
        CPU: 13ms
     CGroup: /system.slice/openarc.service
             └─123135 /usr/sbin/openarc -f

Dec 19 00:09:06 sv1.blue.int-design.jp systemd[1]: Starting Authenticated Receive Chain (ARC) Milter...
Dec 19 00:09:06 sv1.blue.int-design.jp systemd[1]: Started Authenticated Receive Chain (ARC) Milter.
Dec 19 00:09:06 sv1.blue.int-design.jp openarc[123135]: OpenARC Filter: Opening listen socket on conn inet:8892@localhost
Dec 19 00:09:06 sv1.blue.int-design.jp openarc[123135]: OpenARC Filter v1.0.0 starting (args: -f

SPF (Sender Policy Framework) の設定

SPF (Sender Policy Framework) の導入は、DNSにSPFレコードを記述するだけです。

SPF (Sender Policy Framework)の書式

SPFの目的は、電子メールアドレスのなりすましやスパム(特にphishing)を防ぐことです。これは、送信者ドメインのDNSレコードに、対応するIPアドレスまたは送信サーバーの識別子を含む「SPFレコード」を作成することで実現されます。

例えば、ドメインexample.com のSPFレコードは以下のようになることがあります。

example.com. IN TXT "v=spf1 ip4:192.168.0.1 include:_spf.example.net -all"
example.com. IN TXT "v=spf1 ip4:192.168.0.0/24 ip6:2001:db8::/32 -all"

このレコードでは、次のようなルールが定義されています。

  • v=spf1: SPFプロトコルのバージョンを示す。
  • ip4:192.168.0.1/24example.comからのメールを送信できるIPv4サブネットを示す。
  • ip6:2001:db8::/32example.comからのメールを送信できるIPv6 アドレスの範囲(この場合は 2001:db8:: から 2001:db8:0:ffff:ffff:ffff:ffff:ffff まで)
  • include:_spf.example.netexample.comのSPFルールに、_spf.example.netドメインのSPFルールを追加する。
  • -all: SPFレコードで許可されていないすべての送信元に対して、メールを拒否することを示す。

ip4 と ip6 を誤って ipv4 ipv6 と記述しないように注意してください。

SPFレコードの -all と ~all の違い

SPFレコードの -all と ~all は、受信側のメールサーバーがどのようにSPF検証が失敗したメールを扱うかに関する指示です。それぞれの違いは次のとおりです。

  • -all: ハードフェイル (Hard Fail)
    • SPF検証に失敗したメールは、明確に拒否されます。これは、非常に厳格なポリシーであり、ドメインから送信されることが許可されていないすべてのメールがリジェクトされることを意味します。これにより、正規の送信元以外からのメールがブロックされる可能性が高くなりますが、誤った設定や変更によって正当なメールも拒否されるリスクがあります。
  • ~all: ソフトフェイル (Soft Fail)
    • SPF検証に失敗したメールは、注意喚起の対象としてマークされますが、通常は受信サーバーに届きます。これは、検証に問題があった場合でもメールが配信されることを許容し、特にSPFポリシーのテストや移行が行われている際に役立ちます。ただし、ソフトフェイルでは不正なメールのブロックが緩やかになるため、スパム対策としては -all に比べて効果が低い場合があります。

どちらのオプションを使用するかは、ドメイン管理者がセキュリティポリシーと通信要件に基づいて決定すべきです。厳格なスパム対策が重要であれば -all を、柔軟性や誤検知リスクの軽減が優先される場合は ~all を選択することが一般的です。

受信サーバーは、このSPFレコードを使用して、電子メールが許可されたサーバーから送信されたかどうかを検証します。検証が成功した場合(「パス」)、メールは通常どおり処理されます。失敗した場合(「フェイル」「ソフトフェイル」「ニュートラル」など)、受信サーバーは設定に応じてメールをリジェクト、受信、または別の扱いを行います。

SPFは単独では完全なセキュリティソリューションとはなりませんが、他の電子メール認証プロトコル(例:DKIM、DMARC)と組み合わせることで、効果的な電子メールセキュリティ戦術の一部となります。

SRS (Sender Rewriting Scheme)の設定

SRS (Sender Rewriting Scheme)、電子メール転送中に送信者のアドレスを書き換える方法です。SRSは主に2つの目的で使用されます。

  • SPF (Sender Policy Framework) を通過するため
  • 送信元ドメインの認証が失敗した場合のバウンスメッセージ(エラーメッセージ)を正確に処理するため

SRSの導入は必須ではありません。必要に応じて導入します。
SRSの導入は慎重に検討してください。
自身のサーバーで運用しているドメインであれば SRS_EXCLUDE_DOMAINS に追加することで書き換えされなくなります。
※以下のred.int-design.jpは、書き換えテストのため追加していません。

SRSでは転送メールなどのSPF認証を回避するために、Return-Path:From: が書き換えられます。
SRSにより、ドメインを red…をblue…に書き換えてますという意味です。

SRSに対応したサーバーやメーラーであれば、Fromが正しく表示されますが、そうでない場合は一見して送信者がわからない表示となります。GMailであれば表示は、以下のような表示ですが、そのまま返信しても問題ありません。
受信者が混乱しないように、SRSを導入する場合は書き換えの仕組みなどの事前説明が必要です。
SPFがPASSしなくてもDKIMがPASSできれば、GMailにもメールは届きますので受信者に不安がある場合は、使用しない選択肢もあります。

Return-Path:
From:
conagi@red.int-design.jp                  
送信時(SRS書き換え前)

Return-Path:
From:
SRS0=Ym/8=H7=red.int-design.jp=conagi@blue.int-design.jp
受信時(SRS書き換え後)

postsrsdの設定

/etc/default/postsrsd 設定ファイルを編集し、必要な設定を行います。
※環境によっては/etc/sysconfig/postsrsdかも

sudo vi /etc/default/postsrsd

以下のように変更して保存してください(ドメイン名とシークレットキーサイズを更新して適切な値に置き換える必要があります)

SRS_DOMAIN=blue.int-design.jp

#VirtualDomain運用の場合、/etc/default/excluded_domainsに全てのドメインを追加
SRS_EXCLUDE_DOMAINS="$(cat /etc/default/excluded_domains)"

CHROOT=/var/spool/postsrsd

RUN_AS=postsrsd

SRS_SECRET_LENGTH=24

VirtualDomain運用の場合、/etc/default/excluded_domainsに全てのドメインを追加します。
追加してないドメインは Return-Path: 同様に From:ヘッダーが書き換えられてしまいます。
SRS_EXCLUDE_DOMAINSに追加してもReturn-Path:は期待通り書き換えしてくれます。

SPF, DMARCは、From:のドメインで検証するため、全てのドメインにSPF, DMARCレコードを正しく登録しておく必要があります。

sudo vi /etc/default/excluded_domains

自身のメールサーバーのドメインは除外します。

blue.int-design.jp

CHROOT オプション

PostSRSd の chroot ディレクトリーを設定する際には、一般的に /var/spool/postsrsd をおすすめします。セキュリティと管理の観点から、このディレクトリーは専用のユーザーとグループが所有していることが望ましいです。
以下に、PostSRSd の chroot 環境を構築する手順を示します。

専用ユーザーとグループを作成

sudo groupadd -r postsrsd
sudo useradd -r -g postsrsd -d /var/spool/postsrsd -s /sbin/nologin postsrsd

ディレクトリと権限を設定

sudo mkdir -p /var/spool/postsrsd
sudo chown -R postsrsd:postsrsd /var/spool/postsrsd
sudo chmod 0750 /var/spool/postsrsd

Dovecot の設定

この記事ではSieveは省略しています。

mailuser アカウントを作成

mailuserというユーザーを作成し、uidを10000、gidを10000、ホームディレクトリを/home/mailuser、シェルを/sbin/nologinに設定します。
このユーザーのホームディレクトリに、VurtualDomain毎のメールスプールが作成されます。

sudo groupadd -g 10000 mailuser
sudo useradd -u 10000 -g 10000 -d /home/mailuser -s /sbin/nologin mailuser

/etc/dovecot/rc.local 全変更内容まとめ

conf.d 内の 設定ファイルを個々に書き換えるより rc.local に変更をまとめたほうが管理しやすいと思います。
設定内容は、個々の環境に合わせて変更してください。

auth_debug_passwords = no
auth_verbose = no
auth_debug = no

listen = *

###from 10-auth.conf
#ここの環境にあわせて
disable_plaintext_auth = no
auth_mechanisms = CRAM-MD5 login plain
#auth_mechanisms = plain login

###from 10-mail.conf
mail_location = maildir:/home/mailuser/%d/%n/Maildir
#mail_location = maildir:~/Maildir

mail_uid = mailuser
mail_gid = mailuser
mail_privileged_group = mailuser
first_valid_uid = 10000
first_valid_gid = 10000
#mail_plugins=$mail_plugins quota imap_quota

###from 10-ssl.conf
ssl = yes
ssl_cert = </usr/local/ssl/example.net.fullchain
ssl_key = </usr/local/ssl/example.net.key
#ssl_ca = </usr/local/ssl/example.net.ca

#複数ドメイン対応する場合は列挙する
local_name example.com {
  ssl_cert = </usr/local/ssl/example.com.fullchain
  ssl_key = </usr/local/ssl/example.com.key
}

ssl_dh = </etc/dovecot/dh.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = !SHA1:!SHA256:!SHA384:!SSLv3:!DSS:AESGCM+ECDHE:AESGCM+EDH
ssl_prefer_server_ciphers = yes

###from 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
    group = postfix
    user = postfix
  }
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
#   unix_listener auth-userdb {
#     mode = 0600
#     user = mailuser
#     group = mailuser
#   }
  user = dovecot
}

service auth-worker {
  user = mailuser
}
#service managesieve-login {
#  inet_listener sieve {
#    port = 4190
#  }
#}

###from auth-sql.conf.ext
protocol imap {
 imap_client_workarounds = delay-newmail tb-extra-mailbox-sep
#  mail_plugins = $mail_plugins imap_quota
}
protocol pop3 {
  pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }
}

###from 15-lda.conf
#protocol lda {
#  # Space separated list of plugins to load (default is global mail_plugins).
#  #mail_plugins = $mail_plugins
#  mail_plugins = $mail_plugins sieve
#}

###from 20-managesieve.conf
#protocol sieve {
#  protocols = $protocols sieve
#}

###from 20-lmtp.conf
protocol lmtp {
  mail_plugins = $mail_plugins sieve
}

###from 90-sieve.conf
#plugin {
#  sieve = /home/mailuser/%d/%n/.dovecot.sieve
#  sieve_dir = /home/mailuser/%d/%n/sieve
#  sieve_user_log = /home/mailuser/%d/%n/.dovecot.sieve.log
#}

/etc/dovecot/dovecot.conf

Dovecotの設定 /etc/dovecot/dovecot.conf を開きます。

sudo vi /etc/dovecot/dovecot.conf

以下の行を追加してください。

protocols = imap lmtp pop3 sieve
listen = *

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

/etc/dovecot/conf.d/10-mail.conf を開きます。

sudo vi /etc/dovecot/conf.d/10-mail.conf

以下の行を変更または追加してください。

mail_location = maildir:/home/mailuser/%d/%n/Maildir
#mail_location = maildir:~/Maildir

mail_uid = mailuser
mail_gid = mailuser
mail_privileged_group = mailuser
first_valid_uid = 10000
first_valid_gid = 10000
#mail_plugins=$mail_plugins quota imap_quota

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

/etc/dovecot/conf.d/10-auth.conf を開いて、以下の行を変更します。

sudo vi /etc/dovecot/conf.d/10-auth.conf
##どちらでもお好みで
##disable_plaintext_auth = yes
disable_plaintext_auth = no

auth_mechanisms = CRAM-MD5 login plain

#コメントアウト
#!include auth-system.conf.ext

#コメントアウト解除
!include auth-sql.conf.ext

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

/etc/dovecot/conf.d/10-ssl.conf を開いて、以下のように変更します。

sudo vi /etc/dovecot/conf.d/10-ssl.conf

サーバー証明書は、VirtualDomain 毎に設定できます。
証明書関係の設定は、環境にあわせて適宜変更してください。

#証明書を必須としない場合は
#ssl = required

ssl = yes
ssl_cert = </etc/letsencrypt/live/example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/example.com/privkey.pem
#ssl_ca = </etc/letsencrypt/live/example.com/chain.pem 

local_name mail.example.net {
  ssl_cert = </etc/letsencrypt/live/example.net/fullchain.pem
  ssl_key = </etc/letsencrypt/live/example.net/privkey.pem
}
local_name mail.xxxxxx.net {
  ssl_cert = </etc/letsencrypt/live/xxxxxx.net/fullchain.pem
  ssl_key = </etc/letsencrypt/live/xxxxxx.net/privkey.pem
}

#/etc/dovecot/dh.pemはこの後の手順により作成します。
ssl_dh = </etc/dovecot/dh.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = !SHA1:!SHA256:!SHA384:!SSLv3:!DSS:AESGCM+ECDHE:AESGCM+EDH
ssl_prefer_server_ciphers = yes

dh.pemファイルの作成

Dovecotで使用するdh.pemファイルは、Diffie-Hellman(DH)鍵交換のパラメータが含まれています。これは暗号化された通信を行う際に、安全な共有鍵を生成するために使用されます。dh.pemファイルを作成してDovecotに設定する方法は次のとおりです。

OpenSSLツールを利用して、適切な長さ(2048ビット以上が推奨されます)のDHパラメータを生成します。以下のコマンドを実行してください。

sudo openssl dhparam -out /etc/dovecot/dh.pem 2048

このコマンドは、2048ビットのDHパラメータを生成し、/etc/dovecot/dh.pemに保存します。4096ビットのように長いキーを生成するとセキュリティが向上しますが、計算時間が増えるため、ここでは2048ビットのキーを生成しています。

生成したdh.pemファイルのパーミッションを、dovecotのみが参照できるように設定します。

##sudo chmod 600 /etc/dovecot/dh.pem
sudo chmod 644 /etc/dovecot/dh.pem
sudo chown root:root /etc/dovecot/dh.pem

/etc/dovecot/conf.d/auth-sql.conf.ext

sudo vi /etc/dovecot/conf.d/auth-sql.conf.ext
protocol imap {
 imap_client_workarounds = delay-newmail tb-extra-mailbox-sep
#  mail_plugins = $mail_plugins imap_quota
}
protocol pop3 {
  pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }
}

/etc/dovecot/dovecot.conf

sudo vi /etc/dovecot/dovecot.conf 
service stats {
  unix_listener stats-reader {
    group = apache
    mode = 0660
  }
  unix_listener stats-writer {
    group = apache
    mode = 0660
  }
}

phpをapacheグループで実行しているので、stats-writer ソケットのアクセス権をそのグループに与えます。

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

MariaDBと連携して認証するための SQLの設定を作成します。

sudo vi /etc/dovecot/dovecot-sql.conf.ext
driver = mysql
#パスワードを平文であえて保存したい場合はCRAM-MD5をPLAINにする
default_pass_scheme = CRAM-MD5
connect = host=/var/lib/mysql/mysql.sock dbname=postfix user=postfix password=ここにパスワード
password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT concat('/home/mailuser/', maildir) as home, 10000 as uid, 10000 as gid FROM mailbox WHERE username = '%u' AND active = '1'
iterate_query = SELECT userid AS username, domain FROM users

/etc/dovecot/conf.d/15-lda.conf

/etc/dovecot/conf.d/15-lda.conf を開いて、以下のようにコメントアウトします。

sudo vi /etc/dovecot/conf.d/15-lda.conf
#protocol lda {
#  # Space separated list of plugins to load (default is global mail_plugins).
#  #mail_plugins = $mail_plugins
#  mail_plugins = $mail_plugins sieve
#}

/etc/dovecot/conf.d/20-managesieve.conf

/etc/dovecot/conf.d/20-managesieve.conf を開いて、以下のようにコメントアウトします。

sudo vi /etc/dovecot/conf.d/20-managesieve.conf
#protocol sieve {
#  protocols = $protocols sieve
#}

/etc/dovecot/conf.d/20-lmtp.conf

/etc/dovecot/conf.d/20-lmtp.conf を開いて、以下のように変更します。

sudo vi /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp {
  mail_plugins = $mail_plugins sieve
}

/etc/dovecot/conf.d/90-sieve.conf

/etc/dovecot/conf.d/90-sieve.conf を開いて、以下のようにコメントアウトします。

sudo vi /etc/dovecot/conf.d/90-sieve.conf
#plugin {
#  sieve = /home/mailuser/%d/%n/.dovecot.sieve
#  sieve_dir = /home/mailuser/%d/%n/sieve
#  sieve_user_log = /home/mailuser/%d/%n/.dovecot.sieve.log
#}

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

sudo vi /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
    group = postfix
    user = postfix
  }
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
#   unix_listener auth-userdb {
#     mode = 0600
#     user = mailuser
#     group = mailuser
#   }
  user = dovecot
}
service auth-worker {
  user = mailuser
}

設定が完了したら、Dovecotを再起動します。

sudo systemctl restart dovecot
sudo systemctl enable dovecot

/etc/dovecot/conf.d/10-logging.conf

/etc/dovecot/conf.d/10-logging.conf を変更してDebug用のログを出力することもできます。

sudo vi /etc/dovecot/conf.d/10-logging.conf
#auth_debug_passwords = no
#auth_verbose = no
#auth_debug = no

auth_debug_passwords = yes
auth_verbose = yes
auth_debug = yes
log_path = /var/log/dovecot.log

Postfix の設定

/etc/postfix/main.cf の設定

現在の設定は以下のようになっています。

grep -v "^#" /etc/postfix/main.cf

compatibility_level = 2
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix

mail_owner = postfix

myhostname = sv1.blue.int-design.jp
mydomain = blue.int-design.jp
myorigin = $myhostname

inet_interfaces = all
inet_protocols = ipv4

mydestination = $myhostname, localhost.$mydomain, localhost

unknown_local_recipient_reject_code = 550

mynetworks = 127.0.0.0/8

alias_maps = hash:/etc/aliases,proxy:mysql:/etc/postfix/mysql_alias_maps.cf

alias_database = hash:/etc/aliases

home_mailbox = Maildir/
 
mailbox_command = /usr/libexec/dovecot/deliver
allow_mail_to_commands = alias,forward,include

debug_peer_level = 2

debugger_command =
	 PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
	 ddd $daemon_directory/$process_name $process_id & sleep 5

sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix/samples
readme_directory = /usr/share/doc/postfix/README_FILES

## Let's Encryptの証明書を使用しています。
smtpd_tls_cert_file = /etc/letsencrypt/live/blue.int-design.jp/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/blue.int-design.jp/privkey.pem
smtpd_tls_security_level = may
smtp_tls_CApath = /etc/pki/tls/certs
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt

smtp_tls_security_level = may
meta_directory = /etc/postfix
shlib_directory = /usr/lib64/postfix

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $mydomain
smtpd_client_restrictions = reject_rbl_client bl.spamcop.net,
        reject_rbl_client cbl.abuseat.org,
        reject_rbl_client truncate.gbudb.net,
        check_client_access hash:/etc/postfix/reject_client,
        permit
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes


tls_server_sni_maps=hash:/etc/postfix/tls_server_sni_maps
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_base = /home/mailuser
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 10000
virtual_uid_maps = static:10000
virtual_gid_maps = static:10000
virtual_mailbox_limit = 0


smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_received_header = yes
smtpd_tls_loglevel = 0


milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891,inet:localhost:8892,inet:localhost:8893
non_smtpd_milters = inet:localhost:8891,inet:localhost:8892,inet:localhost:8893

recipient_canonical_maps = tcp:localhost:10002

header_checks=regexp:/etc/postfix/header_checks

主な設定カ所は以下の通りです。

sudo vi /etc/postfix/main.cf
## myhostname に設定するホスト名は Linux のホスト名に設定されているか確認してください。
## myhostnameとmydomainに同じものを設定しないようにします。
myhostname = sv1.blue.int-design.jp
mydomain = blue.int-design.jp
inet_interfaces = all
inet_protocols = ipv4
##mydestination = $myhostname, localhost.$mydomain, localhost
mydestination =
mynetworks = 127.0.0.0/8
home_mailbox = Maildir/

####mailbox_command = /usr/libexec/dovecot/deliver
## 追加
allow_mail_to_commands = alias,forward,include

# Let's Encrypt証明書などを指定する
##smtpd_tls_cert_file = /etc/letsencrypt/live/blue.int-design.jp/fullchain.pem
##smtpd_tls_key_file = /etc/letsencrypt/live/blue.int-design.jp/privkey.pem

smtpd_tls_cert_file = /etc/pki/tls/certs/blue.int-design.jp.crt
smtpd_tls_key_file = /etc/pki/tls/private/blue.int-design.jp.key

# 追加
#
### SMTP-Auth
#
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $mydomain
smtpd_client_restrictions = reject_rbl_client bl.spamcop.net,
        reject_rbl_client cbl.abuseat.org,
        reject_rbl_client truncate.gbudb.net,
        check_client_access hash:/etc/postfix/reject_client,
        permit
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes

#
### Virtual Domains
#
tls_server_sni_maps=hash:/etc/postfix/tls_server_sni_maps
##local_transport = virtual
##virtual_transport = virtual
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_base = /home/mailuser
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
##virtual_alias_domains = $virtual_alias_maps
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 10000
virtual_uid_maps = static:10000
virtual_gid_maps = static:10000
# Mailbox limit(クォーターの設定はなし)
##virtual_mailbox_limit = 0

#
### SSL/TLS Settings
#
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_received_header = yes
smtpd_tls_loglevel = 0

#
# OpenDKIM:8891 & OpenARC:8892 & OpenDMARC:8893 
#
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891,inet:localhost:8892,inet:localhost:8893
non_smtpd_milters = inet:localhost:8891,inet:localhost:8892,inet:localhost:8893

#
### SRS (Sender Rewriting Scheme)
# SRSを無効にする場合は、sender_canonical_mapsをコメントアウト
sender_canonical_maps = hash:/etc/postfix/canonical,tcp:localhost:10001
recipient_canonical_maps = tcp:localhost:10002

#
### その他
#
#disable_vrfy_command = yes
#sender_canonical_maps = hash:/etc/postfix/canonical

/etc/postfix/master.cf の設定

現在の設定は以下のようになっています。

grep -v "^#" /etc/postfix/master.cf

smtp      inet  n       -       n       -       -       smtpd
submission inet n       -       n       -       -       smtpd
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
relay     unix  -       -       n       -       -       smtp
        -o syslog_name=postfix/$service_name
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache
postlog   unix-dgram n  -       n       -       1       postlogd

主な設定カ所は、以下の通りです。

sudo vi /etc/postfix/master.cf
submission inet n       -       n       -       -       smtpd
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject

/etc/postfix/mysql_virtual_domains_maps.cf

Postfixメールサーバーが仮想ドメインとメールボックスを管理するためにMySQLデータベースとの連携を設定するためのファイルです。
このファイルに記述される設定は、PostfixがMySQLデータベースから仮想ドメイン情報を取得する方法を指定します。具体的な設定項目は以下の通りです。

sudo vi /etc/postfix/mysql_virtual_domains_maps.cf 
user = postfix
password = ここにパスワード
dbname = postfix
hosts = localhost
table = domain
# query = SELECT domain FROM domain WHERE domain='%s'
select_field = domain
where_field = domain
additional_conditions = and active = '1'

/etc/postfix/mysql_virtual_alias_maps.cf の設定

Postfixの仮想エイリアスマップを構成するための設定ファイルです。このファイルでは、MySQLデータベースと接続する方法、およびエイリアスの情報を取得するためのクエリが定義されています。

sudo vi /etc/postfix/mysql_virtual_alias_maps.cf
user = postfix
password = [パスワード]
dbname = postfix
hosts = localhost
#query = SELECT goto as address FROM virtual_aliases WHERE address=_utf8'%s'
table = alias
select_field = goto
where_field = address

/etc/postfix/mysql_virtual_mailbox_maps.cf の設定

Postfixの仮想メールボックスマップを構成するための設定ファイルです。このファイルでは、MySQLデータベースと接続する方法および仮想メールボックス情報を取得するためのクエリが定義されています。

sudo vi /etc/postfix/mysql_virtual_mailbox_maps.cf
user = postfix
password = [パスワード]
hosts = localhost
dbname = postfix
table = mailbox
select_field = maildir
where_field = username

tls_server_sni_maps.db

tls_server_sni_maps は、Postfix メールサーバーでTLS(Transport Layer Security)を使用する際に、SNI(Server Name Indication)を利用して動的に接続先サーバの証明書を選択するための設定です。

/etc/postfix/tls_server_sni_maps を作成し、ドメイン毎に使用する証明書と秘密鍵のパスを設定します。

sudo vi /etc/postfix/tls_server_sni_maps
blue.int-design.jp /etc/letsencrypt/live/blue.int-design.jp/fullchain.pem /etc/letsencrypt/live/blue.int-design.jp/privkey.pem 
blredue.int-design.jp /etc/letsencrypt/live/red.int-design.jp/fullchain.pem /etc/letsencrypt/live/red.int-design.jp/privkey.pem 
green.int-design.jp /etc/letsencrypt/live/green.int-design.jp/fullchain.pem /etc/letsencrypt/live/green.int-design.jp/privkey.pem 

設定ファイルからHash形式のデータベースを生成します。
-Fオプションを付けてBase64で保存します。

sudo postmap -F /etc/postfix/tls_server_sni_maps
#空ファイル
touch /etc/postfix/reject_client

sudo postmap /etc/postfix/canonical
sudo postmap /etc/postfix/reject_client
sudo postmap /etc/postfix/virtual

設定が完了したら、Postfixを起動します。
postfix check でPostfixの設定の文法上の誤りがないか確認できます。

sudo postfix check

sudo systemctl enable postfix
sudo systemctl start postfix

sudo systemctl restart postfix
systemctl status postfix

● postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/usr/lib/systemd/system/postfix.service; enabled; preset: disabled)
     Active: active (running) since Tue 2023-12-19 12:28:12 JST; 1s ago
    Process: 130719 ExecStartPre=/usr/sbin/restorecon -R /var/spool/postfix/pid (code=exited, status=0/SUCCESS)
    Process: 130722 ExecStartPre=/usr/libexec/postfix/aliasesdb (code=exited, status=0/SUCCESS)
    Process: 130724 ExecStartPre=/usr/libexec/postfix/chroot-update (code=exited, status=0/SUCCESS)
    Process: 130725 ExecStart=/usr/sbin/postfix start (code=exited, status=0/SUCCESS)
   Main PID: 130793 (master)
      Tasks: 3 (limit: 11135)
     Memory: 3.1M
        CPU: 263ms
     CGroup: /system.slice/postfix.service
             ├─130793 /usr/libexec/postfix/master -w
             ├─130794 pickup -l -t unix -u
             └─130795 qmgr -l -t unix -u

Dec 19 12:28:12 sv1.blue.int-design.jp systemd[1]: Starting Postfix Mail Transport Agent...
Dec 19 12:28:12 sv1.blue.int-design.jp postfix/postfix-script[130791]: starting the Postfix mail system
Dec 19 12:28:12 sv1.blue.int-design.jp postfix/master[130793]: daemon started -- version 3.5.9, configuration /etc/postfix
Dec 19 12:28:12 sv1.blue.int-design.jp systemd[1]: Started Postfix Mail Transport Agent.

Postfix をMySQL(MariaDB)で管理するために

MariaDBにログインし、データベースとユーザーを作成します。

mysql -u root -p
CREATE DATABASE postfix;
GRANT ALL PRIVILEGES ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'ここにパスワード';
FLUSH PRIVILEGES;

必要なテーブルなどは自分で作成する必要がありますが、PostfixAdmin をインストールすれば、これらを自動作成されます。PostfixAdminを使用しない場合は、以下のSQLで同等のデータベースを作成できます。

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";

--
-- データベース: `postfix`
--

-- --------------------------------------------------------

--
-- テーブルの構造 `admin`
--

CREATE TABLE `admin` (
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `modified` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1,
  `superadmin` tinyint(1) NOT NULL DEFAULT 0,
  `phone` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `email_other` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `token` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `token_validity` datetime NOT NULL DEFAULT '2000-01-01 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Virtual Admins';

-- --------------------------------------------------------

--
-- テーブルの構造 `alias`
--

CREATE TABLE `alias` (
  `address` varchar(255) NOT NULL,
  `goto` text NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `modified` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Virtual Aliases';

-- --------------------------------------------------------

--
-- テーブルの構造 `alias_domain`
--

CREATE TABLE `alias_domain` (
  `alias_domain` varchar(255) NOT NULL DEFAULT '',
  `target_domain` varchar(255) NOT NULL DEFAULT '',
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `modified` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Domain Aliases';

-- --------------------------------------------------------

--
-- テーブルの構造 `config`
--

CREATE TABLE `config` (
  `id` int(11) NOT NULL,
  `name` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `value` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='PostfixAdmin settings';

--
-- テーブルのデータのダンプ `config`
--

INSERT INTO `config` (`id`, `name`, `value`) VALUES
(1, 'version', '1843');

-- --------------------------------------------------------

--
-- テーブルの構造 `domain`
--

CREATE TABLE `domain` (
  `domain` varchar(255) NOT NULL,
  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `aliases` int(10) NOT NULL DEFAULT 0,
  `mailboxes` int(10) NOT NULL DEFAULT 0,
  `maxquota` bigint(20) NOT NULL DEFAULT 0,
  `quota` bigint(20) NOT NULL DEFAULT 0,
  `transport` varchar(255) NOT NULL,
  `backupmx` tinyint(1) NOT NULL DEFAULT 0,
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `modified` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1,
  `password_expiry` int(11) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Virtual Domains';

-- --------------------------------------------------------

--
-- テーブルの構造 `domain_admins`
--

CREATE TABLE `domain_admins` (
  `username` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Domain Admins';

-- --------------------------------------------------------

--
-- テーブルの構造 `fetchmail`
--

CREATE TABLE `fetchmail` (
  `id` int(11) UNSIGNED NOT NULL,
  `mailbox` varchar(255) NOT NULL,
  `src_server` varchar(255) NOT NULL,
  `src_auth` enum('password','kerberos_v5','kerberos','kerberos_v4','gssapi','cram-md5','otp','ntlm','msn','ssh','any') CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,
  `src_user` varchar(255) NOT NULL,
  `src_password` varchar(255) NOT NULL,
  `src_folder` varchar(255) NOT NULL,
  `poll_time` int(11) UNSIGNED NOT NULL DEFAULT 10,
  `fetchall` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
  `keep` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
  `protocol` enum('POP3','IMAP','POP2','ETRN','AUTO') CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,
  `usessl` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
  `extra_options` text DEFAULT NULL,
  `returned_text` text DEFAULT NULL,
  `mda` varchar(255) NOT NULL,
  `date` timestamp NOT NULL DEFAULT '1999-12-31 15:00:00',
  `sslcertck` tinyint(1) NOT NULL DEFAULT 0,
  `sslcertpath` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '',
  `sslfingerprint` varchar(255) DEFAULT '',
  `domain` varchar(255) DEFAULT '',
  `active` tinyint(1) NOT NULL DEFAULT 0,
  `created` timestamp NOT NULL DEFAULT '1999-12-31 15:00:00',
  `modified` timestamp NOT NULL DEFAULT current_timestamp(),
  `src_port` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

-- --------------------------------------------------------

--
-- テーブルの構造 `log`
--

CREATE TABLE `log` (
  `timestamp` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `username` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `action` varchar(255) NOT NULL,
  `data` text NOT NULL,
  `id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Log';

-- --------------------------------------------------------

--
-- テーブルの構造 `mailbox`
--

CREATE TABLE `mailbox` (
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `maildir` varchar(255) NOT NULL,
  `quota` bigint(20) NOT NULL DEFAULT 0,
  `local_part` varchar(255) NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `modified` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1,
  `phone` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `email_other` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `token` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `token_validity` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `password_expiry` datetime NOT NULL DEFAULT '2000-01-01 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Virtual Mailboxes';

-- --------------------------------------------------------

--
-- テーブルの構造 `quota`
--

CREATE TABLE `quota` (
  `username` varchar(255) NOT NULL,
  `path` varchar(100) NOT NULL,
  `current` bigint(20) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

-- --------------------------------------------------------

--
-- テーブルの構造 `quota2`
--

CREATE TABLE `quota2` (
  `username` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
  `bytes` bigint(20) NOT NULL DEFAULT 0,
  `messages` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

-- --------------------------------------------------------

--
-- テーブルの構造 `vacation`
--

CREATE TABLE `vacation` (
  `email` varchar(255) NOT NULL,
  `subject` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `body` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `cache` text NOT NULL,
  `domain` varchar(255) NOT NULL,
  `created` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT 1,
  `modified` timestamp NOT NULL DEFAULT current_timestamp(),
  `activefrom` timestamp NOT NULL DEFAULT '1999-12-31 15:00:00',
  `activeuntil` timestamp NOT NULL DEFAULT '2038-01-17 15:00:00',
  `interval_time` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci COMMENT='Postfix Admin - Virtual Vacation';

-- --------------------------------------------------------

--
-- テーブルの構造 `vacation_notification`
--

CREATE TABLE `vacation_notification` (
  `on_vacation` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
  `notified` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `notified_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='Postfix Admin - Virtual Vacation Notifications';

--
-- ダンプしたテーブルのインデックス
--

--
-- テーブルのインデックス `admin`
--
ALTER TABLE `admin`
  ADD PRIMARY KEY (`username`);

--
-- テーブルのインデックス `alias`
--
ALTER TABLE `alias`
  ADD PRIMARY KEY (`address`),
  ADD KEY `domain` (`domain`);

--
-- テーブルのインデックス `alias_domain`
--
ALTER TABLE `alias_domain`
  ADD PRIMARY KEY (`alias_domain`),
  ADD KEY `active` (`active`),
  ADD KEY `target_domain` (`target_domain`);

--
-- テーブルのインデックス `config`
--
ALTER TABLE `config`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `name` (`name`);

--
-- テーブルのインデックス `domain`
--
ALTER TABLE `domain`
  ADD PRIMARY KEY (`domain`);

--
-- テーブルのインデックス `domain_admins`
--
ALTER TABLE `domain_admins`
  ADD KEY `username` (`username`);

--
-- テーブルのインデックス `fetchmail`
--
ALTER TABLE `fetchmail`
  ADD PRIMARY KEY (`id`);

--
-- テーブルのインデックス `log`
--
ALTER TABLE `log`
  ADD PRIMARY KEY (`id`),
  ADD KEY `timestamp` (`timestamp`),
  ADD KEY `domain_timestamp` (`domain`,`timestamp`);

--
-- テーブルのインデックス `mailbox`
--
ALTER TABLE `mailbox`
  ADD PRIMARY KEY (`username`),
  ADD KEY `domain` (`domain`);

--
-- テーブルのインデックス `quota`
--
ALTER TABLE `quota`
  ADD PRIMARY KEY (`username`,`path`);

--
-- テーブルのインデックス `quota2`
--
ALTER TABLE `quota2`
  ADD PRIMARY KEY (`username`);

--
-- テーブルのインデックス `vacation`
--
ALTER TABLE `vacation`
  ADD PRIMARY KEY (`email`),
  ADD KEY `email` (`email`);

--
-- テーブルのインデックス `vacation_notification`
--
ALTER TABLE `vacation_notification`
  ADD PRIMARY KEY (`on_vacation`,`notified`);

--
-- ダンプしたテーブルの AUTO_INCREMENT
--

--
-- テーブルの AUTO_INCREMENT `config`
--
ALTER TABLE `config`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

--
-- テーブルの AUTO_INCREMENT `fetchmail`
--
ALTER TABLE `fetchmail`
  MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;

--
-- テーブルの AUTO_INCREMENT `log`
--
ALTER TABLE `log`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- ダンプしたテーブルの制約
--

--
-- テーブルの制約 `vacation_notification`
--
ALTER TABLE `vacation_notification`
  ADD CONSTRAINT `vacation_notification_pkey` FOREIGN KEY (`on_vacation`) REFERENCES `vacation` (`email`) ON DELETE CASCADE;
COMMIT;

運用を便利にするツールなど

PostfixAdmin の導入

MySQL(MariaDB)のpostfixデータベースに必要な情報を登録すればメールサーバーとして運用できますが、ドメインやメールアドレスの追加、削除などを簡単にできるように、PostfixAdminなどを導入します。

必要なパッケージのインストール

sudo yum install wget unzip php-mbstring

PostfixAdminのダウンロード

設置場所はご自身のWebサーバーにあわせて変更してください。

cd /var/www
wget https://sourceforge.net/projects/postfixadmin/files/postfixadmin-3.3.8/PostfixAdmin%203.3.8.tar.gz
tar zxvf 'PostfixAdmin 3.3.8.tar.gz'
rm 'PostfixAdmin 3.3.8.tar.gz'

sudo mv postfixadmin-postfixadmin-7d04685 postfixadmin

config.local.php (config.inc.php) ファイルの設定

デフォルトの設定ファイルconfig.inc.phpがあり、それをconfig.local.phpで設定を上書きするようになっています。変更内容は、config.local.php まとめましょう。

Postfixadmin のセットアップ画面にログインするためのハッシュを設定しておきます。
セットアップのパスワードのhash はセットアップ画面で作成することもできます。
※パスワードは5文字以上で指定しないと警告が表示され使用できません。

cd /var/www/postfixadmin/
php -r "require_once('functions.inc.php'); echo password_hash('セットアップのパスワード', PASSWORD_DEFAULT) . PHP_EOL;"

#このようなhashが出力されます。
$2y$10$ftuBtmmgiYBN.RqakFt9W.zrNECBw5dO0WiAQ/Tm5.qhgbWgDVAsa
cd /var/www/postfixadmin/

sudo vi config.local.php

php のスクリプトなので、 <?php を忘れないようにつけます。

<?php

$CONF['configured'] = true;
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'ここにパスワード(MariaDB postfixユーザー))';
$CONF['database_name'] = 'postfix';

$CONF['alias_control'] = 'NO';
$CONF['setup_password'] = 'セットアップのパスワードのhash';

$CONF['encrypt'] = 'dovecot:CRAM-MD5';
$CONF['authlib_default_flavor'] = '';

$CONF['min_password_length'] = '4';

$CONF['maildir_name_hook'] = 'maildir_name_hook_custom';

function maildir_name_hook_custom($domain, $user) {
  preg_match("/^(.+)@[^@]+$/", $user, $matches);
  return $domain . '/' . $matches[1] . '/Maildir/';
}

$CONF['alias_control']の値をNOに変更し、転送メールエイリアスの自動作成を無効にします。
セットアップのパスワードのhash
 は $2y$10$ftuBtmmgiYBN.RqakFt9W.zrNECBw5dO0WiAQ/Tm5.qhgbWgDVAsa このような文字列でパスワードではないので注意してください。

Apache の設定ファイル(postfixadmin.conf)を作成

Apacheの設定ファイルにPostfixAdmin用のディレクティブを追加します。
エイリアス等の設定を行います。

sudo vi /etc/httpd/conf.d/postfixadmin.conf

以下の内容を追加してください。

Alias /postfixadmin /var/www/postfixadmin/public

<Directory "/var/www/postfixadmin/public">
    Require all granted
</Directory>

設定変更後、Apacheを再起動します。

sudo systemctl restart httpd

PostfixAdmin セットアップ画面

最後に、以下のURLにアクセスしてPostfixAdminをセットアップします。
先に設定したセットアップ画面用のパスワードでログインします。
※先にDovecotがインストールされていないとエラーがでます。

ERROR: the templates_c directory doesn't exist or isn't writeable for the webserver

このようなエラーがでますので、 INSTALL.TXTに従い templates_cフォルダを作成します。
Apacheで書き込めるように、Apacheのオーナーにするか、 chmod 0777 で書き込み権限を付けてください。

cd /var/www/postfixadmin/

mkdir -p templates_c
chown -R apache templates_c

その他によくあるエラーのトラブルシューティングの例です。
Errors (MUST be fixed)

  • ⛔Password Hashing – attempted to use configured encrypt backend (dovecot:CRAM-MD5) triggered an error: /usr/bin/doveadm pw failed, see error log for details
  • ⛔Possibly helpful error_log messages – [19-Dec-2023 04:50:29 UTC] Failed to read password from /usr/bin/doveadm pw … stderr: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 14: ssl_cert: Can’t open file /etc/pki/dovecot/certs/dovecot.pem: Permission denied
    , password:
    [19-Dec-2023 04:57:12 UTC] Failed to read password from /usr/bin/doveadm pw … stderr: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 14: ssl_cert: Can’t open file /etc/pki/dovecot/certs/dovecot.pem: Permission denied
  • ⛔You will have problems logging into PostfixAdmin.
  • ⛔Check out our Dovecot documentation at https://github.com/postfixadmin/postfixadmin/blob/master/DOCUMENTS/DOVECOT.txt, specifically around ‘3. Permissions’.

(dovecot:CRAM-MD5)のエラーでる場合は、doveadmコマンドに問題がない場合は、/run/dovecot/stats-writer のgroupがapache等に権限が無い等が考えられます。dovecotのconfで設定しない場合はデフォルトの dovecotになります。

service stats {
  unix_listener stats-reader {
    group = apache
    mode = 0660
  }
  unix_listener stats-writer {
    group = apache
    mode = 0660
  }
}

証明書のPermission deniedのエラーがでる場合は、Let’sEncryptがroot権限でしかアクセスできないような設定をしていますので、パーミッションを変更します。

最後に

OpenARC、OpenDKIM、OpenDMARC等の設定を変更したらPostfixも再起動させます。

sudo systemctl restart openarc
sudo systemctl restart opendkim
sudo systemctl restart opendmarc
sudo systemctl restart postfix

動作確認

GMailへの送信テストです。
直接GMailへメール送信、DKIM署名済みメールをGMailへ転送、DKIM未署名メールをGMailへ転送を行いSPF、DKIMにパスして問題なくメールが送信されることを確認します。

GMailへのメール送信テスト

メール ID<3f7b5baee45c3a3dfe9474830ec2b1b4@blue.int-design.jp>
作成日:2023年12月19日 23:11(2 秒後に配信済み)
From:conagi@blue.int-design.jp
To: ******@gmail.com>
件名:test
SPF:PASS(IP: 160.251.***.***)。詳細
DKIM:‘PASS’(ドメイン: blue.int-design.jp)詳細
DMARC:‘PASS’ 詳細

SPF、DKIM、DMARC全てPASSになります。

DKIM署名済みのメールの転送テスト

メール ID<6506be81e263806a88933bf4c3ee4c8a@conagi.jp>
作成日:2023年12月19日 22:55(6 秒後に配信済み)
From:こなぎインターネット <*****@conagi.jp>
To:conagi@blue.int-design.jp
件名:test
SPF:PASS(IP: 160.251.***.***)。詳細
DKIM:‘PASS’(ドメイン: conagi.jp)詳細

ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@blue.int-design.jp header.s=default header.b=vQh1Wt1l; dkim=pass header.i=@conagi.jp header.s=default header.b=kjoE8dP7; spf=pass (google.com: domain of srs0=3zjy=h6=conagi.jp=csr@blue.int-design.jp designates 160.251.***.*** as permitted sender) smtp.mailfrom=”SRS0=3zjy=H6=conagi.jp=csr@blue.int-design.jp”

Authentication-Results: mx.google.com; dkim=pass header.i=@blue.int-design.jp header.s=default header.b=vQh1Wt1l; dkim=pass header.i=@conagi.jp header.s=default header.b=kjoE8dP7; spf=pass (google.com: domain of srs0=3zjy=h6=conagi.jp=csr@blue.int-design.jp designates 160.251.***.*** as permitted sender) smtp.mailfrom=”SRS0=3zjy=H6=conagi.jp=csr@blue.int-design.jp”

ARCで転送メールの認証状況が伝搬されます。
SPFはSRSでpassさせています。

DKIM未署名のメールの転送テスト

受信したメールにDKIM署名がない場合は、転送サーバーでDKIM署名を行います。

メール ID<b6c66cf78b52a13f4c8ef8329934203a@example.com>
作成日:2023年12月19日 22:41(3 秒後に配信済み)
From:xxxx@example.com
To:conagi@blue.int-design.jp
件名:test
SPF:PASS(IP: 160.251.***.***)。詳細
DKIM:‘PASS’(ドメイン: blue.int-design.jp)詳細

DKIM署名がついていないので、強制的にDKIM再署名をします。
SPFはSRSでpassさせています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (6件)

コメントする

目次