契約していたサーバーが古くなってしまったため、新しく契約した CentOS 7 にメールサーバーを移行しました。 本稿では、その移行作業の記録を共有したいと思います。
構築するメールサーバーの概要
まずは、構築するメールサーバーの概要について説明します。
- 構築するサーバーのメールアドレスは、 xxxxx@myhost.com のように @myhost.com のドメインを持つこととします。
- 構築するサーバーのホスト名は mail.myhost.com とし、DNS の MX レコードに登録することとします。
- 受信したメールは、全て Gmail の別のメールアドレス宛に転送します。
- Gmail の画面から独自ドメイン(@myhost.com)のメールアドレスでメールを送信できるようにします。
このように、利用者に対して Gmail がフロントになることがポイントです。 Gmailをフロントとする理由は、以下の通りです。
- 自メールサーバー内にメールを保存したくない。
- 普段使い慣れている Gmail の操作性の恩恵を受けたい。
このようなポリシーにより、対外的には独自ドメインのメールアドレスを周知できますが、実質のメールの管理を Gmail の機能に頼ることができます。
事前知識
手順の説明をはじめる前に、メールサーバーを構築するにあたり必要な知識について、軽くおさらいします。
MTA (Mail Transfer Agent)
インターネットにおいて、メールを送信・転送する役割を担うソフトウェアを MTA (Mail Transfer Agent) といいます。 CentOS 7 ではデフォルトで Postfix というソフトウェアがインストールされています。 他に有名な MTA としては、Sendmail や qmail などのソフトウェアがありますが、今回は CentOS 7 にデフォルトでインストールされている Postfix を利用します。
SMTP, SMTPS
コンピュータ間でメールを転送するプロトコルは SMTP (Simple Mail Transfer Protocol) です。 SMTP は通常、TCPのポート番号 25 を利用します。 ただし SMTP は暗号化せずに通信を行うプロトコルですので、通信経路で盗聴があった場合にメールの内容が漏洩するリスクがあります。
それを解決するために、SMTP の通信を SSL もしくは TLS で暗号化した SMTPS があります。 SMTPS はポート番号 465 を利用します。 SSL や TLS での暗号通信には証明書が必要ですが、本稿では無償で証明書を発行してくれている Let’s Encrypt を利用して証明書を取得します。
完成イメージ
構築するメールサーバーの完成イメージとしては次の通りです。
- SMTP 25番ポートへの接続を待ち受け、メールを受信する。 (クライアントが暗号通信に対応していない場合向け)
- SMTPS 465番ポートへの接続を待ち受け、メールを受信する。 (クライアントが暗号通信に対応している場合向け)
- 受信したメールはローカルに保存せず、/etc/aliases の設定により Gmail に転送する。
- 別メールサーバーにメールを送る際に、相手が暗号通信をサポートする場合は暗号通信する。
セットアップ
さて、それでは具体的なセットアップ手順について確認してみましょう。 セットアップの手順は次のようになります。
- DNS の MX レコードを設定する。
- Postfix をインストールする。
- Let’s Encrypt で SSL 証明書を発行する。
- Postfix の設定を変更する。
- エイリアス設定をする。
- Firewalld の設定を変更する。
1. DNS の MX レコードを設定する
まずはメールアドレスのドメインを解決できるようにするために DNS の MX レコードを設定してください。 この作業は CentOS 7 上での構築作業ではありませんが、メールサーバーを構築する上で必要な作業です。
本稿では、メールアドレスのドメインは myhost.com ですが実際のメールサーバーは mail.myhost.com というサーバーとしますので、DNS の MX レコードに次のように設定します。 また mail.myhost.com をサーバーのIPアドレスと紐づける A レコードも登録しています。
myhost.com. IN MX 10 mail.myhost.com.
mail.myhost.com IN A 10.x.x.xxx
2. Postfix をインストールする
CentOS 7 には Postfix がデフォルトでインストールされているはずです。 次の例のコマンドで、Postfix がインストールされていることを確認しましょう。 次の例では Postfix 2.10 がインストールされていることが分かります。
# yum list installed | grep postfix
postfix.x86_64 2:2.10.1-6.el7 @base
もし上のコマンドで何も表示されなかった場合は、 次のように yum install コマンドで Postfix をインストールしてください。
# yum install postfix
3. Let’s Encrypt で SSL 証明書を発行する
新しく構築するメールサーバーが暗号された通信を提供できるように、SSL/TLS暗号用の証明書を発行します。証明書は、無償で SSL/TLS証明書を発行してくれる Let’s Encrypt を利用します。
CentOS 7 に Let’s Encrypt をインストールして証明書を発行するまでの手順については、「CentOS 7 + Apache 2.4 に Let’s Encrypt の証明書を導入する手順」を参考にしてください。 ここでは mail.myhost.com に対して証明書を発行しました。
4. Postfix の設定を変更する
さて、ここからはメールサーバーソフトウェアである Postfix の設定です。 まず知っておくべきことは、Postfix の設定ファイルの種類です。 Postfix の設定ファイルは /etc/postfix フォルダにまとまってあります。 その中で本稿で編集するファイルは、master.cf と main.cf になります。
ホスト名などの基本設定
まずは main.cf の設定から行います。 main.cf をエディタで開き、まずはメールサーバーのホスト名を設定します。 DNS の MX レコードに登録したホスト名を設定します。
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = host.domain.tld
#myhostname = virtual.domain.tld
myhostname = mail.myhost.com
次にメールアドレスのアットマーク以降に現れるドメイン名を設定します。
# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = domain.tld
mydomain = myhost.com
このメールサーバーから送信されるメールで利用されるドメイン名を設定します。 上で設定した mydomain そのままのため、 $mydomain という変数を設定しています。
# The myorigin parameter specifies the domain that locally-posted
# mail appears to come from. The default is to append $myhostname,
# which is fine for small sites. If you run a domain with multiple
# machines, you should (1) change this to $mydomain and (2) set up
# a domain-wide alias database that aliases each user to
# user@that.users.mailhost.
#
# For the sake of consistency between sender and recipient addresses,
# myorigin also specifies the default domain name that is appended
# to recipient addresses that have no @domain part.
#
#myorigin = $myhostname
#myorigin = $mydomain
myorigin = $mydomain
このマシンでメールを受信するネットワークインターフェースを設定します。 ここでは全てのネットワークインターフェースを対象とするため、次のように all を設定します。
# The inet_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on. By default,
# the software claims all active interfaces on the machine. The
# parameter also controls delivery of mail to user@[ip.address].
#
# See also the proxy_interfaces parameter, for network addresses that
# are forwarded to us via a proxy or network address translator.
#
# Note: you need to stop/start Postfix when this parameter changes.
#
#inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
#inet_interfaces = 127.0.0.1
inet_interfaces = all
送られてきた(受信した)メールのうち、このサーバーで受け取るべきドメインを指定します。 ここでは “mail.myhost.com”, “myhost.com” と、”localhost” も指定しています。
# The mydestination parameter specifies the list of domains that this
# machine considers itself the final destination for.
#
# These domains are routed to the delivery agent specified with the
# local_transport parameter setting. By default, that is the UNIX
# compatible delivery agent that lookups all recipients in /etc/passwd
# and /etc/aliases or their equivalent.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain.
#
# Do not specify the names of virtual domains - those domains are
# specified elsewhere (see VIRTUAL_README).
#
# Do not specify the names of domains that this machine is backup MX
# host for. Specify those names via the relay_domains settings for
# the SMTP server, or use permit_mx_backup if you are lazy (see
# STANDARD_CONFIGURATION_README).
#
# The local machine is always the final destination for mail addressed
# to user@[the.net.work.address] of an interface that the mail system
# receives mail on (see the inet_interfaces parameter).
#
# Specify a list of host or domain names, /file/name or type:table
# patterns, separated by commas and/or whitespace. A /file/name
# pattern is replaced by its contents; a type:table is matched when
# a name matches a lookup key (the right-hand side is ignored).
# Continue long lines by starting the next line with whitespace.
#
# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
#mydestination = $myhostname, localhost.$mydomain, localhost
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
別メールサーバーへメール送信する場合のSMTP設定
Postfix から別メールサーバーへメールを送信する際の設定を行います。 つまり、あなたの Postfix がメールクライアントとなる場合の設定です。 次の設定は、main.cf の最終行などに新たに追加します。
相手となるメールサーバーが暗号通信(TLS)に対応している場合は、暗号通信を行った方が良いことは言うまでもありません。 smtp_tls_security_level の値を may に設定すると、暗号通信できる場合に暗号通信を行います。
smtp_tls_security_level=may
通信相手となるメールサーバーの証明書を検証するための、ローカルにインストールされているルート証明書ファイルを指定します。
smtp_tls_CAfile = /etc/pki/tls/cert.pem
暗号通信を行った場合にログを出力するように、次のように設定します。 もしログの出力が必要なければ「0」を設定します。
smtp_tls_loglevel = 1
なお、「サーバーAの場合は暗号化しない、サーバーBの場合は暗号化する」といったように、通信するメールサーバー個別に暗号化の有無を設定することもできますが、本稿では説明を割愛します。
メールを受信する場合の暗号設定
メールサーバーとして、メールをクライアントから受信する場合の暗号通信の設定を行います。 次の設定も main.cf の最終行などに新たに追加します。
TLSの暗号通信を有効にする指定をします。
smtpd_use_tls = yes
暗号通信はクライアントが対応している場合にのみ行うことを指定します。
smtpd_tls_security_level = may
暗号通信するのに利用する証明書を指定します。 ここで指定するのは、上で Let’s Encrypt で発行した証明書ファイルです。 次の例の mail.myhost.com となっている部分は、あなたがお持ちのドメインになります。
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.myhost.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.myhost.com/privkey.pem
暗号通信を行った場合にログを出力するように設定します。 ログの出力が必要ない場合は「0」を設定します。
smtpd_tls_loglevel = 1
ここまでで main.cf の編集は終了です。
master.cf の変更
次に master.cf ファイルを変更します。 設定としては、行頭のコメントを外すだけの設定です。
まず SMTPS を有効にするため、smtps の行のコメントを外します。 また、SMTPS で通信する際に TLS のラッパーモードを使うように -o オプション行のコメントを外します。
#
# Postfix master process configuration file. For details on the format
# of the file, see the master(5) manual page (command: "man 5 master").
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# 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
ここまでで Postfix の設定は完了です。
5. エイリアス設定をする
メールユーザーのエイリアスを設定できるファイルとして /etc/aliases ファイルがあります。 どんな設定ができるのかは、次の例を見てもらった方が早いでしょう。 メールアドレスのユーザー名に対して、実体を設定できます。 次の例では hogemoge というユーザーに対して、 hogemoge@gmail.com という実体のメールアドレスを設定しています。
hogemoge: hogemoge@gmail.com
このように /etc/aliases ファイルの末尾に、ユーザー名を実体のメールアドレスを対になるように追記します。 設定するユーザー名に対して、Linux ユーザーがいなくても大丈夫です。 好きなだけメールアドレスアカウントを作成することができます。 また、メールアドレスはカンマ区切りで複数設定することができますので、メーリングリストのようなものも実現可能です。
/etc/aliases ファイルの変更が完了したら、 newaliases コマンドで設定を再読み込みします。
# newaliases
6. ファイアウォール(firewalld)の設定を変更する
CentOS 7 では、デフォルトでファイアウォール機能(firewalld)が有効になっていますので、SMTP(25) や SMTPS(465) のポートに対して外部から接続することができません。 念のためファイアウォール機能(firewalld)が有効になっていることを次のように systemctl コマンドで確認します。
# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Active: active (running) since Mon 2017-05-01 15:09:59 UTC; 2s ago
コマンドの実行結果の Active の値が active (runnning) となっていれば、ファイアウォールが有効になっています。 逆に inactive (dead) となっている場合は無効になっています。
現時点でファイアウォールが外部に向けて開放しているサービスは、次のような firewall-cmd で確認できます。 次の例だと、dhcpv6-client と ssh のサービスが開放されています。
# firewall-cmd --list-services --zone=public --permanent
dhcpv6-client ssh
ここでは外部に対して SMTP と SMTPS のポートを開放したいので、次のようなコマンドで開放するサービスを追加し、ファイアウォールの設定をリロードします。
# firewall-cmd --add-service=smtp --zone=public --permanent
# firewall-cmd --add-service=smtps --zone=public --permanent
# firewall-cmd --reload
これで SMTP と SMTPS のポートが外部に向けて開放されました。
その他の注意事項
- ローカルのコンピュータや自宅サーバーにメールサーバーを構築しようとした際に、契約しているプロバイダーが Outbound port 25 Blocking(OP25B) をしていて、25番ポートでインターネット向けにメールを送信できなくしている場合があるので注意が必要です。
- さくらインターネットの「さくらのVPS」などでサーバーを借りた際に、お試し期間だと外部に向けてメールが送信できなくなっている場合があります。 そのような場合は、本契約する必要があります。
メール受信/転送の動作確認
上記のセットアップにより、メールサーバーが機能するようになったはずです。 実際にメールを送ってみて、Postfix がメールを受信して転送することを確認しましょう。 動作確認の際にはログを表示しながら確認するのが良いでしょう。 Postfix のログファイル /var/log/maillog を tail で表示すると良いでしょう。
# tail -f /var/log/maillog
/etc/aliases ファイルに設定したユーザー名に対してメールを送信し、対になるように設定したメールアドレスにメールが転送されていれば良いでしょう。
Gmail から独自ドメインのメール送信
Gmail には、Gmail アカウントのメールアドレスとは違う、別のメールアドレスでメールを送信できる機能があります。 もちろん、その別のメールアドレスを所有していることの証明確認が必要になります。 その機能を利用することで、本稿で構築したメールサーバーのメールアドレスでメールを送信できるようになります。
設定方法については Gmail のヘルプページに手順がありますので、「別のアドレスやエイリアスからメールを送信する」を参考にしてください。
おわりに
本稿では CentOS 7 に Postfix で転送用メールサーバーを構築する手順について解説しました。