電子メールサービス - Postfix と Devecot 

# Postfix

## プログラム

|プログラム|役割|
|---|---|
|sendmail|sendmail互換I/F|
|smtpd|外部配送処理|
|pickup|maildropキューを監視し、内部配送を処理する|
|cleanup|ヘッダの書き換えなどを行って、incomingキューに入れ、qmgrに通知する|
|qmgr|キュー内のメールを配送プログラムに渡す|
|nqmgr|qmgrと同じだが配送アルゴリズムが異なる|
|master|全体の制御をするデーモン|
|bounce|バウンスメールの処理|次のページを参考にに

## 設定

|ファイル名|役割|
|---|---|
|main.cf|MTAとしての設定ファイル|
|master.cf|Postfixを構成する各種デーモンの設定ファイル|

### main.cf

```:main.cf
＃自ホスト名
myhostname = mail.example.com  

＃ドメイン名
mydomain = example.com

＃メールアドレスの@以降に適用されるドメイン名
myorigin =  $mydomain

＃ipv4に限定
inet_interfaces = all

＃ipv4に限定
inet_protocols = ipv4

＃ローカル配送を行うドメイン名（特定のドメイン名のメールを受信する）
mydestination =  $ myhostname, localhost.$mydomain, localhost, $mydomain

＃中継を許可するSMTPクライアントのアドレス
mynetworks = 192.168.1.0/24, 127.0.0.0/8

＃メールプールディレクトリ
mail_spool_directory = /var/spool/mail

＃ローカル配送を行うプログラム
mailbox_command =  /var/bin/procmail

＃SMTPで出力されるバナー情報
smtpd_banner = $myhostname ESMTP $main_name
```
- **postconf** : 全設定値が表示されます。
- **-n** オプションをつけると、デフォルト値から変更されている箇所のみが表示されます。
- パラメータを指定すると、指定したパラメータのみが表示されます。

## メールのリレー

リレー：MTA間でのメールの中継

他のホストに宛てたメールを受け取った場合、MTAはそのメールのリレーを許可すべきかどうか判断します。

- 基本
 - リレーを許可したいLAN内からのアウトバウンドメールは許可する。
 - リレーを許可したい場合ドメインのメールは許可する。
 - 外部からのアウトバウンドメールは拒否する。

**mydestination** や **mynetworks** で、適切な設定を行う。

## バーチャルドメイン

バーチャルドメイン：設定ファイルに含まれるドメイン名とは異なるドメインのメールも扱うことができる。(もちろん、MXレコードに登録されている必要がある。)

```:main.cf
virtual_alias_domains = example.net
virtual_alias_maps = hash:/etc/postfix/virtual
```

/etc/postfix/virtual には、どのユーザーにメールが届くか指定し、Postfix を再起動する必要がある。

```:/etc/postfix/virtual
postmaster@example.net postmaster
info@example.net info-net
```

```
# postmap /etc/postfix/virtual
```

## postfixコマンド

|サブコマンド|説明|
|---|---|
|check|設定ファイルの構文チェック|
|start|開始| 
|stop|停止|
|abort|強制停止|
|reload|設定を再読み込み|
|flush|キュー内にあるメッセージを再送する|

## ncコマンド

ncコマンドを使って、接続のテストを行えます。

|メソッド|説明|
|---|---|
|HELO ホスト|SMTPセッションを開始する|
|EHLO ホスト|拡張HELO|
|MAIL FROM:|メールの送信元を指定する|
|PCRT TO:|メールの宛先を指定する|
|DATA|メールの本文を開始する|
|QUIT|SMTPセッションを終了する|
|VRFYユーザー|ユーザーの確認|
|EXPNユーザー|ユーザーのエイリアスの確認|

## メールエイリアスと転送

### /etc/aliases

```:/etc/aliases
postmaster: taro,hanako
```

上記のユーザー名以外にも、次のような形式で指定することもできます。標準入力に送る例です。

```:/etc/aliases
linuc: |/home/linucuser/bin/mcheck
```

設定を反映ささせるには、**newaliases** を使います。
また、**postalias**　でエイリアスデータベースを指定して更新することもできます。

### .forward

**.forward**ファイルを作成すると、そのユーザー宛に届いたメールを、任意のメールアドレスに転送することができます。

```/home/linuc/.forward
test@mx.example.com
```

## SMTP認証

main.cf に次の設定を追加します。(SMTP認証に、dovecot を利用する例です。)

```:main.cf
smtp_sasl_type = dovecot
smtp_sasl_puth = private/auth
smtp_local_domain = $myhostname
smtp_sasl_security_options = noanonymos
broken_sasl_auth_clients = yes
smtp_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
```

認証タイプを、dovecot としたので、devecotの設定ファイルを編集します。

