目的
ローカルネットワーク内で使用するメールサーバをdocker-composeで構築する
内部DNSサーバも同様にdocker-composeで同一ホスト上に構築する
ドメイン名は以下を使用
murci.internal
環境
ubuntu 22.04
DNSサーバおよびメールサーバ:192.168.9.10
CoreDNS
docker-mailserver
CoreDNS構築手順
CoreDNSをdocker-composeで構築する
ディレクトリ構成
プロジェクトフォルダ構成は以下のとおり
$ tree ~/coredns/
/home/admin/coredns/
├── docker-compose.yml
├── Dockerfile
└── volumes
□└── config
□□├── Corefile
□□├── murci.internal.zone
Dockerfile
Dockerfileを以下のとおり作成する
$ cat Dockerfile
FROM coredns/coredns:1.7.0
EXPOSE 53
EXPOSE 53/udp
ENTRYPOINT ["/coredns"]
CMD ["-conf", "/etc/coredns/Corefile"]
docker-compose.yml
docker-compose.ymlを以下のとおり作成する
ポートはホスト側/コンテナ側ともに53を使用
$ cat docker-compose.yml
version: '3.1'
services:
coredns:
build: .
container_name: coredns
restart: on-failure # other option: always - if you want persistent through host reboots
expose:
- '53'
- '53/udp'
ports:
- '53:53'
- '53:53/udp'
volumes:
- './volumes/config/Corefile:/etc/coredns/Corefile'
- './volumes/config/murci.internal.zone:/etc/coredns/murci.internal.zone'
ゾーンファイルの作成
hostsファイルでうまくいかなかったので、ゾーンファイルを作成しました。
bindのゾーンファイルと同じ文法で作成します。
正引きのゾーンファイルを以下のとおり作成する
4行目「admin.server01.murci.internal.」はメールアドレス「admin@server01.murci.internal」のこと
$ cat murci.internal.zone
$ORIGIN murci.internal.
$TTL 3600
@ IN SOA server01.murci.internal. admin.server01.murci.internal. (
2023071201 ; Serial
1h ; Refresh
2h ; Retry
1w ; Expire
1h ; Negative Cache TTL
)
@ IN NS think01.murci.internal.
@ IN A 127.0.0.1
@ IN AAAA ::1
@ IN MX 10 server01.murci.internal.
think01 IN A 192.168.9.10
win10 IN A 192.168.9.7
Corefileの作成
Corefileを以下のとおり作成する
$ cat Corefile
. {
whoami
forward . 8.8.8.8:53
errors
log . "{proto} {remote} is Request: {name} {type} {>id}"
reload
}
murci.internal {
file /etc/coredns/murci.internal.zone {
}
docker-composeでcorednsコンテナを起動する
$ pwd
/home/admin/coredns
$ docker-compose up -d
Creating network "coredns_compose_2_default" with the default driver
Creating coredns ... done
クライアント側のresolve設定
クライアントのDNSサーバ指定はsystemd-resolvedサービスを使用する
dns_servers.confを作成する
$ mkdir /etc/systemd/resolved.conf.d
$ cd /etc/systemd/resolved.conf.d
$ vi dns_servers.conf
------
[Resolve]
DNS=192.168.9.10
Domains=murci.internal.
Domains=9.168.192.in-addr.arpa.
------
systemd-resolvedサービスを再起動する
$ systemctl restart systemd-resolved.service
$ resolvectl status
Current DNS Server: 192.168.9.10
※構築したDNSサーバーが表示されていること
DNS通信テスト
DNSクライアントで以下実行、名前解決ができることを確認する
$ dig think01.murci.internal
;; ANSWER SECTION:
think01.murci.internal. 0 IN A 192.168.9.10
※IPアドレスが表示されること
docker-mailserver構築手順
docker-mailserverリポジトリの取得
dockerコンテナイメージとして、docker-mailserverを利用する
作成用リポジトリをgithubから取得する
プロジェクトフォルダ
/home/admin/docker-mailserver
$ git clone https://github.com/docker-mailserver/docker-mailserver.git
$ cd docker-mailserver
docker-compose.ymlの作成
docker-compose.ymlを以下のとおり作成する
$ cat docker-compose.yml
version: '3.8'
services:
mailserver:
image: docker.io/mailserver/docker-mailserver:latest
hostname: think01.murci.internal
domainname: murci.internal
ports:
- "25:25"
- "465:465"
- "587:587"
- "993:993"
volumes:
- ./data/maildata:/var/mail
- ./data/mailstate:/var/mail-state
- ./data/maillogs:/var/log/mail
- /etc/localtime:/etc/localtime:ro
- ./config/:/tmp/docker-mailserver/
- ./config/main.cf:/etc/postfix/main.cf
- ./config/postfix-sasl-password.cf:/etc/postfix/sasl/sasl_passwd
restart: always
stop_grace_period: 1m
cap_add: [ "NET_ADMIN", "SYS_PTRACE" ]
dockerコンテナの起動
dockerコンテナを起動する
$ docker-compose up -d
ユーザ作成
メール送付テストを行う前にユーザの作成を行う。コマンド実行時に自動的にユーザのメールボックスが作成される。ホストOSに直接Postfix/Dovecotインストールする場合は、SASLDBにユーザを登録しないといけないが、docker-mailserverは、以下のコマンド実行だけでSASL認証ユーザ登録ができる
$ cd /home/admin/docker-mailserver
$ ./setup.sh email add testadmin@murci.internal murci
※メールアドレス パスワード
$ ./setup.sh email list
※作成したユーザが表示されること
メール疎通確認
telnetを使用して、25番ポートでメール疎通テストを行う
アカウントtestadminからadminへのメール送信を行う
エラーコードが表示されずに転送されること
※クライアントで以下実行
$ telnet 192.168.9.10 25
EHLO murci.internal
MAIL FROM: testadmin@murci.internal
RCPT TO: admin@murci.internal
DATA
Return-Path:
From:
Date: 20230713
To:
Subject: to admin
this is a mail
.
QUIT
maillogを確認する
$ tail /home/admin/docker-mailserver/data/maillogs/maillogs
status=sent
※statu=sentとなっていること
メールボックスにmailが受信されていることを確認
メールボックスは以下に存在
/home/admin/docker-mailserver/data/maildata/murci.internal/ユーザ名/new
$ pwd
/home/admin/docker-mailserver/data/maildata/murci.internal/admin/new
$ ls -ltr
-rw-r--r-- 1 5000 5000 1177 Jul 13 14:20 '1689225605.M45925P25201.think01.murci.internal,S=1177,W=1199'
$ cat 1689225605.M45925P25201.server01.murci.internal,S=1177,W=1199
Return-Path:
Delivered-To: admin@murci.internal
Received: from think01.murci.internal
by think01.murci.internal with LMTP
id K+exAoWJr2RxYgAUadzQdA
(envelope-from )
for ; Thu, 13 Jul 2023 14:20:05 +0900
Received: from localhost (localhost [127.0.0.1])
by think01.murci.internal (Postfix) with ESMTP id 078985D216AB
for ; Thu, 13 Jul 2023 14:20:05 +0900 (JST)
Received-SPF: Temperror (mailfrom) identity=mailfrom; client-ip=192.168.110.8; helo=murci.internal; envelope-from=testadmin@murci.internal; receiver=
Authentication-Results: think01.murci.internal; dmarc=none (p=none dis=none) header.from=murci.internal
Received: from murci.internal (unknown [192.168.110.8])
by think01.murci.internal (Postfix) with ESMTP id E59FA5D21694
for ; Thu, 13 Jul 2023 14:18:52 +0900 (JST)
From:
Date: 20230713
To:
Subject: to admin
Message-Id: <20230713052005.078985D216AB@think01.murci.internal>
this is a mail
SASLによるユーザ認証設定
メール送付時に送信者のアカウントに対してユーザ認証を行う
Base64エンコード
ユーザのメールアドレス、パスワードに対してBase64でエンコードを行う
$ python3
import base64
username = "testadmin@murci.internal"
password = "murci"
# 送信者のユーザー名とパスワードをそれぞれエンコード
encoded_username = base64.b64encode(username.encode()).decode()
encoded_password = base64.b64encode(password.encode()).decode()
# AUTH LOGIN コマンドに渡す認証情報を作成
auth_string = f"{encoded_username}\r\n{encoded_password}"
print(auth_string)
エンコードされたメールアドレス、パスワードの文字列がそれぞれ表示されるのでコピーする
メール疎通確認(ポート587)
submissionポート587:587を使用してtelnetでメール疎通テストを行う
$ telnet 192.168.9.7 587
EHLO murci.internal
AUTH LOGIN
<Base64でエンコードしたメールアドレス>
<Base64でエンコードしたパスワード>
MAIL FROM:
RCPT TO:
DATA
Subject: Test Email
From:
Date: 20230725
To:
This is a test email sent using telnet.
.
QUIT
ログとメールボックスを確認して正常にメールが送付されていることを確認する
複数のユーザを一括で登録する方法
Docker-Mailserverを使用して複数のユーザを一括で登録し、SMTPリレーサーバの設定を行う手順を紹介します。
- 以下のようなユーザのメールアドレスとパスワードの対応表をCSV形式で作成します。ファイル名を
users.csv
とします。
testuser1@murci.internal,password
testuser2@murci.internal,password
testuser3@murci.internal,password
- ユーザ登録用のシェルスクリプトを作成します。ファイル名を
users_regist.sh
とします。
#!/bin/bash
while IFS=',' read -r email password; do
./setup.sh email add "$email" "$password"
done < users.csv
- シェルスクリプトに実行権限を与えます。
$ chmod +x users_regist.sh
- ユーザ登録用のシェルスクリプトを実行します。
$ ./users_regist.sh
- ユーザが正しく登録されたか確認するために、以下のコマンドを実行します。
$ ./setup.sh email list
* testuser1@murci.internal ( 0 / ~ ) [0%]
* testuser2@murci.internal ( 0 / ~ ) [0%]
* testuser3@murci.internal ( 0 / ~ ) [0%]
※ユーザが表示されること
DNS/Mailクライアントの設定
- DNSに
192.168.9.7
を追加します。 - ホスト:
think01.murci.internal
- ポート:
25
または587
- E-mail Address:
testuser1@murci.internal
- ホスト:
think01.murci.internal
- ポート:
143
SMTPの設定:
IMAPの設定:
SMTPリレー設定(検証中)
googleのリレーサーバを利用する
/home/admin/docker-mailserver/main.cfに以下を追記する
relayhost = [smtp.gmail.com]:587
mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 192.168.9.0/24
※リレーを許可する対象のネットワークを指定
SMTPリレー設定(SASL)
ローカルSMTPサーバに対するSASL設定と、SMTPリレーサーバに対するSASLがあるから混同しないようにする。
SMTPリレーサーバに対するSASL認証設定を行う
/home/admin/docker-mailserver/main.cfに以下を追記する
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes
smtpd_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_passwd
SMTPサーバ認証用設定
googleのSMTPサーバ(smtp.gmail.com)へログインするためのコマンドを実行する
./setup.sh relay add-domain gmail.com smtp.gmail.com 587
./setup.sh relay add-auth gmail.com username@gmail.com 'password'
設定の反映
postfixをリロードする
コンテナ内で、登録されていることを確認
# /etc/postfix reload
# cat postfix-relaymap.cf
@gmail.com [smtp.gmail.com]:587
root@think01:/tmp/docker-mailserver#
# cat postfix-sasl-password.cf
[smtp.gmail.com]:587 username@gmail.com:password