: O. Yuanying

Docker 上にメールサーバを構築する (3)

yuanying/postfix 続き

前回、 Postfix を Dokcer 上に構築した訳だが メールフィルタリング方式をどーしようと悩んだ。 主に悩んだ部分は、 自分のメールのハム/スパム学習をどういうアーキテクチャで処理しようかというところだったが、 とりあえずその部分は無視して スタンダードに組んでみる ことにしよう。

cron 有効化

めんどくさいので Amavisd や Spamassassin, ClamAV は全部同じイメージに突っ込んでしまう。 そのための前段階として (Spammassassin とかが更新に使ってるようなので) cron を有効化する。

$ git diff  
diff --git a/Dockerfile b/Dockerfile
index 527cd55..7d69f12 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,6 +17,7 @@ RUN bash -c 'debconf-set-selections <<< "postfix postfix/main_mailer_type string
 RUN bash -c 'debconf-set-selections <<< "postfix postfix/mailname string mail.example.com"'

 RUN apt-get install -y postfix postfix-mysql postgrey syslog-ng procmail
+RUN apt-get install -y cron

 ADD postfix/header_checks /etc/postfix/header_checks
 ADD postfix/main.cf /etc/postfix/main.cf
diff --git a/run b/run
old mode 100644
new mode 100755
index 393c7b2..69732a4
--- a/run
+++ b/run
@@ -13,6 +13,7 @@ sed -i "s/__REPLACE_DATABASE_HOST__/${MYSQL_PORT_3306_TCP_ADDR}/g" /etc/postfix/
 sed -i "s/__REPLACE_DATABASE_PORT__/${MYSQL_PORT_3306_TCP_PORT}/g" /etc/postfix/mysql-virtual-mailbox-maps.cf
 sed -i "s/__REPLACE_DATABASE_PASSWORD__/${POSTFIX_MYSQL_PASSWORD}/g" /etc/postfix/mysql-virtual-mailbox-maps.cf

+cron -f &
 service syslog-ng start
 service postfix start
 tail -F /var/log/mail.log

cron をインストールしコンテナ起動時にバックグラウンドで起動。

フィルタリング系パッケージのインストール

$ git diff
diff --git a/Dockerfile b/Dockerfile
index 7d69f12..b7a661c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,6 +18,9 @@ RUN bash -c 'debconf-set-selections <<< "postfix postfix/mailname string mail.ex

 RUN apt-get install -y postfix postfix-mysql postgrey syslog-ng procmail
 RUN apt-get install -y cron
+RUN apt-get install -y amavisd-new spamassassin clamav-daemon \
+                       pyzor razor \
+                       arj cabextract cpio nomarch pax unzip zip

 ADD postfix/header_checks /etc/postfix/header_checks
 ADD postfix/main.cf /etc/postfix/main.cf

rarunrar が入らなかったが、とりあえず無視。

設定

ClamAV, Spamassassin, Amavisd-new の設定をそれぞれ。 postfix のコンテンツフィルターを使って Amavis と通信し、 スパムチェックとウイルスチェックをやる感じ。

$ git diff            
diff --git a/Dockerfile b/Dockerfile
index 7d69f12..7a19e38 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,6 +18,23 @@ RUN bash -c 'debconf-set-selections <<< "postfix postfix/mailname string mail.ex

 RUN apt-get install -y postfix postfix-mysql postgrey syslog-ng procmail
 RUN apt-get install -y cron
+RUN apt-get install -y amavisd-new spamassassin clamav-daemon \
+                       pyzor razor libencode-detect-perl libdbi-perl libdbd-mysql-perl \
+                       arj cabextract cpio nomarch pax unzip zip
+
+# ClamAV
+RUN adduser clamav amavis
+RUN adduser amavis clamav
+
+# Spamassassin
+RUN sed -i "s/ENABLED\=0/ENABLED=1/g" /etc/default/spamassassin && \
+    sed -i "s/CRON\=0/CRON=1/g" /etc/default/spamassassin && \
+    echo "normalize_charset 1" >> /etc/mail/spamassassin/local.cf  && \
+    echo "report_safe 0" >> /etc/mail/spamassassin/local.cf
+
+# Amavisd-new
+ADD amavisd/50-user /etc/amavis/conf.d/50-user
+RUN chown root:root /etc/amavis/conf.d/50-user

 ADD postfix/header_checks /etc/postfix/header_checks
 ADD postfix/main.cf /etc/postfix/main.cf
diff --git a/postfix/main.cf b/postfix/main.cf
index fe96e19..0dac04f 100644
--- a/postfix/main.cf
+++ b/postfix/main.cf
@@ -63,7 +63,7 @@ virtual_transport = procmail
 procmail_destination_recipient_limit = 1

 # Use amavis for virus and spam scanning
+content_filter = smtp-amavis:[127.0.0.1]:10024

 # Header manipulation
 # --------------------------------------