```:/etc/devecot/conf.d/10.master.conf
#Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
 mode = 0666
 user = postfix
 group = postfix
}
```

```:/etc/devecot/conf.d/10.auth.conf
auth_mechanisms = plain login
```

## SMTP over SSL/TLS

SMTP認証の場合、心配な点は、**PLAIN,LOGIN** が脆弱であるということです。その場合に、**SSL/TLS(SMTPS)** を導入します。

```:main.cf
smtpd_use_tls = yes
smtpd_tls_cert_file = /usr/share/ssl/certs/mail.toritonssl.com.cert
smtpd_tls_key_file = /usr/share/ssl/private/mail.toritonssl.com.key
```

```:master.cf
smtps inet n - n - - smtpd
-o smtpd_tls_wrappermode=yes 
-o smtpd_sasl_auth_enable=yes
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
```

telnet でローカルホストの Postfix に接続して確認し、「STARTTLS」という表示がされていればOK。

## メールキュー

|メールキュー|説明|
|---|---|
|maildrop|ローカル配信に使われる|
|incoming|送受信処理中のメールが保持される|
|active|配信待ちメールが保持される|
|deferred|送信に失敗したメールが暫く保持される|

- メールキューを確認する。
 - **mailq**
 - **postqueue -p**

- キュー内のメールを直ちに送信する。
 - **postqueue -f**
 - **postfix flush**

- キュー内のメールを削除する。
 - **postsuper -d** 

## ログ

`/var/log/messege` に保存される。

#アドレスの書き換え#

- 送信者アドレスを書き換えるパラメータ
 - sender_canonical_classes
 - sender_canonical_maps

- 受信者アドレスを書き換えるパラメータ
 - recipient_canonical_classes
 - recipient_canonical_maps

- 両方書き換える
　 - canonical_classes
　 - canonical_maps

①canonical_classes で書き換える対象を指定する。
②canonical_maps でアドレス変換のデータベースを指定する。
③指定したファイルを編集する。
　（例）@example.com @mylpic.com (@example.com を @mylpic.com に書き換える)
④postmapコマンドを実行して、データベースを作成する。
⑤postfixコマンドで設定をリロードする。

[Postfixで送信時にメールアドレスのドメインを付け替える](Postfixで送信時にメールアドレスのドメインを付け替える)

# Devecot

## 設定ファイル

|設定フィル|説明|
|---|---|
|devecot.conf|メイン設定ファイル|
|conf.d/10-auth.conf|ユーザー認証関連|
|conf.d/10-logging.conf|ログ関連|
|conf.d/10-mail.conf|メールの配送関連|
|conf.d/10-master.conf|基本動作|
|conf.d/10-ssl.conf|SSL/TLS関連|
|conf.d/15-lda.conf|ローカル配送関連|
|conf.d/20-imap.conf|IMAP関連|
|conf.d/20-pop3.conf|POP3関連|

### devecot.conf

|プロトコル|ポート番号|
|---|---|
|POP3|110|
|IMAP|143|
|POP3|995|
|IMAPS|993|

```:devecot.conf
protocolos = imap imaps pop3 pop3s 
```

### 10-auth.conf

|認証メカニズム|説明|
|---|---|
|plain|平文によるユーザー認証（RFC4616）|
|login|平文によるユーザー認証（標準仕様なし）|
|cram-md5|チャレンジレスポンスによるユーザー認証(RFC2195)|

```:10-auth.conf
auth_mechanisms = plain login
```

### 10-mail.conf

メールの配送場所と配送形式を指定する。

```:10-mail.conf
mail_location = maildir:~/Maildir
```

### 10-ssl.conf

```:10-ssl.conf
ssl = yes
```

## deveconf

**deveconf** : 設定値を表示する

## doveadm

|サブコマンド|説明|
|---|---|
|reload|設定を再読み込み|
|stop|停止|
|log find|ログファイルのパスを確認|
|log test|テストログメッセージの生成|
|pw|パスワードのハッシュ値を生成|
|mailbox|メールボックスの管理を行う。|
|who|接続しているユーザー一覧を表示する。|
|config|設定内容を表示する|

# 設定例

## 1.AレコードとMXレコードの作成

