4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

docker-postfixでDKIM対応送信専用SMTPリレーを立てる

Last updated at Posted at 2021-05-02

概要

docker-postfixを使用してDockerのコンテナ内リンク(またはローカルネットワークやVPN)からの送信専用SMTPリレー(SMTPサーバ)を構築した際のメモ。

作者公式Dockerイメージをdocker-composeでハンドリングしてDKIMに対応させる。自身の用途としてはdocker-composeで構築したオンプレアプリ類からユーザーへのメール配信用。

なお、実績のないドメインからのメールはSPFもDKIMも関係なく問答無用で迷惑メール扱いされるのが普通で、アカウント云々の文言が含まれる場合は尚更である。ユーザーへの念押しは必須。

※RHEL8互換環境を想定、それ以外の場合は必要に応じて読み替えのこと

DKIM

docker-postfixではDKIMはoptionalのため、鍵は自分で用意する必要がある。今回はOpenDKIMを使用し、ホスト上で鍵を作成してvolumesでマウントする。

パッケージのインストール

DKIM鍵を生成するためにホストにOpenDKIMと依存パッケージをインストールする。

shell
dnf install -y opendkim opendkim-tools
  • OpenDKIMはEPELに収録されている

鍵の生成

shell
mkdir -p /etc/opendkim/keys/<DOMAIN>
opendkim-genkey -b 2048 -d <DOMAIN> -D /etc/opendkim/keys/<DOMAIN> -s <SELECTOR> -v
  • <DOMAIN> は使用するドメイン名( exmaple.com 等)
  • <SELECTOR> はDKIM鍵の識別名のようなもの(例えば mail 等)
    • 指定しないと default になる
  • 実行すると秘密鍵が /etc/opendkim/keys/<DOMAIN>/<SELECTOR>.private に生成され、TXTレコードの内容が /etc/opendkim/keys/<DOMAIN>/<SELECTOR>.txt に出力される

DNS

DKIMレコード

出力された /etc/opendkim/keys/<DOMAIN>/<SELECTOR>.txt を元にDNSにDKIMレコードを追加する。OpenDKIMが出力するテキストはzoneファイルの書式のためbindならそのまま使える。

<SELECTOR>._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIB......"
  • Type: TXT
  • Name: <SELECTOR>._domainkey
  • Value: v=DKIM1; k=rsa; p=MIIB......
    • /etc/opendkim/keys/<DOMAIN>/<SELECTOR>.txt の二重引用符の中身を連結したもの
  • TTL: 適当
LuaDNSにおける設定例

image.png

SPFレコード

わかりやすい解説が大量にあるため検索して参照のこと。

<DOMAIN>. IN TXT "v=spf1 +ip4:<GLOBAL_IP>/32 -all"
  • 修飾子 + - ~ ? はその条件に一致した場合の扱いを規定する
    • + : 認証する(省略可)/ - : 認証しない/ ~ : 認証しないが受信推奨/ ? : 認証の有無を評価しない
  • よって設定した条件以外で送る可能性が全くない場合、allディレクティブの修飾子は ~ ではなく厳格な - の方がより安全
LuaDNSにおける設定例

image.png

Composeファイル

environmentの項目はdocker-postfixのreadmeを参照のこと。

コンテナ間リンク用設定例

docker-compose.yml
version: '3.8'

services:
  smtp:
    image: panubo/postfix:latest
    container_name: smtp
    hostname: smtp-server
    environment:
      - MAILNAME=<DOMAIN>
      - TZ=Asia/Toyo
      - USE_TLS=no
      - USE_DKIM=yes
      - DKIM_KEYFILE=/etc/opendkim/keys/<DOMAIN>/<SELECTOR>.private
      - DKIM_SELECTOR=<SELECTOR>
    expose:
       #- '25'
       - '587'
    volumes:
      - /etc/opendkim:/etc/opendkim
    networks:
      - container-link
    logging:
      options:
        max-size: "10m"
        max-file: "3"

networks:
  default:
    external:
      name: bridge
  container-link:
    name: docker.internal
  • 各コンテナで指定するSMTPサーバのアドレスはdocker-postfixコンテナのhostnameと待ち受けポートになる
    • この設定例では smtp-server:587 を指定することになる
  • 許可するIP範囲は明示的に指定しないと 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 に設定される
    • コンテナ間リンクで使用する場合はそのままでOKと思われる
  • TLSは標準でON( USE_TLS=yes )のため、不要なら明示的に切る必要がある
    • コンテナ間リンク内で閉じているなら不要と思われる
  • DKIMを有効化し、先の手順で作成したDKIM鍵をマウントして使用する
  • コンテナ間リンクに明示的に命名したbridgeネットワークを使用している
    • 立てたSMTPサーバを使用するコンテナはこのネットワークに繋げること
  • 当然ながらメールにはSMTPのチェーンの始点となる送信元コンテナのhostnameとIPが記載される
  • 内部アクセス専用のため認証はない

その他設定例

ローカルIP 10.0.0.1 のアダプタ上でIPアドレス範囲 10.0.0.0/24 からのアクセスのみ待ち受ける

docker-compose.yml
    environment:
      - MYNETWORKS=10.0.0.0/24
    ports:
      - '10.0.0.1:587:587'

TLSの使用を強制し、Let's Encryptの証明書と鍵を使用(使用するドメインで繋がるようにしておく必要がある)

docker-compose.yml
    environment:
      - USE_TLS=yes
      - TLS_SECURITY_LEVEL=encrypt
      - TLS_KEY=/etc/letsencrypt/live/<DOMAIN>/privkey.pem
      - TLS_CRT=/etc/letsencrypt/live/<DOMAIN>/fullchain.pem
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt

実際のヘッダー

Gmailに送ったもの。

image.png

  • s=mail<SELECTOR> のこと
  • Received に送信元コンテナのホスト名とIPが入っている
4
6
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
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?