ラベル Postfix の投稿を表示しています。 すべての投稿を表示
ラベル Postfix の投稿を表示しています。 すべての投稿を表示
2024年3月10日日曜日

PostfixにSPF検証機能を実装する

メールセキュリティの機能として知られるSPF検証は、迷惑メールなどの対策として、ほぼすべてのメールシステムで実装されている。

本記事では、PostfixにSPF検証機能を実装する手順を記載する。

環境

  • OS : AlmaLinux release 9.3
  • Postfix : 3.5.9
  • pypolicyd-spf : 2.9.3-4

導入手順

1. pypolicyd-spfをインストール

Postfixは単体ではSPF検証を行うことはできないので、pypolicyd-spfをdnfでインストールする。

# dnf install pypolicyd-spf -y

pypolicyd-spfの設定ファイルはシンプルな内容となっている。SPFレコードのチェックは、HELO時に記載されたドメインとMAIL FROMに記載されたドメインの2か所に対して実施し、受信拒否をすることができる。

今回はどちらもチェックさせるよう、そのままの設定とするが、受信拒否をさせたくない場合は、FailFalseに変更すればよい。また、このままでは内部から外部へメール送信時もSPFチェックがされてしまうので、ローカルのネットワークアドレスをskip_addressesに追加しておこう。

/etc/python-policyd-spf/policyd-spf.conf

#  For a fully commented sample config file see policyd-spf.conf.commented

debugLevel = 1
TestOnly = 1

HELO_reject = Fail
Mail_From_reject = Fail

PermError_reject = False
TempError_Defer = False

skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1,192.168.0.0/16

2. Postfixの設定

メール受信時にpolicyd-spfに渡すための設定を実施する。

/etc/postfix/master.cf

policyd-spf unix -      n       n       -       0       spawn
  user=nobody argv=/usr/libexec/postfix/policyd-spf

/etc/postfix/main.cf

smtpd_recipient_restrictions = check_policy_service unix:private/policyd-spf
policyd-spf_time_limit = 3600

設定後、Postfixのサービスを再起動し、設定を反映させる。

# systemctl restart postfix
# systemctl status postfix

3. 動作確認(SPF検証成功例)

実際にメールを受信した際に、SPF検証に成功している際のログを以下に記載する。

Mar 10 06:40:54 hoge policyd-spf[57430]: 
prepend Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=123.45.67.89; 
helo=mail-xxxx.google.com; envelope-from=hoge@gmail.com; receiver=<UNKNOWN>

通過したメールのヘッダーにもSPF検証がPassしている旨追記される。

4. 動作確認(SPF検証NGの例)

SPF検証がNGとなる場合は、HELOとMAIL FROMの場合で若干メッセージが異なるため、2パターンをそれぞれ記載する。

HELOのSPF検証NG

550 5.7.23 <tech-mmmm@hoge.tech-mmmm.com>: 
Recipient address rejected: Message rejected due to: SPF fail - not authorized. 
Please see http://www.openspf.net/Why?s=helo;id=example.com;ip=192.168.111.1;r=<UNKNOWN>

MAIL FROMのSPF検証NG

550 5.7.23 <tech-mmmm@hoge.tech-mmmm.com>: 
Recipient address rejected: Message rejected due to: SPF fail - not authorized. 
Please see http://www.openspf.net/Why?s=mfrom;id=from@hoge.tech-mmmm.com;ip=192.168.111.1;r=<UNKNOWN>

以上で、PostfixにSPF検証機能を実装する手順は完了となる。

更新履歴

  • 2024/3/10 新規作成
  • 2024/3/16 skip_addressesの記載を追記

2024年2月4日日曜日

Roundcubeでメール振り分け等のフィルター機能を有効にする

OSSのWebメールクライアントである「Roundcube」は、標準ではメール振り分けといったメールフィルターの機能を使用することができない。

Roundcubeはプラグインとして、機能を追加することができる。今回はRoundcubeにて「ManageSieve」のプラグインを有効化し、フィルター機能を利用できるようにする。

なお、ManageSieveを利用する際には、Dovecot PigeonholeをインストールしSieveスクリプトによるメール制御を行うことで、フィルター機能を実現することから、Postfix及びDovecot への設定追加が必要となる。

環境

Roundcubeのインストール手順は以下を参照いただきたい。

Roundcubeはあくまでもメールクライアントであるため、PostfixやDovecotによるメールサーバーの設定も必要となる。なお、今回は、バーチャルドメインのIMAPメールサーバーに対して設定を行っている。PostfixとDovecotの構築手順は以下を参照いただきたい。

構築環境としては以下となる。

  • OS : AlmaLinux 8.8
  • DB : MariaDB 10.3.35
  • Roundcube : 1.6.2
  • PHP : 7.4
  • Apache HTTP Server : 2.4.37
  • Postfix : 3.5.8
  • Dovecot : 2.3.16

Rondcubeフィルター有効化手順

1. Dovecot Pigeonholeをインストール

Dovecot Pigeonholeとは、メールの処理方法を定義する「Sieve」と呼ばれるスクリプト言語を用いてDovecot のメール配送処理を制御するためのソフトウェアとなる。

Dovecot Pigeonholeはdnfコマンドにてインストールできる。

dnf install dovecot-pigeonhole -y

2. Dovecot設定追加

Sieveを使えるようにするため、LDA (ローカル配送エージェント) 及びLMTP (Local Mail Transfer Protocol) の設定にsieveを追加する。

/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 sieve    # <- sieveを追加
}

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

protocol lmtp {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins sieve    # <- sieveを追加
}

Dovecotにて、ManageSieveと呼ばれるSieveのアップロード等を管理するための機能を有効化する。設定ファイルの前半のコメントアウトされている行をアンコメントし有効化する。

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

# Uncomment to enable managesieve protocol:
protocols = $protocols sieve

# Service definitions

service managesieve-login {
  inet_listener sieve {
    port = 4190
  }

  inet_listener sieve_deprecated {
    port = 2000
  }

  # Number of connections to handle before starting a new process. Typically
  # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
  # is faster. <doc/wiki/LoginProcess.txt>
  service_count = 1

  # Number of processes to always keep waiting for more connections.
  process_min_avail = 0

  # If you set service_count=0, you probably need to grow this.
  vsz_limit = 64M
}

Sieveのスクリプトファイル名は、デフォルトで.dovecot.sieveと隠しファイルになっているが、先頭に.が付いているとメールフォルダと誤認してしまう場合があるため、dovecot.sieveというファイル名に変更しておく。

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

plugin {
  sieve = file:~/sieve;active=~/dovecot.sieve
}

以上が完了したら、Dovecotのサービスを再起動させる。

# systemctl restart dovecot

3. Postfix設定追加

Dovecotのローカル配送エージェントであるdovecot-ldaにメール配送をできるよう、master.cfに以下設定を追加する。

userはバーチャルメールボックスで使用するユーザー、グループであるvmailを指定する。

/etc/postfix/master.cf

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}

設定したdovecot-ldaへメールを配送するよう、main.cfに以下設定を追加する。

/etc/postfix/main.cf

virtual_transport = dovecot

以上が完了したら、Postfixのサービスを再起動させる。

systemctl restart postfix

4. Roundcubeで「ManageSieve」のプラグインを有効化

以下の設定を追加する。なお、設定は即時に反映されるため、サービス等の再起動は不要となる。

/etc/roundcubemail/config.inc.php

$config['plugins'] = array('managesieve');

5. 動作確認

実際にRoundcubeにログインすると、「設定」画面に「フィルター」が表示されるようになっていることがわかる。

ここで動作確認のため、以下の通りフィルターを作成する。

  • フィルター名 : テスト
  • 規則 : 「件名」、「含む」、「テストメール」
  • 操作 : 「次にメッセージを移動」、「test」フォルダ

実際に「これはテストメールです。」という件名のメールを送信すると、以下の通り、「test」フォルダにメールが配送されていることがわかる。

なお、Sieveのスクリプトファイルは、以下のように作成されていた。

