nanisore oishisou

Webエンジニアあるまさんのゆるふわ奮闘記。

PHPでメール着弾時、メール本文をパースしDBへ格納する(1)〜メールサーバ構築編〜

大まかな流れ

  • 特定のメールアドレス宛のメールを受信したらPHPをキックするようにpostfixで設定

大まかなやること

  1. 目的のドメインにMXレコードを追加する
  2. 本番サーバにpostfixをインストール
  3. postfixの設定をする
  4. /etc/aliasesに着弾用ユーザ名を追加し、phpをキックさせるようにする

本番サーバにpostfixをインストール&設定手順

postfixがインストールしてあるか確認

yum list installed | grep postfix
cd /etc/postfix
which postfix

インストールしてなかったらyumでインストール

sudo yum -y install postfix

インストールしてある人はmtaの確認

sudo alternatives --config mta

2 プログラムがあり 'mta' を提供します。

  選択       コマンド
-----------------------------------------------
*  1           /usr/sbin/sendmail.sendmail
 + 2           /usr/sbin/sendmail.postfix

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:

こんなふうにsendmail.postfixが選択されていたらEnterを押して終了する。 sendmail.sendmailだった人は、周りに確認してからsendmail.postfixに変更。

MXレコードの確認

nslookup -type=mx example.com                                                                                                                                                     
Server:     192.168.0.1
Address:    192.168.0.1#53

Non-authoritative answer:
example.com     mail exchanger = 10 mx1.example.com.

こんな感じでNon-authoritative answerのところに追加したMXレコードがでてくればOK。

DNSの更新が遅い場合があるので、そんな時はGoogle Public DNSを指定して問合せてみるとすでに反映されている可能性がある。

nslookup -type=mx example.com 8.8.8.8                                                                                                                                                   12:48:32
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
example.com mail exchanger = 10 example.com.

Authoritative answers can be found from:

ひとまずメール送信できるかテスト

sendmail watashi_no_address@example.co.jp
From:test@example.com
To:chakudan@example.com

Subject:テスト送信

テスト送信してみました。てへぺろ
.

この段階では送れはするが送信元アドレスとかいろいろおかしい。

迷惑メールフォルダに入ってる可能性もあるので、そっちもチェックしたほうがいい。

メールログで送信できてるか確認

sudo cat /var/log/maillog

status=sentになってれば送れてる

Postfix設定

main.cfというのがPostfixの設定ファイルなので、それを編集して設定していく。

SMTP認証関係の設定も同時に行う。

今回は受信が必要なので、受信用の設定も同時に行う。

sudo cp main.cf main.cf.org
sudo vi main.cf

▼main.cf

myhostname = mx1.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 192.168.0.0/24, 127.0.0.0/8
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

home_mailbox = Maildir/

smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_unauth_destination
smtpd_sasl_security_options = noanonymous

※inet_interfacesとmydestinationは外部からメールを受け付ける受信用の設定

master.cfの設定もしていく

sudo cp master.cf master.cf.org
sudo vi master.cf

master.cfの以下の行をコメントインする

▼master.cf

submission inet n       -       n       -       -       smtpd
  -o smtpd_sasl_auth_enable=yes
   -o smtpd_client_restrictions=$mua_client_restrictions

postfixを再起動する

sudo service postfix restart

Postfix自動起動設定

sudo systemctl enable postfix
sudo systemctl start postfix

SMTP認証に使われるsaslをインストールする

sudo yum install cyrus-sasl

自動起動設定

sudo systemctl start saslauthd
sudo systemctl enable saslauthd

saslの設定

sudo cp /etc/sasl2/smtpd.conf /etc/sasl2/smtpd.conf.org
sudo vi /etc/sasl2/smtpd.conf

▼smtpd.conf

pwcheck_method: auxprop
mech_list: plain login

ユーザーディレクトリの雛型を設定しメール用のディレクトリをデフォで作る

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

着弾用ユーザを追加

sudo useradd chakudan
sudo passwd chakudan

追加したユーザにSMTP認証用パスワードを設定

sudo saslpasswd2 -u mx1.example.com chakudan