diff --git a/postfix/master.cf b/postfix/master.cf
index 45cd6ba..337cc07 100644
--- a/postfix/master.cf
+++ b/postfix/master.cf
@@ -27,8 +27,8 @@ submission inet n       -       -       -       -       smtpd
 #  -o milter_macro_daemon_name=ORIGINATING
 #628       inet  n       -       -       -       -       qmqpd
 pickup    fifo  n       -       -       60      1       pickup
-        # -o content_filter=
-        # -o receive_override_options=no_header_body_checks
+   -o content_filter=
+   -o receive_override_options=no_header_body_checks
 cleanup   unix  n       -       -       -       0       cleanup
 qmgr      fifo  n       -       n       300     1       qmgr
 #qmgr     fifo  n       -       n       300     1       oqmgr
@@ -113,31 +113,31 @@ mailman   unix  -       n       n       -       -       pipe
   flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
   ${nexthop} ${user}

+smtp-amavis     unix    -       -       -       -       2       smtp
+        -o smtp_data_done_timeout=1200
+        -o smtp_send_xforward_command=yes
+        -o disable_dns_lookups=yes
+        -o max_use=20
+
+127.0.0.1:10025 inet    n       -       -       -       -       smtpd
+        -o content_filter=
+        -o local_recipient_maps=
+        -o relay_recipient_maps=
+        -o smtpd_restriction_classes=
+        -o smtpd_delay_reject=no
+        -o smtpd_client_restrictions=permit_mynetworks,reject
+        -o smtpd_helo_restrictions=
+        -o smtpd_sender_restrictions=
+        -o smtpd_recipient_restrictions=permit_mynetworks,reject
+        -o smtpd_data_restrictions=reject_unauth_pipelining
+        -o smtpd_end_of_data_restrictions=
+        -o mynetworks=127.0.0.0/8
+        -o smtpd_error_sleep_time=0
+        -o smtpd_soft_error_limit=1001
+        -o smtpd_hard_error_limit=1000
+        -o smtpd_client_connection_count_limit=0
+        -o smtpd_client_connection_rate_limit=0
+        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

 # Integration with Dovecot - hand mail over to it for local delivery, and
 # run the process under the vmail user and mail group.
diff --git a/run b/run
index 69732a4..9c1021f 100755
--- a/run
+++ b/run
@@ -13,8 +13,17 @@ sed -i "s/__REPLACE_DATABASE_HOST__/${MYSQL_PORT_3306_TCP_ADDR}/g" /etc/postfix/
 sed -i "s/__REPLACE_DATABASE_PORT__/${MYSQL_PORT_3306_TCP_PORT}/g" /etc/postfix/mysql-virtual-mailbox-maps.cf
 sed -i "s/__REPLACE_DATABASE_PASSWORD__/${POSTFIX_MYSQL_PASSWORD}/g" /etc/postfix/mysql-virtual-mailbox-maps.cf

+sed -i "s/__REPLACE_DATABASE_HOST__/${MYSQL_PORT_3306_TCP_ADDR}/g" /etc/amavis/conf.d/50-user
+sed -i "s/__REPLACE_DATABASE_PORT__/${MYSQL_PORT_3306_TCP_PORT}/g" /etc/amavis/conf.d/50-user
+sed -i "s/__REPLACE_DATABASE_PASSWORD__/${POSTFIX_MYSQL_PASSWORD}/g" /etc/amavis/conf.d/50-user
+
 cron -f &
 service syslog-ng start
+service spamassassin start
+service clamav-daemon start
+service clamav-freshclam start
+service amavis start
 service postfix start
+
 tail -F /var/log/mail.log

起動および動作チェック

以下のコマンドで起動。

docker run -d --link mysql:mysql \
  --name postfix \
  -e "POSTFIX_MYSQL_PASSWORD=postfixpassword" \
  -h 'mail.fraction.jp' \
  -v /var/vmail:/var/vmail \
  -p 25:25 \
  yuanying/postfix

telnet で 25 番ポートにアクセスし、ちゃんとメールが通るかチェック。

$ telnet 172.16.42.43 25
Trying 172.16.42.43...
Connected to localdocker.
Escape character is '^]'.
220 mail.example.com ESMTP Postfix (Ubuntu)
HELO 172.16.42.43
250 mail.example.com
MAIL FROM: user@fraction.jp
250 2.1.0 Ok
RCPT TO: yuanying@172.16.42.43.xip.io
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: user@fraction.jp
Subjet: test
Hello world.
.
250 2.0.0 Ok: queued as EAA2D318
QUIT
221 2.0.0 Bye
Connection closed by foreign host.

docker logs postfix でログの確認をした後に、 /var/vmail 下の該当のアカウントにメールがちゃんと配送されているかチェック。

次は dovecot 作る。(なんかあまり docker 関係ないな…。)