# cat /var/spool/virtual/[mydomain]/[myuser]/Maildir/dovecot.sieve
require ["fileinto"];
# rule:[テスト]
if allof (header :contains "subject" "テストメール")
{
        fileinto "INBOX.test";
}

以上で、Roundcubeにて「ManageSieve」のプラグインを有効化する手順は完了となる。

2024年1月28日日曜日

SPF、DMARC、DKIMに対応するためのDNSとPostfix (OpenDKIM)設定手順

Gmailは2024年2月より、1日あたり5,000件以上のメールを送信する送信元においては、SPF(エスピーエフ)、DMARC(ディーマーク)、DKIM(ディーキム)の設定が必須となるよう、セキュリティポリシーが変更される。

私は自宅検証環境においてメール送受信できるPostfixのメールサーバを構築しているが、SPF以外のDMARCとDKIMの対応ができていなかった。

そこで、本記事では、DNSへレコード追加とPostfixへOpenDKIMを導入し、SPF、DMARC、DKIMに対応したメール送信環境を構築する手順を記載する。

環境

自宅検証環境の構成概要図は以下の通り。今回は、以下構成図の赤枠で示している内部のメールサーバのPostfixと、外部DNSとして利用している「お名前ドットコム」に対して設定変更を行う。

本記事で説明に用いるドメインはexample.tech-mmmm.comとするため、各自の所有するドメインに読み替えて参照いただきたい。

SPF

SPFへの対応はDNSへ登録するのみで完了できる。具体的には以下のようなSPFレコード (TXTレコード)をDNSに登録する。

example.tech-mmmm.com. 3600 IN TXT
  "v=spf1 +ip4:[送信元となるメールサーバのIPアドレス] -all"

DMARC

DMARCへの対応もSPFと同様、DNSへ登録するのみで完了できる。レコードは_dmarc.[ドメイン名]で登録するが、具体的には以下のようなDMARCレコード (TXTレコード)をDNSに登録する。

p=noneはポリシーの設定であり、今回はDMARCの結果において特に何もしない (None)という設定としている。

ruarufはDMARCの判定結果のレポートを送信する自ドメインのメールアドレスを設定すればよい。設定すると、Gmailからは1日1回おおよそAM 9:00 (UTCでいうと0:00)に「Report domain: example.tech-mmmm.com Submitter: google.com」というタイトルのメールがレポートとして送られてくるようになる。

_dmarc.example.tech-mmmm.com. 3600 IN TXT
  "v=DMARC1; p=none; rua=mailto:dmarc-report@example.tech-mmmm.com; ruf=mailto:dmarc-report@example.tech-mmmm.com;"

DKIM

DKIMに関してはメール送信時に署名を付与する仕組みが必要であり、Postfixの場合はMilter (Mail Filter)として動作するOpenDKIMを使用する。

以下に導入手順を記載する。

1. OpenDKIMインストール

EPELのリポジトリ追加後、以下をインストールする。opendkim-toolsに鍵情報を作成するコマンドが含まれているため、併せてインストールすること。

# dnf install epel-release -y
# dnf install opendkim opendkim-tools -y

2. DKIM署名用の鍵を作成

DKIM署名用の鍵は、opendkim-genkeyコマンドで行う。

-sオプションでセレクタと呼ばれる任意の識別するための文字列を指定できる。今回はmyselectorと設定した。-bオプションは鍵の長さを設定するオプションとなり、OpenDKIMのデフォルトは1024bitとなるが、セキュリティの観点から2048bitで設定する。

# mkdir /etc/opendkim/keys/example.tech-mmmm.com
# opendkim-genkey -D /etc/opendkim/keys/example.tech-mmmm.com/ -d example.tech-mmmm.com -s myselector -b 2048
# ls -l /etc/opendkim/keys/example.tech-mmmm.com/
合計 8
-rw-------. 1 root root 887  1月 27 18:01 myselector.private
-rw-------. 1 root root 328  1月 27 18:01 myselector.txt

鍵情報のファイルは、ユーザー・グループを変更しておく。

# chown -R opendkim:opendkim /etc/opendkim/keys/example.tech-mmmm.com/
# ls -l /etc/opendkim/keys/example.tech-mmmm.com/
合計 8
-rw-------. 1 opendkim opendkim 887  1月 27 18:01 myselector.private
-rw-------. 1 opendkim opendkim 328  1月 27 18:01 myselector.txt

3. 設定ファイル修正

OpenDKIMの設定ファイルであるopendkim.confを以下の通り修正する。

# vi /etc/opendkim.conf
Mode    sv						    # vからsvに変更
Socket  inet:8891@localhost				    # アンコメント (UNIXドメインソケットからinetソケットに変更)
#Socket local:/run/opendkim/opendkim.sock		    # コメントアウト
Selector        myselector				    # defaultから変更
KeyTable        /etc/opendkim/KeyTable			    # アンコメント
SigningTable    refile:/etc/opendkim/SigningTable	    # アンコメント
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts   # アンコメント
InternalHosts   refile:/etc/opendkim/TrustedHosts	    # アンコメント

セレクタとドメインのに対して使用する鍵情報を紐づけるKeyTableファイルを以下の通り記載する。

# vi /etc/opendkim/KeyTable
myselector._domainkey.example.tech-mmmm.com example.tech-mmmm.com:myselector:/etc/opendkim/keys/myselector.private

署名する際のメールのドメインと使用する鍵情報を紐づけるSigningTableファイルを以下の通り記載する。

# vi /etc/opendkim/SigningTable
*@example.tech-mmmm.com myselector._domainkey.example.tech-mmmm.com

OpenDKIMが信頼できるホストとして認識するホストやネットワークを指定する。今回は内部環境となるので、0.0.0.0/0で指定する。

# vi /etc/opendkim/TrustedHosts
0.0.0.0/0

4. OpenDKIMサービスを起動

設定完了後、OpenDKIMのサービスを起動させる。

# systemctl start opendkim
# systemctl enable opendkim

起動するとポート8891番でLISTENしているかどうか確認しておく。

# ss -nl | grep 8891
tcp   LISTEN 0      128                                127.0.0.1:8891             0.0.0.0:*

5. Postfixの設定修正

OpenDKIMをMilterとして指定するため、以下3行を追加する。

# vi /etc/postfix/main.cf
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

設定完了後、Postfixを再起動しておく。

# systemctl restart postfix

6. DNS設定

DKIMはDNSの登録された公開鍵情報を用いて署名の検証を行うため、DNSへレコードの追加が必要となる。レコードは[セレクタ名]._domainkey.[ドメイン名]で登録する。レコードの内容は鍵を生成した際に作成される、/etc/opendkim/keys/example.tech-mmmm.com/myselector.txtのファイルに記載されているで、このまま登録を行えば問題ない。

# cat /etc/opendkim/keys/example.tech-mmmm.com/myselector.txt
myselector._domainkey   IN      TXT     ( "v=DKIM1; k=rsa; "
          "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyLeUjkqVc712NhH1/20UMGW4rxg4F4sQilrauxt5mWPEbu342y+Px+OD4oVZ1yeF9NAAAgExIJBwl854p1bn87rVgam9J/3mYICCD5GhbBy6MEFODgMZXcSvJ8Q2g7S1Y0mro95mI2p+8WtPfxjUTzERemcduNa3eZu7+i1I1GwIDAQAB" )  ; ----- DKIM key myselector for example.tech-mmmm.com

上記の通りDNSに登録を行う。

myselector._domainkey.example.tech-mmmm.com. 3600 IN TXT
  "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyLeUjkqVc712NhH1/20UMGW4rxg4F4sQilrauxt5mWPEbu342y+Px+OD4oVZ1yeF9NAAAgExIJBwl854p1bn87rVgam9J/3mYICCD5GhbBy6MEFODgMZXcSvJ8Q2g7S1Y0mro95mI2p+8WtPfxjUTzERemcduNa3eZu7+i1I1GwIDAQAB"

動作確認

実際にメールを送信した際のGmailにおける受信結果が以下となる。SPF、DKIM、DMARCがすべてPASSしていることがわかる。

以上で、DNSへレコード追加とPostfixへOpenDKIMを導入し、SPF、DMARC、DKIMに対応したメール送信環境を構築する手順は完了となる。