saslのユーザーリストに登録されているか確認

sudo sasldblistusers2

パーミッションの変更

sudo chgrp postfix /etc/sasldb2
sudo chmod 640 /etc/sasldb2

postfixとsaslを再起動

sudo systemctl restart postfix
sudo systemctl restart saslauthd

外部からメールを受信させる設定

25番ポート開いてるか確認(外から)

↓こんな感じで返って来たら開いてる

telnet mx1.example.com 25
Trying xx.xx.xx.xx...
Connected to mx1.example.com.
Escape character is '^]'.
220 mx1.example.com ESMTP Postfix

↓こんな感じで返って来たら開いてない

Trying xx.xx.xx.xx...
telnet: connect to address xx.xx.xx.xx: Connection refused
telnet: Unable to connect to remote host: Connection refused

※ポートの確認をするのはドメインに対してではなく、MXレコードで追加したメールサーバのホストネームのほうで確認しないと意味ない。MXレコードのIPを記述ミスするとハマる。

25番ポートを開ける

まずはクラウド側でポート解放設定があったらそれを先にやる

それだけで解放できない場合はサーバ側からも解放する

まずは開いてるポートの確認

sudo firewall-cmd --list-ports --zone=public
xxx/tcp

25が開いてない人は開ける

sudo firewall-cmd --add-port=25/tcp --zone=public

このままだと再起動するとポートが閉じてしまうので再起動しても開いてくれる設定をする

sudo firewall-cmd --reload
sudo firewall-cmd --add-port=25/tcp --zone=public --permanent
sudo firewall-cmd --reload

25番ポート開いてるか再確認

telnet mx1.example.com 25

サーバローカルで認証のテスト

Base62でユーザ名とパスワードをエンコードしておく

perl -MMIME::Base64 -e 'print encode_base64("chakudan\0chakudan\0password");'

telnetで認証のテストをする

telnet localhost 25
EHLO localhost
AUTH PLAIN Y2hha3VkYW4AY2hha3VkYW4AcGFzc3dvcmQ=

235 2.7.0 Authentication successfulが表示されたら認証OK。

上記のパスワードは、chakudanユーザのOSログインパスワードではなくSMTP認証用パスワードで設定したパスワード。

転送設定

ひとまず自分のアドレスへ転送設定をしておく

sudo cp /etc/aliases /etc/aliases.org
sudo vi /etc/aliases

▼aliasesの一番下にこれを追加

chakudan: chakudan, watashi_no_address@example.co.jp

chakudanは着弾用ユーザ名
watashi_no_address@example.co.jpは自分が普段使ってるgmailのアドレスなんかにしておけばいいと思う。

aliasの設定を反映

sudo newaliases

テスト送信

普段使ってるgmailなどのメーラーからchakudan@example.comにテストメールを送信してみる。

サーバ側の/home/chakudan/Maildirにメールが届いていて、watashi_no_address@example.co.jpにも同じメールが転送されていれば、サーバ側の設定は完了。

ついでにPOP3サーバの設定もする

dovecotをインストールする

sudo yum install dovecot

dovecotの設定

sudo cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.org
sudo vi /etc/dovecot/dovecot.conf

dovecot.confの以下をコメントイン

protocols = imap pop3 lmtp
sudo cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.org
sudo vi /etc/dovecot/conf.d/10-auth.conf

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

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

▼10-auth.conf

disable_plaintext_auth = no

▼10-mail.conf

mail_location = maildir:~/Maildir

▼10-ssl.conf

ssl = no

dovecotの起動設定

sudo systemctl start dovecot
sudo systemctl enable dovecot

pop用ポートを解放

クラウド側で110番ポートを解放

サーバ側ポート解放

sudo firewall-cmd --add-port=110/tcp --zone=public --permanent

ポートが開いてるか確認

sudo firewall-cmd --list-ports --zone=public
telnet example.com 110

メーラーに設定して送受信のテストを行う。

送信も受信もできれば、メールサーバの構築は完了。

めでたし、めでたし。

次回は、PHPをキックしてメールをパースしてDBに格納するよっ♥

お楽しみにね★