TL;DR
情報処理安全確保支援士でメールサーバーが試験範囲となります。
理屈は書籍の上で学べるのですが、実際に構築・使用してみようということで、まずはSMTPサーバーを構築しようという試みです。
LPIC Lv.2の試験範囲でもありますので、筆者にとっては復習。
LPIC Lv.2を受験しようと考えられている方にとっても勉強になると思います。
なお、今回はGCEに構築したサーバーではなくdokcerに構築したRocky Linux環境でSMTPサーバーを構築しています。
理由はGCEだとTCP25番ポートが使えず587番ポートを利用したりと、SMTPサーバーに関する制約が存在しているので、それを回避するためです。
docker環境
dockerそのものはインストール済みと仮定します。
dockerファイルとdocker-compose.ymlはこんな感じです。
必要最低限(osイメージ)しか入れてません。
ポートに関してはとりあえずhttp,https,ftp,smtpのみの設定。
smtpだけあればまあいいのですが、あとに再利用することも考えてとりあえずということで。
version: "3"
services:
infrastudy:
build:
context: ./docker
dockerfile: Dockerfilecentos8
hostname: infrastudy
ports:
- 80:80
- 443:443
- 20:20
- 21:21
- 25:25
stdin_open: true
tty: true
privileged: true
command: /sbin/init
FROM centos:centos8
CMD ["/sbin/init"]
ファイルを作ったら、docker-compose up していきます。
postfix, rsyslog, telnetをインストールしていく
dockerが立ち上がってコンテナ内に入ったら、今回必要なソフトをインストールしていきます。
まずはpostfixから。
意気揚々とyum installするといきなりエラーが。
エラー1 Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
これまでGCEのRocky環境ではでなかったエラーが出てきた。
リポジトリリストのURLがない的なことを言われてますね。
エラーをググっていると以下のサイトにたどり着く。
上記のサイトを参考にしたところ、リポジトリリストのURLを過去バージョンも含めてパッケージが公開されているURLへ向けてやる必要があることを知ります。
GCEのRockyだとそんなことを設定した覚えもないので、おそらくGCEが勝手にやってくれているのではないかという説。
とりあえず、上記のサイトで紹介されていたコマンドを叩きます。
以下のふたつです。
[root@infrastudy /]# sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*
[root@infrastudy /]# sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*
このふたつを実行後、再度yum intallします。
エラー解消されたと思いきや、別のエラーが表示されています。
エラー2 Failed to set locale, defaulting to C.UTF-8
LOCALEが設定されてないということで、またもググる。
今度はQiitaの以下のページを参考に解決。
https://qiita.com/ponsuke0531/items/699fcc0eca59f9b10217
単に環境変数をセットしてあげるだけみたいです。
[root@infrastudy /]# export LC_ALL=C
これでyumを使う準備が整ったはず。
各種インストール
[root@infrastudy /]# yum install -y postfix
[root@infrastudy /]# yum install -y rsyslog
[root@infrastudy /]# yum install -y telnet
postfixはいわずもがな。
rsyslogはメール送信時のログを出力するために必要となります。
telnetは実際にSMTPコマンドを叩くために使用します。
postfixの設定
ここからはpostfixでメール送信を行うための準備をしていきます。
とはいっても難しいことは特段ありません。
以下のサイトを参考にしています。
https://www.rem-system.com/mail-postfix01/
設定ファイルの場所
postfixの各種設定ファイルは/etc/postfixにあります。
「各種」と言っているのはpostfixは設定ファイルが1種類ではないからです。
主にmain.cfとmaster.cfという二種類の設定ファイルを持ちます。
main.cfはMTAとしての基本設定ファイル。
master.cfはpostfixを構成する各種デーモンの設定ファイルです。
今回主に触っていくのはmain.cfで、LPIC Lv.2の試験においても主に問われるのはmain.cfの設定項目です。
まずは元の設定ファイルをバックアップ
[root@f7465ed7389d /]# cp /etc/postfix/main.cf /etc/postfix/main.cf.org
この時点でpostfixを起動してみると?
[root@infrastudy /]# systemctl restart postfix
残念ながら怒られます。
Job for postfix.service failed because the control process exited with error code.
See "systemctl status postfix.service" and "journalctl -xe" for details.
なぜ怒られるのか?文法チェック
postfixはbindやapacheと同様に設定ファイルの文法チェックコマンドがあるのでそれを使います。
[root@infrastudy /]# postfix check
するとまあ案の定怒られています。
postfix: fatal: parameter inet_interfaces: no local interface found for ::1
エラーの内容でググり、行き当たったサイトがこちら。
http://akira-arets.blogspot.com/2018/11/linux-centos7-docker-postfix-rsyslog.html
どうやらipv6のインターフェースを使用するという設定になっているにもかかわらず、ipv6用のネットワークインターフェースがないよってことでエラー見たいです。
ipv6なんぞ使わないので、未使用にするようmain.cfの設定を以下のように書き換えます。
(抜粋)
# inet_protocols = all
inet_protocols = ipv4
書き換え後、再度文法チェックすると今度は怒られなくなりました。
telnetでlocalhostに接続してメール送信
ここまででpostfixからメール送信を行う準備は整ったので、いよいよtelnetで接続し、メール送信を行います。
[root@infrastudy /]# telnet localhost 25
上記のコマンドを叩いた後、以下のように表示され入力待ちになれば成功です。
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 infrastudy.localdomain ESMTP Postfix
ここからは情報処理安全確保支援士でも問われる内容です。
SMTPセッションの開始
SMTPコマンド・heloを入力。
helo localhost
以下の表示が出れば成功。
250 infrastudy.localdomain
250から後ろの表示は環境によって変わります。
なおheloコマンドの拡張版としてehloも使えますが、役割はほぼ同じです。
送信元の指定
送信元 MAIL FROMを指定します。
ここで指定した内容が受信者側では送信元として表示されます。
つまり、MAIL FROM = 送信元ドメイン名ではないので、送信元を詐称することが可能です。
mail from: test@docker.infrastudy
以上のように入力し、以下のように表示されれば成功です。
250 2.1.0 Ok
今回自分が使っている環境はローカルマシンのdocker環境なのでドメインもへったくれもないのですが、これで送信元が「docker.infrastudy」ということになりました。
後ほど受信メールを確認してみましょう。
送信先の指定
ここでは実際にメール受信可能なアドレスにしてください。
rcpt to: 送信先メールアドレス@gmail.com
以上のように入力し、以下のように表示されれば成功です。
250 2.1.5 Ok
メール本文の指定
data
を入力しエンターを押下すると次のような表示が出るはず。
354 End data with <CR><LF>.<CR><LF>
以降で本文を入力していきます。
「.」を入力しエンターを押下すると、本文の入力終了とみなされます。
250 2.0.0 Ok: queued as E46EE865D4
以上のように表示されれば成功です。
キューにメールが入ったことが分かります。
メール送信の終了
quit
メール送信ログの確認
postfixのメール送信ログは、/var/log/maillogです。
catで内容を確認してみましょう。
May 5 00:03:12 infrastudy postfix/qmgr[757]: E46EE865D4: from=<test@docker.infrastudy>, size=339, nrcpt=1 (queue active)
May 5 00:03:14 infrastudy postfix/smtp[772]: E46EE865D4: to=<送信先メールアドレス@gmail.com>, relay=gmail-smtp-in.l.google.com[142.251.8.26]:25, delay=75, delays=72/0.03/1.7/0.74, dsn=2.0.0, status=sent (250 2.0.0 OK 16517
relay=gmail-smtp-in.l.google.comによりgoogleのメールサーバー(142.251.8.26の25番ポート)を経由し、status=sentより送信されたことが分かります。
受信メールの確認

あたかもtest@docker.infrastudyというアドレスから来たように見えてますね。
まとめ
以上、postfixを使ったSMTPサーバー構築編でした。
次回はdovecotで受信もできるようにする…予定です。
お疲れ様でした。