2023年11月11日土曜日

Roundcubeを使ってWebメール環境を構築する

先日、Postfix+DovecotでバーチャルドメインのIMAPメールサーバーを構築する手順を記事にした。

通常メールを確認する際は、Thunderbirdなどのメールクライアントの導入が必要となるが、メールクライアントをダウンロードしてPCにインストールしアカウントの設定を行うといった作業は、何度も実施すると結構な負荷となる。

そこで今回は、Webサーバ上で動作するメールクライアント「Roundcube」を使って、Webメール環境を構築してみることにした。

環境

Roundcubeの必要とするDBやPHPのシステム要件は、以下を参照すること。

上記を踏まえ、今回Roundcubeをインストールした環境は以下の通りとした。

  • OS : AlmaLinux 8.8
  • DB : MariaDB 10.3.35
  • Roundcube : 1.6.2
  • PHP : 7.4
  • Apache HTTP Server : 2.4.37
  • Postfix : 3.5.8
  • Dovecot : 2.3.16

以下記事の手順にて、Postfix+DovecotによるSMTP/IMAPサーバが構築済みであることが前提となる。

Roundcubeインストール手順

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

Roundcubeは必要となるパッケージが多岐にわたる。順にインストールしていこう。

まずはDBとしてMariaDBをインストールする。

dnf install httpd mariadb-server -y

次にPHPをインストールする。PHPのバージョンは7.3以上であることがシステム要件となることから、今回はPHP 7.4を選定した。また、Roundcubeは公式サイトのファイルではなく、Remiリポジトリに存在するRPMパッケージにてインストールを行う。

dnf module enable php:7.4 -y
dnf install http://rpms.remirepo.net/enterprise/remi-release-8.rpm -y
dnf --enablerepo=remi install roundcubemail -y

PHPにてMariaDBを利用するためのライブラリであるphp-mysqlnd (MySQL Native Driver) をインストールする。

dnf install php-mysqlnd -y

ImageMagicをインストールするために必要なパッケージがインストールする。gccmakeはこの後実行するpeclコマンドで必要となる。

dnf install php-devel php-pear gcc make ImageMagick ImageMagick-devel -y

単純にRPMパッケージをインストールするだけではRoundcubeからImageMagicを認識しないため、さらにpeclコマンドを実行し、ImageMagicのインストールを行う。

# pecl install imagick
WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update
downloading imagick-3.7.0.tgz ...
Starting to download imagick-3.7.0.tgz (360,138 bytes)
.........................................................................done: 360,138 bytes
33 source files, building
running: phpize
Configuring for:
PHP Api Version:         20190902
Zend Module Api No:      20190902
Zend Extension Api No:   320190902
Please provide the prefix of ImageMagick installation [autodetect] :
 ↑★そのままエンター

~(中略)~

Build process completed successfully
Installing '/usr/lib64/php/modules/imagick.so'
Installing '/usr/include/php/ext/imagick/php_imagick_shared.h'
install ok: channel://pecl.php.net/imagick-3.7.0
configuration option "php_ini" is not set to php.ini location
You should add "extension=imagick.so" to php.ini

ImageMagicのライブラリのパスを記載したPHPの設定ファイルを作成する。

# cat << EOF > /etc/php.d/20-imagick.ini
extension=/usr/lib64/php/modules/imagick.so
EOF

2. MariaDB設定

ここで一度MariaDBを起動する。

systemctl start mariadb
systemctl enable mariadb

MariaDBを起動したのちに、Roundcubeで用いるDB、ユーザ、パスワードを設定する。今回は以下の通り設定した。

  • DB : roundcubemail
  • ユーザ : roundcube
  • パスワード : password
# mysql -uroot
MariaDB [(none)]> CREATE DATABASE roundcubemail CHARACTER SET utf8 COLLATE utf8_general_ci;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'password';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> quit

DBとDBユーザ作成後、初期設定用のSQLを流し込む。

# mysql -u roundcube roundcubemail -p < /usr/share/roundcubemail/SQL/mysql.initial.sql
Enter password: ←★先ほど作成したroundcubeユーザのパスワードを入力
# ←★エラーなくプロンプトが表示されればOK

3. Apache/PHP設定

PHPの設定ファイルであるphp.iniは最低限タイムゾーンの設定を変更しておく。

sed -i "s#;date.timezone =#date.timezone = 'Asia/Tokyo'#g" /etc/php.ini

Apacheの設定ファイルとして/etc/httpd/conf.d/roundcubemail.confがインストール時に作成されるが、そのままではローカルからのアクセスのみ許可されていることから、外部からのアクセスができるよう以下コマンドを行い設定を置換する。

sed -i 's/Require local/Require all granted/g' /etc/httpd/conf.d/roundcubemail.conf

最後にApacheを起動する。

systemctl start httpd
systemctl enable httpdd

4. インストールウィザードにアクセス

問題なくApacheが起動すれば、Roundcubeのインストールウィザード画面にアクセスできるはずだ。ブラウザから以下URLにアクセスしてみよう。

  • http://[Roundcubeのホスト名/IPアドレス]/roundcubemail/installer/

インストールウィザードでは、各種PHPのライブラリのインストール状況やDBの状況が表示される。ここでは原則すべての項目が「OK」になっていることを確認しよう(DBのみMySQLが「OK」となっていれば問題ない)。


5. config作成

インストールウィザードではRoundcubeの各種設定を行うことができる。多数の設定項目が存在するが、最低限以下表の通り設定を行えば問題ない。

設定項目 説明
Database setup > Database password (omit for sqlite) DBのroundcubeユーザのパスワードを入力する。
IMAP Settings > username_domain ここにドメインを記載すると、ログイン時にドメインを省略できる。
SMTP Settings > smtp_host 今回は同じサーバでSMTPサーバが動作していることから、localhost:25を指定する。
Display settings & user prefs > language 日本語環境にするため、ja_JPを指定する。

設定後、画面下部の「CREATE CONFIG」ボタンを選択する。

6. configをアップロード

設定した内容でconfig.inc.phpの設定ファイルが作成され表示される。

表示されたconfigの内容をブラウザ上でコピーし、/etc/roundcubemail/config.inc.phpのファイルを作成して貼り付ける。

# vi /etc/roundcubemail/config.inc.php
<?php

/* Local configuration for Roundcube Webmail */

~(中略)~

// You can connect to any other googie-compliant service by setting 'spellcheck_uri' accordingly.
$config['spellcheck_engine'] = 'enchant';

Roundcubeの設定反映のためApacheを再起動する。

systemctl restart httpd

7. ログイン確認

これでRoundcubeにログインできるはずだ。以下URLにアクセスしログイン画面が表示されることを確認しよう。

DovecotのIMAP認証に用いるものと同じユーザ (ローカルパートのみでOK) とパスワードを用いてログインできれば成功となる。

以上で、Roundcubeを使ってWebメール環境を構築する手順は完了となる。

2023年11月4日土曜日

Postfix+DovecotでバーチャルドメインのIMAPメールサーバーを構築する手順

先日、メールサーバー構築をする際の定番であるPostfixとDovecotを使ってIMAPのメールサーバーを構築した。

本記事ではその際に得られたノウハウをもとに、Postfix+DovecotでバーチャルドメインのIMAPメールサーバーを構築する手順を記載する。

環境

今回Postfix及びDovecotをインストールした環境は以下の通り。

  • OS : AlmaLinux 8.8
  • Postfix : 3.5.8
  • Dovecot : 2.3.16

共通

1. Postfix及びDovecotをインストール

Postfix及びDovecotのパッケージがインストールされていない場合は、dnfでインストールする。

dnf install postfix dovecot -y

2. バーチャルドメイン用のOSユーザ・グループの作成

バーチャルドメインの場合は、OSユーザではなくDovecot独自のユーザにてメールボックスのユーザが管理される。ただし、メールボックスへのメール配送等はOSユーザを用いる必要があることから、vmailという名前のユーザ・グループを作成する。

groupadd -g 10000 vmail
useradd -u 10000 -g vmail vmail

