0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Postfix × SES × ClamAV サーバーのウイルススキャン~アラートメール送信 を自動化してみた

Last updated at Posted at 2024-08-18

はじめに

どうも、インフラエンジニア見習い (というか社会人見習い。。) の新卒1年目です🙇

職場にて SMTPについて学ぶ機会があったので、プライベートで実践的に復習してみようと思い少し遊んでみました。

自分が再度、同様の環境を構築する際の手順書を作る気持ちで執筆しています。

環境

  • サーバー : EC2 t2.micro(AmazonLinux2)
  • Postfix : ver 2.10.1

作業

1. SMTPクレデンシャルの発行

Postfixからのメール送信を SES経由にする際に必要です。
まずはSESのセットアップ画面を開きましょう

SMTP設定 を開きます

スクリーンショット 2024-08-18 17.56.47.png

SMTP認証情報の作成 をクリック

スクリーンショット 2024-08-18 17.59.15.png

IAMユーザーの作成画面が開かれるので、メールの送信権限があるか確認し、ユーザーの作成 をクリック

スクリーンショット 2024-08-18 18.01.10.png

ユーザーの作成が完了したら SMTPクレデンシャルの秘匿情報が表示されます。
次の 2. Postfix の設定 で使用するので保存しておきましょう
必要な情報は以下2つです

  • SMTP ユーザー名
  • SMTP パスワード

スクリーンショット 2024-08-18 18.05.14.png

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 パスワード>

「ap-northeast-1」 部分はご自身の SES が属するリージョンに合わせて記載を変更して下さい
SESコンソール 画像矢印部分をクリックすると リージョンが確認できます

スクリーンショット 2024-08-18 18.20.12.png

作成したファイルを 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)

参考記事 : ホスト名とは?調べ方やURLやIPアドレスとの関連性を解説

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
    • 相互認証を提供する方法のみを許可 する
smtp_sasl_password_maps
SASLの認証情報が記載されたファイルの場所を指定
デフォルト値: empty
smtp_use_tls
リモートSMTPサーバがSTARTTLSサポートを案内したら TLSを使い、案内がなければ平文でメールを送る (Postfix 2.2以降)
SES では STARTTLS がサポートされているので TLS を使うために有効化する
デフォルト値: no

STARTTLS とは

平文での通信 を SSL/TLS暗号化通信 に切り替えてくれる「コマンド」

参考記事:
STARTTLSとは
Amazon SESSMTPエンドポイントへの接続

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のサーバ証明書の検証を行う
    • メール送信するだけなら厳しすぎる設定
smtp_tls_note_starttls_offer
TLSが有効になっていない場合、STARTTLSを提供するリモートSMTPサーバのホスト名をログ出力させる(Postfix 2.2以降)
デフォルト値: no
以下のようなログが出る
postfix/smtp[pid]:  Host offered STARTTLS: [name.of.host]
smtp_tls_CAfile
Postfix SMTPクライアント証明書を発行した認証局 (CA) の証明書を持つファイルの場所を指定(Postfix 2.2以降)
(-> Postfix が 送信先のSMTPサーバーの正当性を確認するために必要らしい)
デフォルト値: empty

3. ClamAVのアラートメールを飛ばすスクリプト実装

まずは、ClamAVをインストールしましょう

$ sudo yum install -y clamav clamav-daemon libclamunrar9

mailコマンドを使うので mailx をインストールします

sudo yum -y mailx

次に、ウイルス検知時にメールを飛ばすスクリプトを実装しましょう

こちらの記事を参考にし、メモリ使用量を減らすようにしています

/usr/local/bin/run-clamscan.sh
#!/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 のメモリを食うようです
メモリが不足する場合は以下参考に スワップメモリを増やしてみましょう。

EC2をt2.microで立てたときにやることメモ

以下のように、 SMTPプロセス で status=sent となっていればOKです。
ログから、SESの経由に成功していることがわかります👍

bash
$ 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)

実際にメールが届いていることも確認できましたね 🙌
スクリーンショット 2024-08-18 11.03.57.png

SESコンソールでも該当の時間にメール送信したことを確認できました! これでかんぺき〜
スクリーンショット 2024-08-18 11.13.28.png

さいごに

長々とお付き合いいただきありがとうございました🙇
今度は自宅のローカルサーバーに同様の構築をし、 crontab で定期的にウイルススキャンさせるようにしてみたいと思います。

参考文献リスト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?