能書き
私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。
MTAをまともに(GoogleMailなどのガッチリした世界的大手メールサービスともやり取り出来るように)立てるのは非常に大変です。なのでここでは、非公開を前提としたLAN内限定MTAとします。
今回の設定で公開すると、息つく暇も無く迷惑メールの踏み台にされる&メール爆弾の如く迷惑メールが届く筈ですので、絶対に公開しないで下さい。
そんな不自由なメールサーバーを立てる理由は、GitLabです。前回も触れましたが。この後でGitLabサーバーを立てたいと考えていますが、そこでメールサーバーとの連携が必要になります。これが今のモチベーションになっています。
目標
- PostfixをDockerコンテナに立てる
- 非公開を前提に、SMTP認証しない
- 受信ユーザーが1人しかいない事を前提に、全ドメインの全宛先を受信する
参考文献
内容は、以前の記事の焼き直しです。これを元にして現在の設定に従った微調整をします。また、最後に纏めますが、受信できないケースがあります。これを許容範囲にするべく微調整しています。
Dovecotは下記の通りに設定済とします。
Dockerコンテナの置き場所についての、私の決め事です。
インストール時に実行するシェルスクリプトは、こちらから拝借しました。
準備
Dockerコンテナ構築用ディレクトリ
Dockerコンテナの置き場所として、ホストマシン管理者アカウントのhomeディレクトリにdocker-postfixサブディレクトリを作成します。
cd
mkdir docker-postfix
cd docker-postfix
Postfix設定ファイル
上記のディレクトリの中にPostfix関連ファイルを準備します。
Postfixの設定main.cf
はこんな感じにしました。
- ドメイン
example.com
は説明用の仮設定です。お金を出して買った自分だけのドメインに置き換えて下さい。 - LMTPのIPアドレス
172.16.1.2
とポート番号24
は、Dovecotで設定したLMTPサーバーに合わせて下さい。LXDコンテナではなくて、そのホストマシンを設定します。 - ユーザー
taro
は私の環境で唯一のメール受信ユーザーです。色んな宛先に来たメールを、すべてこのユーザーに転送します。
SMTP_PORT=25
LMTP_PORT=24
HOST_IPADDR=172.16.1.2
MYUSER=taro
MYDOMAIN=example.com
cat <<___ >main.cf
compatibility_level = 3.6
mydomain = $MYDOMAIN
myhostname = mail.\$mydomain
myorigin = \$mydomain
inet_protocols = ipv4
inet_interfaces = all
mydestination = home
local_recipient_maps =
mynetworks = 127.0.0.0/8
alias_maps = hash:/etc/aliases
mailbox_transport = lmtp:inet:$HOST_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の仮想ドメインを利用します。その設定は下記の通りです。home
以外のドメイン宛に来たメールは、全て$MYUSER
に転送します。
後で確認してみますが、設定の都合でhome
ドメインだけは不在ユーザーに届きません。home
ドメインなら構いませんよね。
cat <<___ >virtual_domains
!/^home\$/ OK
___
cat <<___ >virtual_users
!/^.*@home\$/ $MYUSER@home
___
Dockerコンテナ構築
docker-compose.yml
ファイルはこうなります。
cat <<___ >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:
- "$SMTP_PORT:$SMTP_PORT"
restart: unless-stopped
___
そしてDockerfile
です。
cat <<___ >Dockerfile
FROM ubuntu:22.04
RUN apt update && apt upgrade -y && \
DEBIAN_FRONTEND=noninteractive apt install postfix -y
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
___
最後に、起動時に実行されるentrypoint.sh
です。下記のようになります。内容の詳細は参考文献を参照ください。
cat <<___ >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 entrypoint.sh
Dockerコンテナを構築します。特別な事は何もありません。
docker compose up -d
動作確認
メール受信ユーザー宛
私の環境で唯一のメール受信ユーザーtaro
にメールしてみます。
nc -C $HOST_IPADDR $SMTP_PORT <<___
ehlo sender.home
mail from: ubuntu@test.corp
rcpt to: $MYUSER@home
data
From: ubuntu@test.corp
To: $MYUSER@home
Subject: test
hello, $MYUSER
$(date +"%Y/%m/%d %H:%M:%S")
.
quit
___
確認はIMAPを使わず、LXDコンテナdovecot1
の/home/taro/Maildir
を直接覗いてみます。「最新メール1通の確認」を簡単に自動化できるので。
新着メールはMaildir/new
ディレクトリに置かれる筈です。
CONTAINER=dovecot1
lxc shell $CONTAINER
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@test.corp>
Delivered-To: taro@home
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id P6GfBFZyVGWMIAAA9sUnBg
(envelope-from <ubuntu@test.corp>)
for <taro@home>; Wed, 15 Nov 2023 16:25:10 +0900
Received: from sender.home (primary [172.16.1.2])
by mail.example.com (Postfix) with ESMTP id 0BF5558C
for <taro@home>; Wed, 15 Nov 2023 07:25:10 +0000 (UTC)
From: ubuntu@test.corp
To: taro@home
Subject: test
hello, taro
2023/11/15 16:25:09
# exit
logout
私のドメインのメール受信ユーザー宛
私のドメイン$MYDOMAIN
の、メール受信ユーザーtaro
に宛ててメールしてみます。
nc -C $HOST_IPADDR $SMTP_PORT <<___
ehlo sender.home
mail from: ubuntu@test.corp
rcpt to: $MYUSER@$MYDOMAIN
data
From: ubuntu@test.corp
To: $MYUSER@$MYDOMAIN
Subject: test
hello, $MYUSER
$(date +"%Y/%m/%d %H:%M:%S")
.
quit
___
メール内容確認結果。設定どおり$MYUSER@home
に転送されて届いてます。
# cd /home/taro/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@test.corp>
Delivered-To: taro@home
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id hdjnAw53VGXGIAAA9sUnBg
(envelope-from <ubuntu@test.corp>)
for <taro@home>; Wed, 15 Nov 2023 16:45:18 +0900
Received: from sender.home (primary [172.16.1.2])
by mail.example.com (Postfix) with ESMTP id EFDFB6A4
for <taro@example.com>; Wed, 15 Nov 2023 07:45:17 +0000 (UTC)
From: ubuntu@test.corp
To: taro@example.com
Subject: test
hello, taro
2023/11/15 16:45:17
# exit
logout
知らないドメインの知らないユーザー宛
知らないドメインunknown.corp
の知らないユーザーhanako
に宛ててメールしてみます。
nc -C $HOST_IPADDR $SMTP_PORT <<___
ehlo sender.home
mail from: ubuntu@test.corp
rcpt to: hanako@unknown.corp
data
From: ubuntu@test.corp
To: hanako@unknown.corp
Subject: test
hello, hanako
$(date +"%Y/%m/%d %H:%M:%S")
.
quit
___
設定どおり、きちんと$MYUSER@home
に転送されてます。
# cd /home/taro/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@test.corp>
Delivered-To: taro@home
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id anzxOil4VGXiIAAA9sUnBg
(envelope-from <ubuntu@test.corp>)
for <taro@home>; Wed, 15 Nov 2023 16:50:01 +0900
Received: from sender.home (primary [172.16.1.2])
by mail.example.com (Postfix) with ESMTP id DCAB075A
for <hanako@unknown.corp>; Wed, 15 Nov 2023 07:50:01 +0000 (UTC)
From: ubuntu@test.corp
To: hanako@unknown.corp
Subject: test
hello, hanako
2023/11/15 16:50:01
# exit
logout
私のドメインの存在しないユーザー宛
私のドメイン$MYDOMAIN
の存在しないユーザーhanako
に宛ててメールしてみます。
nc -C $HOST_IPADDR $SMTP_PORT <<___
ehlo sender.home
mail from: ubuntu@test.corp
rcpt to: hanako@$MYDOMAIN
data
From: ubuntu@test.corp
To: hanako@$MYDOMAIN
Subject: test
hello, hanako
$(date +"%Y/%m/%d %H:%M:%S")
.
quit
___
これも設定どおり、きちんと$MYUSER@home
に転送されてます。
# cd /home/taro/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@test.corp>
Delivered-To: taro@home
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id S3AjJzp5VGX+IAAA9sUnBg
(envelope-from <ubuntu@test.corp>)
for <taro@home>; Wed, 15 Nov 2023 16:54:34 +0900
Received: from sender.home (primary [172.16.1.2])
by mail.example.com (Postfix) with ESMTP id 8A93345E
for <hanako@example.com>; Wed, 15 Nov 2023 07:54:34 +0000 (UTC)
From: ubuntu@test.corp
To: hanako@example.com
Subject: test
hello, hanako
2023/11/15 16:54:34
# exit
logout
homeドメインの存在しないユーザー宛
存在しないユーザーhanako
に、home
ドメインへメールしてみます。
nc -C $HOST_IPADDR $SMTP_PORT <<___
ehlo sender.home
mail from: ubuntu@test.corp
rcpt to: hanako@home
data
From: ubuntu@test.corp
To: hanako@home
Subject: test
hello, hanako
$(date +"%Y/%m/%d %H:%M:%S")
.
quit
___
唯一この場合だけメールのパターンが変わります。
転送せずに直接受信しようとしてユーザーが居ない
→エラーメールを返信
→エラーメールが知らないユーザー宛なので$MYUSER@home
に転送
→$MYUSER
がエラーメールを受信
# cd /home/taro/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <>
Delivered-To: taro@home
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id MJbZD1t6VGUaIQAA9sUnBg
(envelope-from <>)
for <taro@home>; Wed, 15 Nov 2023 16:59:23 +0900
Received: by mail.example.com (Postfix)
id 3EB07760; Wed, 15 Nov 2023 07:59:23 +0000 (UTC)
Date: Wed, 15 Nov 2023 07:59:23 +0000 (UTC)
From: MAILER-DAEMON@example.com (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
To: ubuntu@test.corp
Auto-Submitted: auto-replied
MIME-Version: 1.0
Content-Type: multipart/report; report-type=delivery-status;
boundary="22EBB75C.1700035163/mail.example.com"
Content-Transfer-Encoding: 8bit
Message-Id: <20231115075923.3EB07760@mail.example.com>
This is a MIME-encapsulated message.
--22EBB75C.1700035163/mail.example.com
Content-Description: Notification
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
This is the mail system at host mail.example.com.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to postmaster.
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
<hanako@home>: host 172.16.1.2[172.16.1.2] said: 550 5.1.1 <hanako@home> User
doesn't exist: hanako@home (in reply to RCPT TO command)
--22EBB75C.1700035163/mail.example.com
Content-Description: Delivery report
Content-Type: message/delivery-status
Reporting-MTA: dns; mail.example.com
X-Postfix-Queue-ID: 22EBB75C
X-Postfix-Sender: rfc822; ubuntu@test.corp
Arrival-Date: Wed, 15 Nov 2023 07:59:23 +0000 (UTC)
Final-Recipient: rfc822; hanako@home
Original-Recipient: rfc822;hanako@home
Action: failed
Status: 5.1.1
Remote-MTA: dns; 172.16.1.2
Diagnostic-Code: smtp; 550 5.1.1 <hanako@home> User doesn't exist: hanako@home
--22EBB75C.1700035163/mail.example.com
Content-Description: Undelivered Message
Content-Type: message/rfc822
Content-Transfer-Encoding: 8bit
Return-Path: <ubuntu@test.corp>
Received: from sender.home (primary [172.16.1.2])
by mail.example.com (Postfix) with ESMTP id 22EBB75C
for <hanako@home>; Wed, 15 Nov 2023 07:59:23 +0000 (UTC)
From: ubuntu@test.corp
To: hanako@home
Subject: test
hello, hanako
2023/11/15 16:59:23
--22EBB75C.1700035163/mail.example.com--
# exit
logout
仕舞い
「home
ドメイン以外なら全ドメインの全ユーザー宛メールを受信」するメールサーバーMTAを設定できました!
home
ドメインは諦めましょう。たとえ家庭内限定だとしてもhome
ドメインでメールアドレスを作ってはいけない、という事で一つ御容赦ください。