3. メールボックス作成

メールボックスを/var/spool/virtualというディレクトリで作成する。

mkdir /var/spool/virtual
chown -R vmail:vmail /var/spool/virtual/

上記ディレクトリの配下に、各ユーザのメールボックスが以下のディレクトリ構成で作成される。

/var/spool/virtual/[ドメイン名]/[ユーザ名]/Maildir

Postfix構築手順

1. 設定ファイルバックアップ

設定変更の前に設定ファイルをディレクトリ丸ごとバックアップする。

cp -rp /etc/postfix /root/postfix.org

2. main.cf設定

Postfixの主要な設定は/etc/postfix/main.cfに記載する。以下に主要な設定内容を記載する。

設定項目 説明
myhostname メールサーバのホスト名をFQDNで記載する。
mydomain メールサーバのドメインを記載する。今回はバーチャルドメイン環境であるため、管理対象のメールアドレスのドメインと一致しなくても問題ない。
inet_interfaces 外部からSMTPでアクセスできるようにallを指定する。
inet_protocols 今回はIPv4を指定するが、IPv4にだけでなくIPv6も使用する場合はallを指定する。
mynetworks 外部から接続可能なIPアドレスやネットワークを指定する。ここで設定したネットワークは後述するSASL認証も不要でメール送信が可能となるため、必必要以上に設定しないよう注意する。
relayhost 自ドメイン以外のメールをリレーするサーバを指定する。
home_mailbox メールボックス形式をMailbox形式(ユーザ単位で1ファイルでメールを管理)またはMaildir形式(1メールに対して1ファイルで管理)で指定する。通常はMaildir形式を指定すれば問題ない。なお、Maildir形式に場合は最後に/を付け、Maildir/で指定すること。
smtpd_banner メールヘッダー等に表示するメールサーバ情報を指定する。セキュリティの観点から、使用しているバージョン等は記載しない方針とし、ESMTPのみ設定する。
virtual_mailbox_domains バーチャルドメインで管理するドメインを記載したファイルのパスを指定する。今回は、/etc/postfix/vdomainsというファイルで管理する。
virtual_mailbox_base バーチャルドメインで管理するメールボックスのディレクトリを指定する。今回は/var/spool/virtualを指定する。
virtual_mailbox_maps バーチャルドメインで管理するユーザと、ユーザのメールボックスを紐づけするファイルのパスを指定する。今回は、/etc/postfix/vmailboxというファイルで管理する。なお、大規模環境においてはユーザを大量に管理する必要があることから、処理速度を考慮しハッシュ化したものを指定する(ハッシュ化はpostmapコマンドで行う)。
virtual_uid_maps バーチャルドメインでメール配送等の処理に使用するOSユーザを指定する。前述したvmailユーザのUIDを指定する。
virtual_gid_maps バーチャルドメインでメール配送等の処理に使用するOSグループを指定する。前述したvmailグループのGIDを指定する。
smtpd_sasl_auth_enable SASL認証を有効にする。
smtpd_sasl_type SASL認証で使用する認証先を設定する。今回はDovecotで設定するユーザ・パスワードを用いることからDovecotを指定する。なお、SASLの認証設定は、後程Dovecot側でも実施する。
smtpd_sasl_path PostfixとDovecotが同一環境で動作する環境であれば、private/authを指定すれば問題ない。これが、通信に使用するUNIXソケットファイルのパスになる。
smtpd_sasl_security_options SASL認証時のオプションを指定する。noanonymousにて匿名での認証を拒否し、noplaintextにて平文での認証を拒否する。
smtpd_recipient_restrictions メールを配送する際の制限を行う。permit_sasl_authenticatedにてSASL認証済みであれば許可し、permit_mynetworksにてmynetworksで設定したネットワークからの接続であれば許可する。最後に記載されているrejectにて、それ以外のメール配送を拒否する。
disable_vrfy_command セキュリティの観点からVRFYコマンドを禁止するため、yesで設定する。
smtpd_helo_required セキュリティの観点からSMTPコマンド接続時のHELOコマンドを必須にするため、yesで設定する。

実際のmain.cfの記載例を以下に記載する。

/etc/postfix/main.cf変更箇所抜粋

myhostname = mx01.example.com
mydomain = example.com
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 10.0.0.1
relayhost = [10.0.0.1]:25
home_mailbox = Maildir/
smtpd_banner = ESMTP
virtual_mailbox_domains = /etc/postfix/vdomains
virtual_mailbox_base = /var/spool/virtual
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_uid_maps = static:10000
virtual_gid_maps = static:10000
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject
disable_vrfy_command = yes
smtpd_helo_required = yes

3. バーチャルドメインの設定ファイルの作成

バーチャルドメインの設定として、以下2つのファイルを作成する。

ファイル 内容
/etc/postfix/vdomains バーチャルドメインで管理するドメインを記載したファイル。メールサーバーで管理するドメインを一覧として記載する。
/etc/postfix/vmailbox バーチャルドメインで管理するユーザと、ユーザのメールボックスを紐づけするファイル。メールアドレスとメール保存先のディレクトリを一覧として記載する。ディレクトリは、[ドメイン名]/[メールアドレスのローカルパート]/Maildir/の形式で記載する。

それぞれのファイルの記載例を以下に記載する。

/etc/postfix/vdomains

example.com
example1.com

/etc/postfix/vmailbox

ex01@example.com      example.com/ex01/Maildir/
ex02@example.com      example.com/ex02/Maildir/
ex11@example1.com     example1.com/ex11/Maildir/

/etc/postfix/vmailboxpostmapコマンドを用いてハッシュ化しておく。

postmap /etc/postfix/vmailbox

4. Postfix設定反映

設定反映前に設定ファイルのチェックを行う。

# postfix check
#  ←★エラーがなければ何も表示しない

問題がなければ、Postfixに設定を反映するため再起動する。

systemctl restart postfix
systemctl enable postfix

Dovecot構築手順

1. 設定ファイルバックアップ

設定変更の前に設定ファイルをディレクトリ丸ごとバックアップする。

cp -rp /etc/dovecot /root/dovecot.org

2. 各種設定を実施

DovecotはPostfix以上に設定ファイルが細分化されている。今回の修正対象ファイルを以下に記載する。

ファイル 内容
/etc/dovecot/dovecot.conf メインの設定ファイル。プロトコルとしてIMAPを指定する(デフォルトではPOP3、IMAPの両方が動作する)。
/etc/dovecot/conf.d/10-auth.conf 認証方式を記載する。今回は平文による認証を無効化したうえで、CRAM-MD5による認証方式を用いる。
/etc/dovecot/conf.d/auth-passwdfile.conf.ext 認証する際のパスワードファイルの指定を行う。パスワード認証情報(passdb)及びユーザ認証情報(userdb)は、後程作成する/etc/dovecot/usersファイルを参照するよう設定する。
/etc/dovecot/conf.d/10-master.conf PostfixがSASL認証で使用する際のUNIXソケットファイルのパスを指定する。

それぞれのファイルの記載例を以下に記載する。

/etc/dovecot/dovecot.conf変更箇所抜粋

protocols = imap lmtp

/etc/dovecot/conf.d/10-auth.conf変更箇所抜粋

disable_plaintext_auth = yes
auth_mechanisms = cram-md5
#!include auth-system.conf.ext
!include auth-passwdfile.conf.ext

/etc/dovecot/conf.d/auth-passwdfile.conf.ext変更箇所抜粋

passdb {
  driver = passwd-file
  args = scheme=CRAM-MD5 username_format=%u /etc/dovecot/users
}
userdb {
  driver = passwd-file
  args = username_format=%u /etc/dovecot/users
  default_fields = uid=vmail gid=vmail home=/var/spool/virtual/%d/%n/Maildir
}

/etc/dovecot/conf.d/10-master.conf変更箇所抜粋

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  ~(略)~
}

3. ユーザ・パスワードファイルを作成

Dovecotのユーザ・パスワードファイルを作成する。パスワード情報は平文ではなくCRAM-MD5で暗号化されたものを記載する。CRAM-MD5の暗号化文字列の作成は以下コマンドで行う。

