top of page
エンジニアN

OAuth対応メールリレーサーバのコンテナ構築とメールテスト

更新日:15 分前

社内案件で物理サーバにUbuntuやDockerを構築し、いくつかのコンテナを作成していました。今回は一番苦戦した表題のコンテナ構築手順を紹介していきたいと思います。


前提条件

  • Docker CEをインストール済み

  • ホストOSに対象コンテナ構築のための必要ファイル(Dockerfile等)は配置済み

  • メール転送先はsmtp.office365.com


想定する環境

  • ホストOSからコンテナへのポートフォワーディング


手順概要

1.Entra IDアプリケーションの登録

2.OAuth対応メールリレーサーバのコンテナ起動

3.コンテナ内での認証情報等の設定

4.メールテスト


手順

1.Entra IDアプリケーションの登録

1-1.アプリケーションの登録

Azureにログインします。

[Entra ID] - [アプリの登録] - [新規登録]をクリックします。

[アプリケーションの登録]が表示されるので、以下を入力し、[登録]をクリックします。

名前:<任意のアプリ名>
サポートされているアカウントの種類:この組織ディレクトリのみに含まれるアカウント (XXXXのみ - シングル テナント)

登録後、アプリケーション (クライアント) IDとディレクトリ (テナント) IDをテキスト等にコピーしておきます。


1-2.アクセス許可の設定

<任意のアプリ名> - [APIのアクセス許可] - [アクセス許可の追加]をクリックします。

[Microsoft Graph] - [委任されたアクセス許可] - [SMTP.Send]を追加します。


1-3.認証の設定

<任意のアプリ名> - [認証] - [パブリック クライアント フローを許可する]にて、

以下を入力し、[保存]をクリックします。

次のモバイルとデスクトップのフローを有効にする:はい

2.OAuth対応メールリレーサーバのコンテナ起動

2-1.ディレクトリ移動と事前作成済みのファイル存在確認

cd /var/tmp/container/oauth_mailrelay
ls
Dockerfile  startup_postfix.sh

2-2.各ファイルの内容確認

cat Dockerfile
FROM ubuntu:24.04

# oauthメールリレーサーバに必要なパッケージのインストール
RUN apt-get update && apt-get upgrade -y && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y postfix
RUN apt-get update && \
    apt-get install -y software-properties-common && \
    add-apt-repository -y ppa:sasl-xoauth2/stable && \
    apt-get install -y sasl-xoauth2

# 便利パッケージインストール
RUN apt-get install -y iproute2 vim iputils-ping

# ディレクトリ作成・権限変更
RUN mkdir -p /var/spool/postfix/etc/tokens
RUN chown -R postfix:postfix /var/spool/postfix/etc/tokens

# main.cf編集
RUN cp /etc/postfix/main.cf.proto /etc/postfix/main.cf
RUN sed -i -e 's|#mail_owner = postfix|mail_owner = postfix|' \
    -e 's|#myhostname = virtual.domain.tld|myhostname = oauthub01.<ドメイン>|' \
    -e 's|#mydomain = domain.tld|mydomain = <ドメイン>|' \
    -e 's|#myorigin = $mydomain|myorigin = $mydomain|' \
    -e 's|#inet_interfaces = all|inet_interfaces = all|' \
    -e 's|#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,|mydestination = $myhostname, localhost.$mydomain, localhost|' \
    -e 's|mynetworks = 127.0.0.0/8|mynetworks = 127.0.0.0/8,<メール送信者が所属するネットワーク>|' \
    -e 's|#relay_domains =|relay_domains = $mydestination|' \
    -e 's|#relayhost = \[an.ip.add.ress\]|relayhost = [smtp.office365.com]:587|' \
    -e 's|#alias_maps = hash:/etc/aliases, nis:mail.aliases|alias_maps = hash:/etc/aliases|' \
    -e 's|#alias_database = hash:/etc/aliases, hash:/opt/majordomo/aliases|alias_database = hash:/etc/aliases|' \
    -e 's|smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)|smtpd_banner = $myhostname ESMTP|' \
    -e 's|sendmail_path =|sendmail_path = /usr/sbin/postfix|' \
    -e 's|newaliases_path =|newaliases_path = /usr/bin/newaliases|' \
    -e 's|mailq_path =|mailq_path = /usr/bin/mailq|' \
    -e 's|setgid_group =|setgid_group = postdrop|' \
    -e 's|html_directory =|#html_directory =|' \
    -e 's|manpage_directory =|#manpage_directory =|' \
    -e 's|sample_directory =|#sample_directory =|' \
    -e 's|readme_directory =|#readme_directory =|' \
    /etc/postfix/main.cf
