(2023/11/15 追記ここから)
この記事の設定ですと、「自分のドメインの存在しないユーザー宛メールはエラーメールとなって転送されてくる」という挙動になります。これを(なるべく)抑制する為に微調整した記事を書きました。完全ではありませんが、御参考になれば幸いです。
私的サーバー構築日誌:Postfix
(2023/11/15 追記ここまで)
能書き
自宅サーバー構築譚:基本構想に基づく自宅サーバー構築、Ubuntu22.04LTSインストールその2の続きです。
スミマセン。ここで謝っておきます。私、メールサーバーを舐めてました。メールサーバーは自宅サーバーの華だとか、生意気を言って申し訳ありませんでした。
今、メールサーバー(MTA)を立てるのは大変なんですね。迷惑メール対策でガッチガチに固められて、気を使わなきゃいけない点が増えてます。技術的にかなり面倒な感じ。そしてGoogleとかの世界的大手メールサービスがそれを強要してます。やって出来ない事はないけれど、とても大変です。
と言う訳で、私の自宅サーバーにおけるメールサーバー(MTA)は、志を低くします。
目標
メールサーバー関連作業初回に掲げた作業の題目を再掲します。
- DovecotのLMTP ←完了
- DovecotのIMAP ←完了
- Postfix ←イマココ
そういう訳で。今回はPostfixをDockerコンテナに立てます。
そして志を低く、外部へはメールを一切送信しないサーバーとします。エラーメールも出しません。全ドメインの全ユーザーを受信します。
外部へ発信しないのでSMTP-Authも無しです。
これにもリスクがあるんですけども。何かの間違いで迷惑メールの攻撃対象になっちゃったりなんかしたら、山のようなメールをすべて受け取る事になってしまいます。
もしかするとPostfixの設定をきちんとすれば対策できるのかも知れませんが、私にそこまでの知識がありません。調べても、そういう設定に関する記事が出てきませんし。本格的にPostfixの勉強をしないとダメそうです。仕方が無いので、このリスクは甘受する事にします。
参考文献
Postfixの基本的な設定に関する情報。
Postfixを受信専用にする為の関連情報を集めました。ちょっと数が多いです。
- Postfixで特定のドメイン宛以外のメールを削除したい - KITA-SAN.BLOG
- Postfixアドレス書き換え
- Postfix の拡張メールアドレス - tmtms のメモ
- Postfix 設定パラメータ
- [Postfix]特定のドメインのみ受信しそれ以外は別アドレスに転送する - OSSリファレンス
- 【postfix】送信元(From)によるメール拒否(smtpd_sender_restrictions ) - server-memo.net
- regexp_table - Postfix 正規表現テーブルの書式
- Postfix バーチャルドメインホスティング Howto
- バーチャルドメイン - Postfix チュートリアル
DockerにPostfixをインストールする方法は、この記事を参考にしました。
なお、きっちりと送信も可能なメールサーバーにした事例を見つけましたので、参考までに。
そこで出てくるなりすましメール対策の解説。
準備
Dockerコンテナ構築用ディレクトリ
まず、準備するフォルダは/opt/postfix
とします。
sudo mkdir /opt/postfix
sudo chgrp docker /opt/postfix
sudo chmod g+w /opt/postfix
これらの操作の結果、/opt/postfix
ディレクトリの権限はこうなります。
$ ls -dl /opt/postfix
drwxrwxr-x 2 root docker 2 Jun 4 11:34 /opt/postfix
Postfix設定ファイル
上記のディレクトリの中に、Postfix関連ファイルを準備します。
Postfixの設定main.cf
はこんな感じにしました。
- ドメイン
example.com
は、説明用の仮設定です。お金を出して買った自分だけのドメインに置き換えて下さい。 - IPアドレス
172.16.1.3
とポート番号24
は、Dovecotで設定したLMTPサーバーに合わせて下さい。LXDコンテナではなくて、そのホストマシンを設定します。 - ユーザー
taro
は、色んな宛先に来たメールを受け取る、転送先ユーザーです。
MYDOMAIN=example.com
LMTP_IPADDR=172.16.1.3
LMTP_PORT=24
MYUSER=taro
cat <<___ >/opt/postfix/main.cf
compatibility_level = 3.6
mydomain = $MYDOMAIN
myhostname = mail.\$mydomain
myorigin = \$mydomain
inet_protocols = ipv4
inet_interfaces = all
mydestination = $MYDOMAIN
local_recipient_maps =
mynetworks = 127.0.0.0/8
alias_maps = hash:/etc/aliases
mailbox_transport = lmtp:inet:$LMTP_IPADDR:$LMTP_PORT
smtpd_banner = \$myhostname ESMTP
biff = no
readme_directory = no
virtual_alias_domains = regexp:/etc/virtual_domains
virtual_alias_maps = regexp:/etc/virtual_users
mailbox_size_limit = 0
recipient_delimiter = +
___
全ドメインの全ユーザーを受信する為に、Postfixの仮想ドメインを利用します。その設定は下記の通りです。$MYDOMAIN
以外のドメイン宛に来たメールは、全て$MYUSER
に転送します。
cat <<___ >/opt/postfix/virtual_domains
!/^$MYDOMAIN\$/ OK
___
cat <<___ >/opt/postfix/virtual_users
!/^.*@$MYDOMAIN\$/ $MYUSER@$MYDOMAIN
___
Dockerコンテナ構築
関連ファイルの用意
docker-compose.yml
ファイルはこうなります。
cat <<___ >/opt/postfix/docker-compose.yml
version: '3.8'
services:
postfix1:
build: .
volumes:
- ./main.cf:/etc/postfix/main.cf
- ./virtual_domains:/etc/virtual_domains
- ./virtual_users:/etc/virtual_users
ports:
- "25:25"
___
そしてDockerfile
ファイルです。
cat <<___ >/opt/postfix/Dockerfile
FROM ubuntu:22.04
RUN apt update && apt upgrade -y
RUN DEBIAN_FRONTEND=noninteractive apt install postfix -y
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
___
最後に、起動時に実行されるentrypoint.sh
です。下記のようになります。内容の詳細は参考文献を参照ください。
cat <<___ >/opt/postfix/entrypoint.sh
#!/bin/bash
postfix start
postmap /etc/virtual_domains
postmap /etc/virtual_users
cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
postfix reload
tail -f /dev/null
___
chmod +x /opt/postfix/entrypoint.sh
構築
特別な事は何もありません。
cd /opt/postfix
docker compose up -d
動作確認
知らないドメイン宛
適当なドメインの適当なメールアドレスに送信してみます。
nc -C 172.16.1.3 25 <<___
ehlo sender.home
mail from: ubuntu@example.com
rcpt to: hanako@test.home
data
From: ubuntu@example.com
To: hanako@test.home
Subject: test mail
hello, world
.
quit
___
知らないドメインの知らない人宛のメールは$MYUSER
(今回はtaro
)に届きます。今回はIMAPを使わず、/home/taro/Maildir
を直接覗いてみます。新着メールはMaildir/new
ディレクトリに置かれる筈です。
lxc shell dovecot1
cd /home/taro/Maildir/new
ls -t | head -n1 | xargs cat
exit
実行結果はこんな感じになります。
# cd /home/taro/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@example.com>
Delivered-To: taro@example.com
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id RiRsKroZfGQeGQAA9sUnBg
(envelope-from <ubuntu@example.com>)
for <taro@example.com>; Sun, 04 Jun 2023 13:57:30 +0900
Received: from sender.home (unknown [172.16.1.3])
by mail.example.com (Postfix) with ESMTP id A02A93A8
for <hanako@test.home>; Sun, 4 Jun 2023 04:57:30 +0000 (UTC)
From: ubuntu@example.com
To: hanako@test.home
Subject: test mail
hello, world
# exit
logout
実在ユーザー宛
$MYDOMAIN
ドメインの実在ユーザー宛だと、きちんとその人に届きます。
nc -C 172.16.1.3 25 <<___
ehlo sender.home
mail from: ubuntu@example.com
rcpt to: ubuntu@example.com
data
From: ubuntu@example.com
To: ubuntu@example.com
Subject: test mail
hello, world
.
quit
___
lxc shell dovecot1
cd /home/ubuntu/Maildir/new
ls -t | head -n1 | xargs cat
exit
実行結果。
# cd /home/ubuntu/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@example.com>
Delivered-To: ubuntu@example.com
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id gITxHiojfGRDGQAA9sUnBg
(envelope-from <ubuntu@example.com>)
for <ubuntu@example.com>; Sun, 04 Jun 2023 14:37:46 +0900
Received: from sender.home (unknown [172.16.1.3])
by mail.example.com (Postfix) with ESMTP id 728883B0
for <ubuntu@example.com>; Sun, 4 Jun 2023 05:37:46 +0000 (UTC)
From: ubuntu@example.com
To: ubuntu@example.com
Subject: test mail
hello, world
# exit
logout
仕舞い
不正中継しないよう、全メールを黙って受信してしまう設定が出来ました。これを使えば、メール送信のテストなんかも可能になりそうです。
ともあれ、これで「連絡を受けるだけ」の、人様に迷惑を掛けないメールサーバーが出来ました。やったね