LoginSignup
1
0

私的サーバー構築日誌:Postfix

Last updated at Posted at 2023-11-15

能書き

私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。

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
LXDコンテナ内
cd /home/taro/Maildir/new
ls -t | head -n1 | xargs cat
exit

実行結果は下記のような感じになります。きちんと届いてますね。

LXDコンテナ内
# 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に転送されて届いてます。

LXDコンテナ内
# 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に転送されてます。

LXDコンテナ内
# 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に転送されてます。

LXDコンテナ内
# 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がエラーメールを受信

LXDコンテナ内
# 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ドメインでメールアドレスを作ってはいけない、という事で一つ御容赦ください。

1
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
1
0