doveadm pw -s CRAM-MD5 -p [パスワード文字列]

上記で作成したパスワード文字列を用いて、以下書式でユーザ・パスワードファイルを作成する。行末のコロン2つ(::)は必要となるので省略しないこと。

[ユーザ名]:[暗号化パスワード文字列]::

ユーザ・パスワードファイルの記載例を以下に記載する。

/etc/dovecot/users

test01@example.com:{CRAM-MD5}dcbe8064d829ee98ad16817611150a123455fe1c9dfd79f5395be892f162bfd3::
test02@example.com:{CRAM-MD5}0a9a6905dfdefaf79e95b5a63274464123456166a2f27e593150e37ef2db952::
test11@example1.com:{CRAM-MD5}b71384fd047350e89123456a80ee9959dec89ff9766d75d45ab923792e44ea16::

4. 設定を反映

設定反映前に設定ファイルのチェックを行う。以下コマンドをすると各種設定値が羅列されるが、その際にエラーが表示されていなければ、設定値としては問題ない。

doveconf -n

Dovecotに設定を反映するため再起動する。

systemctl restart dovecot
systemctl enable dovecot

動作確認

メールクライアントを使って確認することが手っ取り早い。

Windows環境であれば、Thunderbird Portable Editionがインストール不要で使え、複数アカウント登録も簡単にできるのでお勧めとなる(ただし、容量は120MB程度あるので注意)。

今回はThunderbird Portable Editionを用いた確認手順を記載する。

1. Thunderbirdのアカウントの設定

Thunderbirdを開き、「設定」→「アカウント設定」を開き、「アカウント操作」から「メールアカウントを追加」を選択する。

でアカウント追加を行う。その際に受信サーバー(IMAP)と送信サーバー(SMTP)の設定を以下の通り行う。

受信サーバー

設定項目 設定値 説明
プロトコル IMAP -
ホスト名 構築したサーバのIPアドレス -
ポート番号 143 STARTTLSであれば143、SSL/TLSであれば993を選択する。
接続の保護 STARTTLS Dovecotの/etc/dovecot/conf.d/10-ssl.confにてssl = requiredの設定がされていることから、STARTTLSまたはSSL/TLSのどちらかを選択する。ここまでの設定で明示的に設定はしていないが、DovecotはデフォルトでIMAPSの通信が可能な構成となっている。
認証方式 暗号化されたパスワード認証 CRAM-MD5で設定されているため、「暗号化されたパスワード認証」を指定する。
ユーザー名 Dovecotで設定したユーザ名を指定 /etc/dovecot/usersに記載したユーザ名を指定する。

送信サーバー

設定項目 設定値 説明
ホスト名 構築したサーバのIPアドレス -
ポート番号 25 -
接続の保護 なし SSL/TLSの設定はしていないため、「なし」を指定する。
認証方式 暗号化されたパスワード認証 CRAM-MD5で設定されているため、「暗号化されたパスワード認証」を指定する。
ユーザー名 Dovecotで設定したユーザ名を指定 /etc/dovecot/usersに記載したユーザ名を指定する。

図13

2. 設定時の警告を承認

アカウントの作成指示に以下のセキュリティ警告が表示される。いずれも、「確認」と「セキュリティ例外を承認」を選択する。


4. アカウント作成

設定が問題なければ「アカウント作成が完了しました」の画面が表示される。

3. メール送受信テスト

同様の手順で複数アカウントを作成し、お互いでメールを送受信できることを確認できれば動作確認完了となる。

以上で、Postfix+DovecotでバーチャルドメインのIMAPメールサーバーを構築する手順は完了となる。

2023年6月17日土曜日

PostfixからGmailを経由してメール送信する手順

以前、OP25B (Outbound Port 25 Blocking)環境におけるPostfixから外部にメール送信を行う手順を記載した。

自宅検証環境は、上記手順にてインターネットサービスプロバイダーのメールサーバを経由して、監視通知メールなどの送信を行っている。しかし、最近は原因が不明だが、多くのメールがロストするという事象が発生しており、メール通知が正常にされないとう状況となっていた。

そこで、Gmailを経由してメールを送信する方針に切り替えることにした。本記事では、自宅のPostfixからGmailを経由してメール送信するための設定手順を記載する。

設定手順

1. Gmailアカウントの管理画面に移動

Googleのアカウントにログインした状態で、ホーム画面から右上のメニューを開き、「アカウント」を選択しアカウント管理画面を表示する。


2. Gmailの2段階認証プロセスを有効にする

アカウント管理画面の右メニューから、「セキュリティ」を選択し、2段階認証プロセスが有効になっていることを確認する。もし有効になっていない場合は、アプリパスワードの作成ができないため、有効化をすること(2段階認証プロセスの有効化手順は、本記事では割愛する)。

3. Gmailのアプリパスワードを作成

2段階認証プロセスが「セキュリティ」を選択し、「2段階認証プロセス」の設定画面に移動する。
※画面遷移時にパスワード確認を求められる。

「2段階認証プロセス」の設定画面の一番下に「アプリパスワード」が存在するので選択する。

「アプリパスワード」画面では、「アプリを選択」で「その他 (名前を入力)」を選択する。名前はあくまでも識別に用いるものであるため任意の名称で問題ないが、今回はPostfixという名前を付けた。

作成後、パスワードが表示されるので、メモ帳などで控えておくこと。

4. main.cfを設定

設定変更箇所を以下に抜粋する。GmailのSMTP接続先としてsmtp.gmail.comを指定し、SASL認証を有効化する。

# 受信許可ネットワークの設定
mynetworks = 127.0.0.0/8, 192.168.0.0/16

# 受付インタフェースを修正
inet_interfaces = all
inet_protocols = ipv4

# メールのリレー先サーバを指定
relayhost = [smtp.gmail.com]:587

# SMTP認証設定 (最下行に追加)
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp_password
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain,login

5. パスワードファイルを作成

SASL認証に用いる認証情報をsmtp_passwordファイルに記載する。本ファイルは、以下の構文で記載する。

[smtp.gmail.com]:587 <Gmailアドレス>:<アプリパスワード>

以下記載例となる。

[smtp.gmail.com]:587 hoge@gmail.com:XXXXXXXX

パスワード情報が含まれるため、rootのみ読み書きできるように権限設定を行ったのち、postmapコマンドでhash化したDBファイルを作成する。

# chmod 600 /etc/postfix/smtp_password
# postmap /etc/postfix/smtp_password
# ls -l /etc/postfix/smtp_password*
-rw------- 1 root root    58  8月 16 06:12 /etc/postfix/smtp_password
-rw------- 1 root root 12288  8月 16 06:12 /etc/postfix/smtp_password.db

6. Postfixの設定反映

最後にPostfixを再起動し、設定を反映する。

# systemctl restart postfix

7, 動作確認

構築したPostfixからGmailを経由してメールが送信できることを動作確認してみよう。

今回はcurlを使って、以下のように送信テストを行った。

( echo "helo test.local"
echo "mail from: <zabbix@test.local>"
echo "rcpt to: <hoge@gmail.com>"
echo "data"
echo "From: zabbix@test.local"
echo "To: hoge@gmail.com"
echo "Subject: test mail"
echo "テストメール"
echo ""
echo "."
echo "quit"
) | curl -v telnet://[メールサーバのIPアドレス]:[ポート番号]

実際受け取ったメールは以下の通り。

本設定にて送信されたメールは、FromのアドレスがGmailのアドレスに変換される点に注意すること。変換前のFromアドレスは、メールのX-Google-Original-Fromというヘッダーに記載されるため、メールのソースを見れば確認可能となる。

メールのソース抜粋

From: hoge@gmail.com
X-Google-Original-From: <zabbix@test.local>
To: <宛先アドレス>

以上で、自宅のPostfixからGmailを経由してメール送信するための設定手順は完了となる。

2021年1月16日土曜日

DockerでPostfixをコンテナ化してメールサーバを構築する

自宅のプロキシ/DNS/メールサーバをPacemakerによる冗長構成から、ロードバランサ (ZEVENET) + Dockerコンテナ構成への移行を進めている。