RUN printf "\n# XOAUTH2 Settings\
    \nsmtp_sasl_auth_enable = yes\
    \nsmtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd\
    \nsmtp_sasl_security_options =\
    \nsmtp_sasl_mechanism_filter = xoauth2\
    \n\
    \n# TLS Settings\
    \nsmtp_tls_security_level = encrypt\
    \nsmtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt\
    \nsmtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache\
    \n\
    \n# Maillog Settings\
    \nmaillog_file = /var/log/mail.log\n"\
    >> /etc/postfix/main.cf

# sasl-xoauth2.conf編集
RUN mv /etc/sasl-xoauth2.conf /etc/sasl-xoauth2.conf.bak
RUN printf "{\
    \n  \"client_id\": \"<任意のアプリ名のアプリケーション (クライアント) ID>\",\
    \n  \"client_secret\": \"\",\
    \n  \"token_endpoint\": \"https://login.microsoftonline.com/organizations/oauth2/v2.0/token\"\
    \n}\n"\
    > /etc/sasl-xoauth2.conf
RUN chmod --reference=/etc/sasl-xoauth2.conf.bak /etc/sasl-xoauth2.conf

# タイムゾーン変更
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
cat startup_postfix.sh
#!/bin/bash

# ボリュームの存在を確認
docker volume inspect postfix > /dev/null 2>&1

# コマンドの終了ステータスを取得
rc=$?

# 終了ステータスに基づいてメッセージを表示
if [ $rc -eq 0 ]; then
    echo "Already create postfix volume."
else
    # ボリュームを作成
    docker volume create postfix
    echo "Create postfix volume."
fi

# Dockerコンテナを起動
docker run --name ubuntu_oauth_mailrelay_server -v postfix:/var/log -p 50003:25 -it ubuntu_oauth_mailrelay_image

とりあえず、/var/log/mail.logなどのログが残ればいいかなと思い、

volume(postfix)をコンテナ内の/var/logにディレクトリにマウントしました。


2-3.Dockerイメージのビルド

docker build --no-cache -t ubuntu_oauth_mailrelay_image .

2-4.Dockerコンテナの起動

sudo ./startup_postfix.sh

※起動後、対象コンテナに入ります。


3.コンテナ内での認証情報等の設定

3-1.Postfixの認証情報を設定

vi /etc/postfix/sasl_passwd

[smtp.office365.com]:587 <Entra IDアカウント>:/etc/tokens/<トークンファイル名(Entra IDアカウント)>
postmap /etc/postfix/sasl_passwd

3-2.トークンを取得

sasl-xoauth2-tool get-token outlook /var/spool/postfix/etc/tokens/<トークンファイル名> --tenant=<ディレクトリ (テナント) ID> --client-id=<アプリケーション (クライアント) ID> --use-device-flow

以下のように表示されるのでWEBブラウザでURLを入力し認証する

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXXXX to authenticate.

認証が成功すると以下と表示される

Acquired token.

トークンファイルは以下のように更新される


cat /var/spool/postfix/etc/tokens/<トークンファイル名>
{
    "access_token": "XXXXXXXXXXXXXXXXX...",
    "refresh_token": "XXXXXXXXXXXXXXXXX...",
    "expiry": XXX...
}

3-3.トークンディレクトリの所有者を変更

chown -R postfix:postfix /var/spool/postfix/etc/tokens

3-4.Postfixサービスの再起動

service postfix restart

これをしないと、ポート25がLISTENにならない。


4.メールテスト

4-1.メールテスト

nPOP等で、ホストOSのIPアドレスと対象コンテナのホストOS側のポートに向けてテストメールを送信し、送信先に届いていることを確認する。


※今回は以下で対象コンテナを起動しているので、ホストOS側のポート番号は"50003"です。

docker run --name ubuntu_oauth_mailrelay_server -v postfix:/var/log -p 50003:25 -it ubuntu_oauth_mailrelay_image

最後に

今回は、OAuth対応メールリレーサーバの仕組みを理解することに苦戦しました。。。

個人的になのですが、認証系は特にイメージが湧きにくいので難しい印象です。

Docker含め学んでいきます!

閲覧数:40回0件のコメント

最新記事

すべて表示

SIerとSESのビジネスモデルの変化

最近動画配信サイトなどで、エンジニア転職支援やフリーランス支援などをしている人たちの会話を聞いていて、”この界隈”のエンジニアは、SIerとSES(人材派遣やSE派遣などの総称)の区別がついていないことに驚きました。 私がこの業界に入った頃は、SIer事業とSES事業は共通...

NetApp(ONTAP)のAPIでファイルサーバの調査

背景 弊社から提供したNetAppの使用状況を調査したいという要望がお客様よりありました。一般的には、PowerShellとかで、最終アクセス日や変更日などを取得するスクリプトで取得するのですが、NetAppは、別マシンからネットワーク越しに実施するので、遅くなりそうという...

コメント


bottom of page