はじめに
どうも、インフラエンジニア見習い (というか社会人見習い。。) の新卒1年目です🙇
職場にて SMTPについて学ぶ機会があったので、プライベートで実践的に復習してみようと思い少し遊んでみました。
自分が再度、同様の環境を構築する際の手順書を作る気持ちで執筆しています。
環境
- サーバー : EC2 t2.micro(AmazonLinux2)
- Postfix : ver 2.10.1
作業
1. SMTPクレデンシャルの発行
Postfixからのメール送信を SES経由にする際に必要です。
まずはSESのセットアップ画面を開きましょう
SMTP設定 を開きます
SMTP認証情報の作成 をクリック
IAMユーザーの作成画面が開かれるので、メールの送信権限があるか確認し、ユーザーの作成 をクリック
ユーザーの作成が完了したら SMTPクレデンシャルの秘匿情報が表示されます。
次の 2. Postfix の設定 で使用するので保存しておきましょう
必要な情報は以下2つです
- SMTP ユーザー名
- SMTP パスワード
2. Postfix の設定
AmazonLinux には Postfixがプリインストールされているので 手動でのインストールは不要です
まずはバージョンを確認してみましょう
$ postconf | grep mail_version
mail_version = 2.10.1
自動起動も有効化してしまいましょう
$ sudo systemctl enable postfix
次に、Postfixの設定をしていきます
Postfix の設定は /etc/postfix/main.cf
を編集、記載します
# メールサーバーの情報を記載
myhostname = mail.example.com
mydomain = example.com
mydestination =
# SESを経由させる設定を記載
relayhost = [email-smtp.ap-northeast-1.amazonaws.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
設定パラメータの内容は <Tips> 設定パラメータの詳細 にまとめましたのでそちらを参考になさって下さい🙏
次に、Postfix に SESコンソール で作成した SMTPクレデンシャル を認識させるためのファイルを作成します。
$ sudo vim /etc/postfix/sasl_passwd
1. SMTPクレデンシャルの発行 で保存しておいた秘匿情報を記載しましょう
[email-smtp.ap-northeast-1.amazonaws.com]:587 <SMTP ユーザーネーム>:<SMTP パスワード>
作成したファイルを postmap
コマンドでハッシュ化しましょう。 引数hash:
を指定してハッシュ化します
$ sudo postmap hash:/etc/postfix/sasl_passwd
ファイルを 管理者のみ閲覧、編集できるように権限変更をしましょう
$ sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
$ sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
chmod 600 って何?
chmod コマンドではファイルの権限を編集します(キーペア作成時とかよく使うよね)
以下のようになっています
- 100の位 : 管理者ユーザーの権限
- 10の位 : グループアクセスの権限
- 1の位 : その他のユーザーのアクセス権限
また、各位の数字は権限に対応する数字の合計となっています
- 4 : 読み出し許可
- 2 : 書き込み許可
- 1 : 実行許可
- 0 : 権限なし
結論
管理者ユーザーの位(100の位)のみ、 読み出し許可(4) + 書き込み許可(2) = 6
となっているのです(他の位は権限なしで 0)
参考記事: chmod 600 ←600ってなんやねん
最後に、Postfix に変更を読み込ませるために再起動をしましょう
$ sudo systemctl restart postfix
<Tips> 設定パラメータの詳細
/etc/postfix/main.cf
に設定したパラメータの詳細を記載します。
すでに内容把握されている方は読み飛ばして下さい 🙏
※適宜、お手元の環境の設定値として正しいか 以下公式ドキュメントの日本語訳 と照らし合わせて設定して下さい。
- myhostname
- SMTP サーバーの FQDN を指定
- デフォルト値: "postconf -d" の出力を参照
FQDN(Fully Qualified Domain Name) とは
ホスト(サーバーの名前) + ドメイン(サーバーが所属するグループの名前) で構成されたサーバーのアドレスのこと
例 : mail(ホスト) + excompany.com(ドメイン) -> mail.excompany.com(FQDN)
- mydomain
- myhostname のドメイン部分を指定
- デフォルト値: "postconf -d" の出力を参照
- mydestination
- 他のマシンに転送するのではなく、 メールをローカルで受信するドメイン名を指定
- デフォルト値: $myhostname, localhost.$mydomain, localhost
- 今回は、同じドメイン向けにメールを配信するため、空欄にします(指定しているとSESリレーされない)
- relayhost
- next-hop配送先(中継サーバー)を指定
- デフォルト値: empty
- SMTP の場合、ドメイン名、ホスト名、hostname:port、[hostname]:port、 [hostaddress] または [hostaddress]:port を指定
- smtp_sasl_auth_enable
- Postfix SMTPクライアントの SASL 認証を有効化
- デフォルト値: no
- smtp_sasl_security_options
- SASL認証のオプションを設定
- デフォルト値: noanonymous
- 以下オプションがある
- noplaintext
- 平文パスワードを使う方法を許可しない
- noactive
- active (非辞書) 攻撃を受けるような方法を許可しない
- nodictionary
- passive (辞書) 攻撃を受けるような方法を許可しない
- noanonymous
- 匿名認証を認めるような方法を許可しない
- mutual_auth
- 相互認証を提供する方法のみを許可 する
- noplaintext
- smtp_sasl_password_maps
- SASLの認証情報が記載されたファイルの場所を指定
- デフォルト値: empty
- smtp_use_tls
- リモートSMTPサーバがSTARTTLSサポートを案内したら TLSを使い、案内がなければ平文でメールを送る (Postfix 2.2以降)
- SES では STARTTLS がサポートされているので TLS を使うために有効化する
- デフォルト値: no
- smtp_tls_security_level
- Postfix SMTPクライアントでのSMTP TLSセキュリティレベル を設定
- デフォルト値: empty
- 以下設定値
- (empty):
- smtp_tls_policy_maps で特定の配送先に対してTLSが有効にされない限り、TLSは使われない
- may:
- サーバがサポートしていればTLSが使われる
- すべてのプロトコルが許可され、"export" グレード以上の暗号(1990年代の頃の強度40bit以下の弱い暗号化形式らしい)が使われる
- encrypt:
- TLS暗号化を強制
- 暗号化ができなければ、その相手にはメールを送れない
- もっとも安全だが、すべての相手が対応しているとは限らないので注意が必要
- verify:
- TLS暗号化を強制
- 相手のサーバーが本物かどうかもチェックする(DNS MX検索)
- secure:
- もっとも厳しい設定
- DNS MXを使わず、postfix内でnext-hopのサーバ証明書の検証を行う
- メール送信するだけなら厳しすぎる設定
- (empty):
- smtp_tls_note_starttls_offer
- TLSが有効になっていない場合、STARTTLSを提供するリモートSMTPサーバのホスト名をログ出力させる(Postfix 2.2以降)
- デフォルト値: no
- 以下のようなログが出る
- smtp_tls_CAfile
- Postfix SMTPクライアント証明書を発行した認証局 (CA) の証明書を持つファイルの場所を指定(Postfix 2.2以降)
- (-> Postfix が 送信先のSMTPサーバーの正当性を確認するために必要らしい)
- デフォルト値: empty
- Postfixの設定
- ClamAVの使い方
- スクリプトの書き方
- EC2インスタンスでのメモリ不足回避方法
postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
3. ClamAVのアラートメールを飛ばすスクリプト実装
まずは、ClamAVをインストールしましょう
$ sudo yum install -y clamav clamav-daemon libclamunrar9
mailコマンドを使うので mailx をインストールします
sudo yum -y mailx
次に、ウイルス検知時にメールを飛ばすスクリプトを実装しましょう
こちらの記事を参考にし、メモリ使用量を減らすようにしています
#!/bin/bash
EXCLUDE_LIST_FILE=/usr/local/bin/scanvirus_exclude_list.txt
LOGFILE=/var/log/scanvirus.log
SCAN_RESULT=/var/log/scanresult.txt
MAX_FILESIZE=200M
MAX_SCANSIZE=200M
MAILFROM=sender@example.com
MAILTO=recipient@example.com
export LANG=C
echo "===== Scan Virus =====" >> ${LOGFILE}
echo "`date` Scan Virus start" >> ${LOGFILE}
# 1. ClamAVプログラムのアップデート
echo "`date` Update ClamAV start" >> ${LOGFILE}
yum -y update clamav 1>> ${LOGFILE} 2>&1
echo "`date` Update ClamAV end" >> ${LOGFILE}
# 2. ウイルス定義の更新
echo "`date` Update Database start" >> ${LOGFILE}
/usr/bin/freshclam 1>> ${LOGFILE} 2>&1
echo "`date` Update Database end" >> ${LOGFILE}
# 3. ウイルススキャンの実施
echo "`date` Do Scan Virus start" >> ${LOGFILE}
## スキャン除外リストの展開
while read LINE
do
if [ $(echo "${LINE}"|grep \/$) ]; then
i=`echo ${LINE}|sed -e 's/^\([^ ]*\)\/$/\1/p' -e d`
excludeopt="${excludeopt} --exclude-dir=^${LINE}"
else
excludeopt="${excludeopt} --exclude=^${LINE}"
fi
done < ${EXCLUDE_LIST_FILE}
echo "excludeopt: ${excludeopt}" >> ${LOGFILE}
## ウイルススキャンの実行
/usr/bin/clamscan / \
--max-filesize=${MAX_FILESIZE} --max-scansize=${MAX_SCANSIZE} \
--infected --recursive ~/tmp 1> ${SCAN_RESULT} 2>> ${LOGFILE}
## ウイルスを検知したときのみ、アラートメールで通知する
[ ! -z "$(grep FOUND$ ${SCAN_RESULT})" ] && \
cat ${SCAN_RESULT} | mail -s "Virus Found in `hostname`" -r ${MAILFROM} ${MAILTO}
cat ${SCAN_RESULT} >> ${LOGFILE}
echo "`date` Do Scan Virus end" >> ${LOGFILE}
echo "`date` Scan Virus complete" >> ${LOGFILE}
最後に、実行権限の付与も忘れずに🙏
$ sudo chmod 700 /usr/local/bin/run-clamscan.sh
4. 動作確認
まずはテスト用マルウェアファイルを配置しましょう
eicar がファイルを配布しているのでそちらを使います。
$ wget https://secure.eicar.org/eicar.com
$ wget https://secure.eicar.org/eicar.com.txt
$ wget https://secure.eicar.org/eicar_com.zip
$ wget https://secure.eicar.org/eicarcom2.zip
スクリプトを起動して動作確認をしてみましょう
$ sudo /usr/local/bin/run-clamscan.sh
kill プロセスが発生してしまう場合
ClamAV は スキャン実行時に 2~3GB のメモリを食うようです
メモリが不足する場合は以下参考に スワップメモリを増やしてみましょう。
以下のように、 SMTPプロセス で status=sent
となっていればOKです。
ログから、SESの経由に成功していることがわかります👍
$ sudo tail -n 4 /var/log/maillog
(中略)
Aug 18 01:06:59 ip-***-**-**-*** postfix/smtp[4077]: 22A8BC1144E: to=<recipient@example.com>,
relay=email-smtp.ap-northeast-1.amazonaws.com[**.***.**.**]:587, delay=100, delays=99/0.01/0.18/0.14,
dsn=2.0.0, status=sent (250 Ok 010601915f68ccad-a5019b3d-e29a-4f84-a357-64c82345799d-000000)
SESコンソールでも該当の時間にメール送信したことを確認できました! これでかんぺき〜
さいごに
長々とお付き合いいただきありがとうございました🙇
今度は自宅のローカルサーバーに同様の構築をし、 crontab
で定期的にウイルススキャンさせるようにしてみたいと思います。