ロードバランサは導入済みなので、最終形として、プロキシ、DNS、メールのそれぞれの機能をDockerのコンテナ化を行うことを計画しており、今回はその第一弾として、メール機能であるPostfixのコンテナ化を行う

最終形として、プロキシ、DNS、メールのそれぞれの機能をDockerのコンテナ化を行うことを計画しており、今回はその第一弾として、メール機能であるPostfixのコンテナ化を行う

環境

今回のDocker環境構築時のソフトウエアバージョンを以下に記載する。

  • DockerホストOS : CentOS 8.2
  • Docer : 19.03.14
  • コンテナ用OSイメージ : centos:latest

Dockerホストとコンテナ間では、サービス提供に必要なポートの紐づけと、ログファイルを出力させるディレクトリの紐づけを行う。以下に簡単に図示しておく。

Postfixコンテナ化手順

1. Dockerのインストール

Dockerのインストールは別記事を参照。CentOS 7にDockerをインストールする内容となっているが、CentOS 8も同様の手順でインストールできる。

Dockerインストール後、Dockerfile等を配置するディレクトリを作成し、以後はそのディレクトリ内にすべてのファイルを配置する。

2. Postfix用の設定ファイルを準備

通常の家庭用のインターネットプロバイダを使っている場合、SMTP (TCP/25ポート) を使って外部へのメール送信はできないようになっている。この仕様をOP25B (Outbound Port 25 Blocking)と呼ぶが、PostfixでOP25Bに対応した設定をすることでメール送信が可能となる。OP25B環境におけるPostfixの設定は以下にて記事にしているで参照いただきたい。

コンテナにする場合も同様の設定を行えばよい。あらかじめ、以下の通り2つの設定ファイルを作成しておく。

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
inet_interfaces = all
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost
unknown_local_recipient_reject_code = 550
mynetworks = 127.0.0.0/8, 192.168.0.0/16 #★
relayhost = [<メールサーバのFQDN>]:587 #★
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

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
smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
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
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp_password
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain,login

smtp_password

※★箇所は各環境に合わせて変更すること。

[<メールサーバのFQDN>]:587 <ユーザ名>:<パスワード> #★

3. rsyslogとPostfix起動用のスクリプト (ラッパースクリプト) を作成

Postfixはログ出力にrsyslogの機能を使うため、rsyslogの起動とPostfixの起動という複数のプロセス起動を行う必要がある。複数のプロセス起動を行う場合の作法としては、ラッパースクリプトを作成して実行させるといった手法が定番のようだ。

今回は、以下の内容でstartup.shというスクリプトを作成した。メインとなるプロセス (今回はPostfix) の起動コマンドはexecを付与してPID 1で動作させるようにしている。

#!/bin/bash

/usr/sbin/rsyslogd
exec /usr/sbin/postfix start-fg

4. Dockerホストにログ出力先を作成

今回はコンテナのPostfixが出力したmaillogをDockerホストのディレクトリ出力するよう構成するため、以下の通りあらかじめログ出力先のディレクトリを作成しておく。