まず、**Aレコード**と**MXレコード**を作成する。
AWSサービスが好きなので、Route53を使って行います。
なお、ドメインは無料で取得できる [Freenom](https://www.freenom.com/ja/index.html) で登録し、NSレコードは既に登録済のものとする。

- ホスト名：mail.naata-swh.tk
- IPアドレス：*.*.*.*
- プライオリティ（優先順位）：10

念の為、dig で確認しておく。

```
# dig naata-swh.tk mx
```

## 2.AWSでメール送信制限解除を行う

今回はEC2上にメールサーバーを構築する。
AWSではスパム対策として、SMTPの利用が制限されているため、メール送信制限解除申請を行う必要がある。
申請方法については下記のAWSのナレッジを参考に行う。
[EC2 インスタンスからポート 25 の制限を削除するにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-port-25-throttle/)
※承認されるまで24時間程度かかる。

## 3.セキュリティグループの設定##

メールで利用する次のポートを開けておく。

- SMTP（25）
- SMTPS（465）
- IMAPS（993）
- POP3S（995）
- POP3(110)
- IMAP(143)

証明書は、フリーの Let's Encrypt を利用する。証明書更新に利用するため以下のポートも開けておく。

- HTTP（80）
- HTTPS（443）

## 4.Postfix設定

Amazon Linux 2 では Postfix がデフォルトでインストールされていいるので、後はSMTP認証に必要なパッケージのみをインストールする。

```
# yum install cyrus-sasl
# systemctl start saslauthd
# systemctl enable saslauthd
```

main.cf を更新します。パラメータの説明はこのページでも説明していますし、ググれば多数出てくるので割愛します。

```:/etc/postfix/main.cf
myhostname = mail.naata-swh.tk
mydomain = naata-swh.tk
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = 10.0.0.0/16, 127.0.0.0/8
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTP unknown

smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_unauth_destination
```

設定に誤りがないか確認し、問題がなければ、postfix を開始させましょう。

```
# postfix check
# systemctl restart postfix 
```

## 5.ローカルユーザー作成

```
# useradd testuser01
# passwd testuser01

# useradd testuser02
# passwd testuser02
```

## 6.test

Amazon Linux はデフォルトで mail コマンドが使えないので、インストールします。

```
# yum install mailx
```

testuser01ユーザーから、testuser02ユーザーへメールを送信してみます。

```
mail testuser02@naata-swh.tk
Subject: test
test
```

testuser02ユーザーにメールが届いているか確認します。

```
# ls -la /home/testuser02/Maildir/new/
total 4
drwx------ 2 testuser02 testuser02  62 Dec  6 11:52 .
drwx------ 5 testuser02 testuser02  39 Dec  6 11:52 ..
-rw------- 1 testuser02 testuser02 537 Dec  6 11:52 1607255523.Vca01I8066e8M374256.mail.naata-swh.tk
```

## 7.Let's Encrypt で証明書を取得する

次のページを参考に、証明書を取得する。
[Amazon Linux2でLet's Encrypt使おうとしたらコケた話](https://qiita.com/MysteriousMonkey/items/f26316447c1ff390ce21)

Python と pip が必須なようです。Pythonは既にインストールされていたので、pip のみインストールします。

```
# yum install python-pip
```

certbot-auto を入手し、権限設定する。

```
# cd /usr/local/bin
# wget https://dl.eff.org/certbot-auto
# chmod 700 certbot-auto
```
certbot-autoを修正する。

```:certbot-auto
elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then

#↑の部分を↓にように編集する。

elif grep -i "Amazon Linux" /etc/issue > /dev/null 2>&1 || \
  grep 'cpe:.*:amazon_linux:2' /etc/os-release > /dev/null 2>&1; then
```

修正した certbot-auto を利用して、証明書を取得する。

```
# ./certbot-auto certonly --standalone \
-d mail.naata-swh.tk \
-m user@naata-swh.tk \
--agree-tos -n

FATAL: Amazon Linux support is very experimental at present...
if you would like to work on improving it, please ensure you have backups
and then run this script again with the --debug flag!
Alternatively, you can install OS dependencies yourself and run this script
again with --no-bootstrap.
```

失敗したようなので、デバックモードで調べると、足りないパッケージがあるようなので、インストール後、再度証明書を取得する。

```
# ./certbot-auto --debug

# ./certbot-auto certonly --standalone \
-d mail.naata-swh.tk \
-m user@naata-swh.tk \
--agree-tos -n
```

次のとおり必要なファイルがインストールされる。

```:/etc/letsencrypt/live/mail.naata-swh.tk/
# ls -ls
total 4
0 lrwxrwxrwx 1 root root  41 Dec  7 04:10 cert.pem -> ../../archive/mail.naata-swh.tk/cert1.pem
0 lrwxrwxrwx 1 root root  42 Dec  7 04:10 chain.pem -> ../../archive/mail.naata-swh.tk/chain1.pem
0 lrwxrwxrwx 1 root root  46 Dec  7 04:10 fullchain.pem -> ../../archive/mail.naata-swh.tk/fullchain1.pem
0 lrwxrwxrwx 1 root root  44 Dec  7 04:10 privkey.pem -> ../../archive/mail.naata-swh.tk/privkey1.pem
4 -rw-r--r-- 1 root root 692 Dec  7 04:10 README
```

## 8.SSL/TLSの設定

main.cf で SMTP認証に、saslauthd を利用する設定へ変更する。

```:main.cf
message_size_limit = 20971520

smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_client_restrictions = permit_mynetworks,reject_unknown_client,permit
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination

smtpd_use_tls = yes
smtp_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.naata-swh.tk/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.naata-swh.tk/privkey.pem
smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
smtpd_tls_received_header = yes
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_timeout = 3600s
```

master.cf で必要な設定をコメントインしていく。

```:master.cf
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd
　#smtp      inet  n       -       n       -       1       postscreen
　#smtpd     pass  -       -       n       -       -       smtpd
　#dnsblog   unix  -       -       n       -       0       dnsblog
　#tlsproxy  unix  -       -       n       -       0       tlsproxy
submission inet n       -       n       -       -       smtpd
　#  -o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
　#  -o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
　#  -o smtpd_helo_restrictions=$mua_helo_restrictions
　#  -o smtpd_sender_restrictions=$mua_sender_restrictions
　#  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       n       -       -       smtpd
　#  -o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
　#  -o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
　#  -o smtpd_helo_restrictions=$mua_helo_restrictions
　#  -o smtpd_sender_restrictions=$mua_sender_restrictions
　#  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
```

saslauthd を起動、自動起動、postfix も再起動しておく。

```
# systemctl start saslauthd
# systemctl enable saslauthd
# systemctl restart saslauthd
```

## 9.devecotの設定

とりあえず、devecot をインストールしておく。

```
# yum install -y devecot
```

利用するプロトコルの設定をする。

```dovecot.conf
protocols = imap pop3
```

ポートや認証リスナーの設定をおこないます。

```:10-master.conf
service imap-login {
  inet_listener imap {
    port = 0
  }
  inet_listener imaps {
    port = 993
    ssl = yes
  }

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

service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
```

認証方式の設定をする。

```:10-auth.conf
disable_plaintext_auth = no

auth_mechanisms = plain login
```

SSL/TLSの有効化と証明書・秘密鍵を指定する。

```:10-ssl.conf
ssl = yes

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

メールボックスの場所を指定する。

```:10-mail.conf
mail_location = maildir:~/Maildir
```

ログを出力するディレクトリを作成し出力先を変更する。

```
# mkdir /var/log/dovecot
```

```:10-logging.conf
log_path = /var/log/
dovecot/dovecot.log
```

dovecot の開始と自動起動。

```
# systemctl start dovecot
# systemctl enable dovecot
```

## 10.ログローテーションの設定

Postfix用のログディレクトリを作成する。

```
# mkdir /var/log/mail
```

rsyslgの設定を変更する。

```:etc/rsyslog.conf
mail.*                                                  -/var/log/mail/maillog
```

Syslogサービスを再起動し、不要なログを削除する。

```
# systemctl restart rsyslog
# rm -f /var/log/maillog*　
```

rsyslogのログローテーションからメールのログを外します。

```:/etc/logrotate.d/syslog
# /var/log/maillog　　←　　削除
```

Postfixのログローテーションを作成する。

```:/etc/logrotate.d/maillog
/var/log/mail/maillog {
    daily
    missingok
    dateext
    rotate 60
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}
```

Dovecotもログローテーションも作成する。

```:/etc/logrotate.d/dovecot
/var/log/dovecot/dovecot.log {
    daily
    missingok
    dateext
    rotate 60
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /var/run/dovecot/master.pid 2>/dev/null` 2> /dev/null || true
    endscript
}
```

ログローテーションされるか確認する。

```
# logrotate -dv /etc/logrotate.d/maillog
# logrotate -dv /etc/logrotate.d/dovecot
```

新規ユーザー追加時、Maildir形式のディレクトリが自動で作成されるように設定しておく。

```
# sudo mkdir -p /etc/skel/Maildir/{new,cur,tmp}
# sudo chmod -R 700 /etc/skel/Maildir/
```

月1でLet's Encrypt証明書自動更新させるようにする。

```:/etc/cron.d/letsencrypt
00 05 01 * * root /usr/local/bin/certbot-auto renew -q --no-self-upgrade --deploy-hook "service postfix restart && service dovecot restart"
```

## 11.test

ユーザーを作成する。

```
# useradd -s /sbin/nologin testuser
# passwd testuser
```

お使いのメールソフトに必要な情報を設定する。

- メールアドレス：usertest03@naata-swh.tk
- パスワード：設定したパスワード
- 受信サーバー：IMAPS　mail.naata-swh.tk 993
- 送信サーバー：SMTPS　mail.naata-swh.tk 465

自分のGmailとかに送信テストする。


# リンク
[Amazon Linux 2上のPostfixでローカルユーザにメール配送してみた](https://dev.classmethod.jp/articles/ec2-postfix-local-delivery/)