mkdir -p /var/log/docker/centos-postfix
chmod 777 /var/log/docker/*

5. Dockerfileを作成

コンテナの構成情報はDockerfileに記述する。いくつか記述内容にポイントがあるので以下表にまとめる。

命令 記述内容 説明
FROM centos コンテナのベースとなるイメージはCentOSを使用する。
ENV TZ タイムゾーンを日本標準時 (Asia/Tokyo) にする。
ENV http_proxy, https_proxy プロキシ環境の場合は、プロキシサーバを指定する。
RUN dnf 必要なパッケージのインストールを行う。Postfixのログはsyslogを使用して出力されるため、rsyslogを追加インストールする点に注意。
RUN sed, mkdir コンテナ環境であってもログを出力できるようにするため、/etc/rsyslog.confの設定ファイルを修正する。maillogの出力先を/var/log/postfix/maillogに変更し、ログの出力をjournald経由ではなくシステムソケットに変更している。また、Dockerホストのボリュームのマウントポイントとなるため、ログ出力先ディレクトリの作成しておく。
COPY - 事前に作成したmain.cfsmtp_passwordの設定ファイルを /etc/postfix/にコピーする。
COPY - プロセス起動用のstartup.sh/にコピーする。
RUN chmod, postmap, postalias 各種設定ファイルの権限設定とPostfixで必要となるDBファイルの作成を行う。
EXPOSE 25 SMTPの25番ポートを記述する。
CMD ["/startup.sh"] startup.shを起動する。[]で囲まずに記述すると/bin/sh -cが付与されてプロセスが実行されてしまうので、通常は必ず[]にてコマンドを囲むこと。

実際のDockerfileは以下の通りとなった。

FROM centos

ENV TZ=Asia/Tokyo \
    http_proxy=http://192.168.33.23:8080 \
    https_proxy=http://192.168.33.23:8080
RUN dnf install postfix cyrus-sasl cyrus-sasl-plain mailx rsyslog -y && \
    sed -i -e 's#/var/log/maillog#/var/log/postfix/maillog#g' \
           -e 's/SysSock.Use="off"/SysSock.Use="on"/g' \
           -e 's/^\(module(load="imjournal"\)/#\1/g' \
           -e 's/^\([ ]*StateFile="imjournal.state\)"/#\1/g' \
           /etc/rsyslog.conf && \
    mkdir /var/log/postfix


COPY main.cf smtp_password /etc/postfix/
COPY startup.sh /
RUN chmod 600 /etc/postfix/smtp_password && \
    postmap /etc/postfix/smtp_password && \
    postalias /etc/aliases && \
    chmod +x /startup.sh

EXPOSE 25
CMD ["/startup.sh"]

6. コンテナイメージを作成

作成したDockerfileを使って、docker buildコマンドにてコンテナイメージを作成する。

# docker build -t centos-postfix:1 .

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos-postfix      1                   9e3991eb23a8        36 hours ago        296MB

7. コンテナを起動

コンテナ起動時には、以下オプションの設定を行う。

設定内容 説明
--name コンテナの名称を設定。今回は「centos-postfix」という名前にする。
-p Dockerホストの通信ポートとコンテナの通信ポートを紐づけを行う。<ホストポート>:<コンテナポート>の書式で記載する。今回はSMTPのポート番号である25番ポートを紐づけるので、25:25で指定する。
-v Dockerホストのディレクトリ/ファイルとコンテナのディレクトリ/ファイルの紐づけを行う。<ホストディレクトリ/ファイル>:<コンテナディレクトリ/ファイル>の書式で記載する。今回はホストの/var/log/docker/centos-postfix/ディレクトリにコンテナの/var/log/postfixを紐づけることで、maillogログを出力させる。

上記をふまえ、以下の通りdocker runコマンドでコンテナの起動を行う。

# docker run -d -p 25:25 --name "centos-postfix" \
-v /var/log/docker/centos-postfix:/var/log/postfix \
centos-postfix:1

# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                          NAMES
f6bb3910351a        centos-postfix:1    "/startup.sh"            28 minutes ago      Up 28 minutes       0.0.0.0:25->25/tcp                             centos-postfix

8. logrotate設定

ホストに出力させたログをローテーションさせるため、logrotateの設定を行う。logrotateは/etc/logrotate.d/に設定ファイルを置けば自動で実行されるようになる。

logrotateの設定のポイントは2つ。

logrotateは元のファイルをリネームして、新規空ファイルを作成するという動作を行うが、この際にログ出力元となるプロセスのリロード等の処理が必要となる。しかし、ホスト側のログローテーション実行とコンテナ側のプロセスのリロードの同期ができないため、copytruncateオプションを付与する。copytruncateオプションを付与すると、元のファイルはリネームではなくコピーしたのち、ログファイルの内容を空にする方式でローテーションが実行される。
※本方式はタイミングによっては、ローテーション中に書き込まれたログがロストする可能性があるので注意。

また、logrotateの仕様により、ログ出力先のディレクトリの権限が777となっている場合、以下メッセージでローテーションが失敗する。このような場合でもログローテーションを実行できるようsu root rootを付与する。

error: skipping "/var/log/docker/centos-postfix/maillog" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.

上記をふまえ、以下のようにdocker-logというファイル名で設定ファイルを作成し、/etc/logrotate.d/に配置した。

# cat /etc/logrotate.d/docker-log
/var/log/docker/*/maillog
/var/log/docker/*/*.log
{
    rotate 7
    daily
    copytruncate
    dateext
    su root root
}

1日経過すると以下の通りログがローテーションされることが確認できた。

# ls -lh /var/log/docker/centos-postfix/
/var/log/docker/centos-postfix/:
-rw-r--r--. 1 root root 263K 12月 20 07:06 maillog
-rw-r--r--. 1 root root 1.2M 12月 20 03:17 maillog-20201220

以上でPostfixのコンテナ化が完了となる。

2020年8月20日木曜日

OP25B環境でメール送信できるようにPostfixを構築する

OP25B (Outbound Port 25 Blocking) とは、ウイルスやスパムなどで外部に大量のメール送信をすることを防ぐことを目的として、外部との25番ポート (SMTP) の通信を拒否する設定のことをいう。この設定は一般的な家庭向けのインターネットサービスプロバイダーでは標準で設定されており、解除することはできない。

OP25Bが有効となった環境においては、SMTPによるメール送信はできないが、サブミッションポートと呼ばれる587番ポートを使ったメール送信を行うことができる。サブミッションポートを使ったメール送信では、プロトコル自体はSMTPが用いられるが、SMTP AUTHによる認証が必要となる。

今回、Postfixにてサブミッションポートを使ったメール送信設定を実施した

環境

  • OS : CentOS 8

Postfixのインストール

CentOS 8は標準でPostfixがインストールされていないのでインストールを行う。同時に、SMTP AUTHに必要となる「cyrus-sasl」関連のパッケージと、メール送信テストに使える「mailx」パッケージを導入しておく。

# dnf install postfix -y
# dnf install cyrus-sasl cyrus-sasl-plain -y
# dnf install mailx -y

Postfixの設定

1. Postfixのmain.cfを修正

Postfixインストール後、「/etc/postfix/main.c」に対して以下設定修正・追加を行う。メールのリレー先サーバは、プロバイダーの情報を参照して適切なFQDNを設定すること。なお、FQDNを[]を囲んでいるが、これはDNSに対してMXレコードの名前解決をせず、AレコードのIPアドレスにて名前解決を行う設定となる。今回のようにメール送信にプロバイダーのメールサーバを使用する場合は、原則[]で囲んでおけば問題なさそうだ。

# 受信許可ネットワークの設定
mynetworks = 127.0.0.0/8, 192.168.0.0/16

# 受付インタフェースを修正
inet_interfaces = all
inet_protocols = ipv4

# メールのリレー先サーバを指定
relayhost = [<メールサーバのFQDN>]:587

# SMTP認証設定 (最下行に追加)
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp_password
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain,login

2. SMTP AUTH用のパスワードファイルを作成

SMTP AUTHはユーザ情報とパスワードが必要となるので、「/etc/postfix/smtp_password」というファイルを作成し、以下構文で設定を行う。

[<メールサーバのFQDN>]:587 <ユーザ名>:<パスワード>

以下記述例となる。

# vi /etc/postfix/smtp_password
[smtp.example.com]:587 USERNAME@example.com:PASSWORD

パスワード情報が含まれるため、rootのみ読み書きできるように権限設定を行ったのち、postmapコマンドでhash化したDBファイルを作成する。

# chmod 600 /etc/postfix/smtp_password
# postmap /etc/postfix/smtp_password
# ls -l /etc/postfix/smtp_password*
-rw------- 1 root root    58  8月 16 06:12 /etc/postfix/smtp_password
-rw------- 1 root root 12288  8月 16 06:12 /etc/postfix/smtp_password.db

3. Postfixを起動

最後にPostfixを起動させ、ステータスでエラーが発生していなければ、設定は成功となる。

# systemctl start postfix
# systemctl enable postfix
# systemctl status postfix
● postfix.service - Postfix Mail Transport Agent
   Loaded: loaded (/usr/lib/systemd/system/postfix.service; enabled; vendor pre>
   Active: active (running) since Sun 2020-08-16 05:48:12 JST; 27s ago
 Main PID: 23119 (master)
    Tasks: 3 (limit: 11091)
   Memory: 4.7M
   CGroup: /system.slice/postfix.service
           tq23119 /usr/libexec/postfix/master -w
           tq23120 pickup -l -t unix -u
           mq23121 qmgr -l -t unix -u

 8月 16 05:48:11 t3022cent systemd[1]: Starting Postfix Mail Transport Agent...
 8月 16 05:48:12 t3022cent postfix/master[23119]: daemon started -- version 3.3>
 8月 16 05:48:12 t3022cent systemd[1]: Started Postfix Mail Transport Agent.

動作確認

動作確認のためmailコマンドでメール送信をしてみよう。以下のように、-SオプションでPostfixを導入したサーバをメールサーバとして指定し、25番ポートを使ってメールが転送され、Gmailなどの外部のメールアドレスでメール受信できれば成功となる。

# echo "Test message" | mail -S smtp://<Postfixを導入したサーバのIPアドレス>:25 -s "Subject : Test mail" <送信先メールアドレス>
2018年4月17日火曜日

Postfixのmain.cfの設定変更は自動反映されるので注意!


Postfixの主要な設定を記載するファイルは、/etc/postfix/main.cfとなる。

main.cfに設定変更を加えたのち、Postfixをreloadすることで設定反映を行うという手順は、さまざまなサイトで言及されている手順となる。

しかし、main.cfの設定は自動反映されることがある。したがって、事前にmain.cfに設定変更を行っておき、任意のタイミングで反映するような作業計画は危険であり、main.cfの設定変更は、設定反映と同じタイミングで実施するよう計画すべきである。

しかし、reloadしなくても反映される場合、どのようなタイミングで反映されるかが気になるので調べてみることにした。

Postfixをデバッグモードにする

通常の設定では詳細なログが出力されないので、Postfixをデバッグモードにする。以下の通り、master.cfのsmtp行に「-v」のオプションを付ける。

# cat /etc/postfix/master.cf | grep -v -e "^#"
------------------------------
smtp      inet  n       -       n       -       -       smtpd -v
------------------------------

設定反映のため、Postfixを再起動する。

# systemctl restart postfix

設定反映のタイミングを確認

Postfixで複数の管理ドメインを持つバーチャルメールボックスの構成としている状況で、管理ドメインの設定ファイルからドメインを1つコメントアウトしてみる。

【main.cfの設定】
# cat /etc/postfix/main.cf | grep virtual
------------------------------
virtual_mailbox_domains = /etc/postfix/vdomains
virtual_mailbox_base = /var/spool/virtual
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_uid_maps = static:10000
virtual_gid_maps = static:10000
virtual_alias_maps = hash:/etc/postfix/virtual
------------------------------

【変更前】
# cat /etc/postfix/vdomains
------------------------------
example.com
example1.com
example2.com
------------------------------

【変更後】
# cat /etc/postfix/vdomains
------------------------------
#example.com
example1.com
example2.com
------------------------------

通常は自分自身のメールボックスに配送されるexample.com宛てのメールが、コメントアウトの設定が反映されることで上位のMTAにリレーされる。この動作の差異を見ることで設定反映の有無を確認することができる。

変更前にexample.com宛てにメールを送ってみると、以下の通り「delivered to maildir」のログが表示され、自身のサーバー内のメールボックスにメールが送信されたことがわかる。

# tail -100 /var/log/maillog | egrep "example.com.*status"
------------------------------
Apr  9 06:25:26 t1110rh72 postfix/virtual[3102]: BF47F18D2AA7: to=<ex-1@example.com>, relay=virtual, delay=0.06, delays=0.05/0.01/0/0, dsn=2.0.0, status=sent (delivered to maildir)
------------------------------

ここで、example.comのドメインをコメントアウトし、再度メールを送信してみる。しかし、このタイミングでは先ほどと同じ動作となることがログからわかる。つまり、設定はまだ反映されていない。

# tail -100 /var/log/maillog | egrep "example.com.*status"
------------------------------
Apr  9 06:26:31 t1110rh72 postfix/virtual[3102]: 6EEC818D2AA9: to=<ex-1@example.com>, relay=virtual, delay=0.02, delays=0.02/0/0/0, dsn=2.0.0, status=sent (delivered to maildir)
------------------------------

しばらく待ってからメールを送信してみると、ログの内容が変化する。どうやらexample.com宛てのメールが上位のMTAにリレーされているようだ。

# tail -100 /var/log/maillog | egrep "example.com.*status"
------------------------------
Apr  9 06:29:05 t1110rh72 postfix/smtp[3185]: 7E88118D2AAB: to=<ex-1@example.com>, relay=192.168.11.112[192.168.11.112]:25, delay=0.05, delays=0.02/0.01/0.01/0.01, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 70D61A67D9)
------------------------------

当然だが、この作業の間にPostfixのサービス再起動などはしておらず、何らかのタイミングで設定が自動反映されたことになる。

なぜ設定が反映されたかを確認してみる

結果的に、maillogを見ることで、設定反映のタイミングを確認することができた。以下ログの黄色網掛け箇所に注目する。

# tail -f /var/log/maillog | grep postfix
------------------------------
Apr  9 06:26:31 t1110rh72 postfix/smtpd[3095]: private/anvil: wanted attribute: (list terminator)
Apr  9 06:26:31 t1110rh72 postfix/smtpd[3095]: input attribute name: (end)
Apr  9 06:26:31 t1110rh72 postfix/smtpd[3095]: disconnect from t1082w216[192.168.11.82]
Apr  9 06:26:31 t1110rh72 postfix/smtpd[3095]: master_notify: status 1
Apr  9 06:26:31 t1110rh72 postfix/smtpd[3095]: connection closed
Apr  9 06:28:11 t1110rh72 postfix/smtpd[3095]: idle timeout -- exiting
------------------------------

メール送信後のconnection closedから100秒後に、idle timeoutが発生している。

Postfixはメール送信時に送信用プロセスを作成するが(これはprocess generationというログから確認できる)、一定時間メール送信がない場合は、プロセスを停止する動作を行う。そして、再度メールが送信される際に新しくプロセスを作成するのだが、その際にmain.cfの再読み込みを行うようだ。

したがって、main.cfの設定変更を行った後、メール送信がない状態が続いてプロセスが停止した場合、設定が反映されてメールが送信されるということになる。

なお、プロセスのアイドル時間は以下設定値で定義されている。デフォルトで100秒となっている。

# postconf | grep -e "^max_idle"
------------------------------
max_idle = 100s
------------------------------

2018年3月14日水曜日

Postfixで"454 4.7.1 Relay access denied"で送信が失敗する

Postfixでメール送信を行う際に、/var/log/maillogに以下エラーが出力されて、送信が拒否されることがある。

------------------------------
Feb 17 08:26:31 t1110rh72 postfix/smtpd[10936]: connect from unknown[192.168.11.82]
Feb 17 08:26:31 t1110rh72 postfix/smtpd[10936]: NOQUEUE: reject: RCPT from unknown[192.168.11.82]: 454 4.7.1 <test2@example100.com>: Relay access denied; from=<ex2-1@example2.com> to=<test2@example100.com> proto=ESMTP helo=<[192.168.11.82]>
Feb 17 08:27:36 t1110rh72 postfix/smtpd[10936]: disconnect from unknown[192.168.11.82]
------------------------------

これはメールクライアントにおいてもエラーとして表示される。


エラー原因

Postfixのmain.cfの以下2つの設定値が適切に設定されていないことが原因となる。
  • mynetworks
  • smtpd_relay_restrictions
エラー発生時の設定内容を抜粋する。

------------------------------
mynetworks = 127.0.0.0/8
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
------------------------------

smtpd_relay_restrictionsは、メールをリレーをする際の制限ルールを記載する。デフォルトで、「permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination」が設定されており、それぞれの意味は以下の通りとなる。
  • permit_mynetworks:mynetworksに記載されたクライアントからのメールリレーを許可
  • permit_sasl_authenticated:SASL認証されたメールのリレーを許可
  • defer_unauth_destination:不明な宛先からのメールリレーを一時的なエラーコード(4xx)で拒否
上記の3つのルールは先頭から順番に処理されるようだ。今回の場合、mynetworksにメールクライアントのIPアドレス登録がされておらず、SASL認証もしない設定だったため、defer_unauth_destinationの制限に該当し、「Relay access denied」となった。

したがって、エラーを回避するためには、メールクライアントのIPアドレスをmynetworksに登録すればよい。例えば、メールクライアントのIPアドレスが192.168.11.82であれば以下のように記載する。

------------------------------
mynetworks = 127.0.0.0/8, 192.168.11.82
------------------------------

参考

・Postfix Configuration Parameters - smtpd_relay_restrictions
http://www.postfix.org/postconf.5.html#smtpd_relay_restrictions

2018年2月5日月曜日

Postfixで"Permission denied"でファイル送信が失敗する

Postfixでメール送信を行う際に、以下のようなエラーで失敗することがある。

# postqueue -p
------------------------------
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
782A818BD67B      429 Sat Jan 13 21:05:10  ex-1@example.com
(maildir delivery failed: create maildir file /var/spool/virtual/example1.com/ex1-1/Maildir/tmp/1515845435.P3212.t1110rh72: Permission denied)
                                         ex1-1@example1.com

-- 0 Kbytes in 1 Request.
------------------------------

これはSELinuxが動いていることが原因となるので、以下の通り無効化してしまえばよい。
※SELinuxを無効化したくない場合は、適切にSELinuxを設定するしかないが、本記事の範囲外とする。

# getenforce
------------------------------
Enforcing
------------------------------
# setenforce 0
# getenforce
------------------------------
Permissive
------------------------------

上記はOS再起動をするともとに戻ってしまうので、以下設定ファイルを修正して完全にSELinuxを無効化しておく。

# cat /etc/selinux/config
------------------------------
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted
------------------------------

2018年1月30日火曜日

Postfixで"unable to create lock file"でファイル送信が失敗する

Postfixでメールサーバー構築を行っていた際に、以下のようなメッセージが表示されて、メール配送に失敗する事象が発生した。

# postqueue -p
------------------------------
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
E632018BD679      429 Sat Jan 13 20:36:21  ex-1@example.com
(delivery failed to mailbox /var/spool/virtual/example1.com/ex1-1/Maildir: unable to create lock file /var/spool/virtual/example1.com/ex1-1/Maildir.lock: No such file or directory)
                                         ex1-1@example1.com

-- 0 Kbytes in 1 Request.
------------------------------

上記エラーをWebで調べても、なかなか同一事象が記載されたサイトがなく、解決に苦労したため、本記事にてエラーの原因と解決方法について記載する。

原因と解決方法

1つのメールサーバーで複数ドメインを扱う必要があったため、バーチャルメールボックスにてPostfixを設定していた。ユーザーとメールボックス紐づけは、/etc/postfix/vmailboxのファイルに以下のように記載をしていた。

# cat /etc/postfix/vmailbox
------------------------------
ex-1@example.com      example.com/ex-1/Maildir
ex-2@example.com      example.com/ex-2/Maildir
ex1-1@example1.com    example1.com/ex1-1/Maildir
ex2-1@example2.com    example2.com/ex2-1/Maildir
------------------------------

当初、上記記載に誤りはないものと考えていたが、結果としては前述したメール配送の失敗が発生した。

いろいろ切り分けた結果、以下のように記載を修正することで解決した。ユーザーのメールボックスの指定する際には、最後に「/」が必要だった。解決した後だから言えるが、たいしたことのない問題だった。

------------------------------
ex-1@example.com      example.com/ex-1/Maildir/
ex-2@example.com      example.com/ex-2/Maildir/
ex1-1@example1.com    example1.com/ex1-1/Maildir/
ex2-1@example2.com    example2.com/ex2-1/Maildir/
------------------------------

人気の投稿