MENU

メール技術検証 セキュリティ設定・検証編

目次

はじめに

何をしたいか

実際にメールサーバーを構築し、メールの送受信の仕組みを理解する。
また、SPF・DKIM・DMARCによる送信ドメイン認証、SMTP AUTHによるユーザー認証、TLSによる通信の暗号化について、設定と動作検証を通して理解を深める。
本記事では、SMTP AUTH・STARTTLSの設定と動作確認に加え、SPF・DKIM・DMARCの設定および認証結果の確認を実施する。

メール技術検証 構築編 https://cybermemo.blog/mail-server-setup
メール技術検証 セキュリティ設定・検証編 本記事

本記事で構築する構成

DNSの構成および設定内容は、一部簡略化して記載。
※構成図に使用したアイコンは、素材サイト「CMAN」からダウンロードしたものです。

構成図

検証環境

仮想化ソフトウェア:Oracle VirtualBox
ゲストOS:Ubuntu Server 26.04.1 LTS(amd64)
SMTPサーバー:Postfix 3.10.6
IMAPサーバー:Dovecot 2.4.2
DKIM署名:OpenDKIM 2.11.0
DMARC検証:OpenDMARC 1.4.2
権威DNS:BIND 9.20.24
フルリゾルバ:Unbound 1.24.2
内部ネットワーク:192.168.56.0/24
検証ドメイン:child.lab.test
メールサーバー:mail.child.lab.test(192.168.56.50)

SMTP AUTH

SMTP AUTHの設定

# SMTPの設定確認
$ sudo postconf -n | grep -E '^(smtpd_sasl_|smtpd_tls_|smtpd_recipient_restrictions|smtpd_relay_restrictions)'
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level = may

# Dovecotの認証設定を確認(一部結果を抜粋)
$ sudo doveconf -n
passdb pam {
}
userdb passwd {
}
(中略)
service auth {                      # Postfix用の認証ソケットが設定されていない
  unix_listener auth-userdb {
  }

# Postfix用の認証ソケットをDovecotで追加
$ sudo vim /etc/dovecot/conf.d/10-master.conf
service auth {
  unix_listener auth-userdb {
  }
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
}

# Dovecotを再起動
$ sudo systemctl restart dovecot
$ sudo systemctl is-active dovecot
active

# 認証ソケットを確認
$ sudo ls -l /var/spool/postfix/private/auth
srw-rw---- 1 postfix postfix 0 Oct 11 09:44 /var/spool/postfix/private/auth

# PostfixでSMTP AUTHを有効化する
$ sudo postconf -e 'smtpd_sasl_type = dovecot'  # 認証処理にDovecotを使用する
$ sudo postconf -e 'smtpd_sasl_path = private/auth'  # Dovecotの認証ソケットを指定する
$ sudo postconf -e 'smtpd_sasl_auth_enable = yes'  # SMTP AUTHを有効にする
$ sudo postconf -e 'smtpd_tls_auth_only = yes'  # TLSで保護された接続でのみSMTP AUTHを許可する
$ sudo postconf -n | grep -E '^(smtpd_sasl_|smtpd_tls_auth_only)'
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_type = dovecot
smtpd_tls_auth_only = yes

# チェックと再読み込み
$ sudo postfix check
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system

SMTP AUTHの動作確認

# Clientで作業
# SMTPの接続/設定確認
# TLSで暗号化される前のSMTP AUTHを禁止できている
$ nc 192.168.56.50 25
220 mail.child.lab.test ESMTP Postfix (Ubuntu)
EHLO client.child.lab.test
250-mail.child.lab.test
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING

# SMTP AUTHの認証に必要なユーザー名とパスワードをBase64形式に変換
# 控えておく
$ printf '\0mailadmin\0パスワード' | base64 -w 0
echo
Base64の文字列が表示される

# STARTTLSで接続
# SMTP AUTHが利用可能
$ openssl s_client \
> -connect 192.168.56.50:25 \
> -starttls smtp \
> -servername mail.child.lab.test \
> -crlf -quiet
Connecting to 192.168.56.50
depth=0 CN=mail.child.lab.test
verify error:num=18:self-signed certificate  # 自己署名証明書を使用している場合のエラーコード
verify return:1
depth=0 CN=mail.child.lab.test
verify return:1
250 CHUNKING
EHLO client.child.lab.test
250-mail.child.lab.test
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
AUTH PLAIN Base64の文字列を入力
235 2.7.0 Authentication successful
QUIT

# 認証失敗した時の挙動確認
$ openssl s_client \
> -connect 192.168.56.50:25 \
> -starttls smtp \
> -servername mail.child.lab.test \
> -crlf -quiet
Connecting to 192.168.56.50
depth=0 CN=mail.child.lab.test
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN=mail.child.lab.test
verify return:1
250 CHUNKING
EHLO client.child.lab.test
250-mail.child.lab.test
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
AUTH PLAIN Base64の文字列を入力
535 5.7.8 Error: authentication failed: (reason unavailable)
QUIT

SMTPのTLS証明書設定/検証

# メールサーバーで作業
# Dovecotの証明書確認
# Dovecotの証明書をSMTPでも利用できる
$ sudo openssl x509 \
> -in /etc/dovecot/private/dovecot.pem \
> -noout -subject -issuer -dates -ext subjectAltName
[sudo: authenticate] Password:
subject=CN=mail.child.lab.test
issuer=CN=mail.child.lab.test
notBefore=Oct 11 03:46:37 2026 GMT
notAfter=Oct 11 03:46:37 2027 GMT
X509v3 Subject Alternative Name:
    DNS:mail.child.lab.test

# 証明書と秘密鍵の対応確認
$ sudo openssl x509 \
> -in /etc/dovecot/private/dovecot.pem \
> -pubkey -noout |
> openssl pkey -pubin -outform DER |
> openssl dgst -sha256
SHA2-256(stdin)= eb94739707f633c7d23b69869be9c52956e955615fe93d9a9ad66d0d6b5dcc52  
$ sudo openssl pkey \
> -in /etc/dovecot/private/dovecot.key \
> -pubout -outform DER |
> openssl dgst -sha256
SHA2-256(stdin)= eb94739707f633c7d23b69869be9c52956e955615fe93d9a9ad66d0d6b5dcc52  # ハッシュ値が一致

# Postfixの証明書設定を確認
$ postconf -f smtpd_tls_cert_file smtpd_tls_key_file
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key

# Postfixの証明書設定を変更
$ sudo postconf -e 'smtpd_tls_cert_file = /etc/dovecot/private/dovecot.pem'
$ sudo postconf -e 'smtpd_tls_key_file = /etc/dovecot/private/dovecot.key'
$ postconf -f smtpd_tls_cert_file smtpd_tls_key_file
smtpd_tls_cert_file = /etc/dovecot/private/dovecot.pem
smtpd_tls_key_file = /etc/dovecot/private/dovecot.key

# 設定チェックと再読み込み
# warningとなっているため、今回の検証環境ではrootに変更
$ sudo postfix check
postfix/postfix-script: warning: not owned by root: /var/spool/postfix/etc/resolv.conf
$ ls -l /var/spool/postfix/etc/resolv.conf
-rw-r--r-- 1 systemd-resolve systemd-resolve 920 Oct 12 01:55 /var/spool/postfix/etc/resolv.conf
$ sudo chown root:root /var/spool/postfix/etc/resolv.conf
$ ls -l /var/spool/postfix/etc/resolv.conf
-rw-r--r-- 1 root root 920 Oct 12 01:55 /var/spool/postfix/etc/resolv.conf
$ sudo postfix check
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system

# Clientで作業
# PostfixがDovecotと共通の自己署名証明書を提示しているか確認
~$ openssl s_client \
> -connect 192.168.56.50:25 \
> -starttls smtp \
> -servername mail.child.lab.test \
> -showcerts
Connecting to 192.168.56.50
CONNECTED(00000003)
depth=0 CN=mail.child.lab.test
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN=mail.child.lab.test
verify return:1
---
Certificate chain
 0 s:CN=mail.child.lab.test
   i:CN=mail.child.lab.test
   a:PKEY: RSA, 3072 (bit); sigalg: sha256WithRSAEncryption
   v:NotBefore: Oct 11 03:46:37 2026 GMT; NotAfter: Oct 11 03:46:37 2027 GMT
-----BEGIN CERTIFICATE-----
(以下省略)

# Dovecotの証明書を再利用
~$ openssl s_client \
> -connect 192.168.56.50:25 \
> -starttls smtp \
> -servername mail.child.lab.test \
> -CAfile ~/mail-server.crt \
> -verify_hostname mail.child.lab.test \
> -verify_return_error
Connecting to 192.168.56.50
CONNECTED(00000003)
depth=0 CN=mail.child.lab.test
verify return:1
---
Certificate chain
 0 s:CN=mail.child.lab.test
   i:CN=mail.child.lab.test
   a:PKEY: RSA, 3072 (bit); sigalg: sha256WithRSAEncryption
   v:NotBefore: Oct 11 03:46:37 2026 GMT; NotAfter: Oct 11 03:46:37 2027 GMT
---
Server certificate
(中略)
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Server public key is 3072 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)  # エラーなし
--- 
(以下省略)

WiresharkでSMTP通信をキャプチャ

IMAPのときと同様に、STARTTLSによるTLSハンドシェイク以降の通信が暗号化されている。

wireshark_smtp_tls

SPF

SPFの設定

# Child DNSのゾーンファイルにTXTレコードを追加
$ sudo vim /etc/bind/db.child.lab.test
$TTL 3600

@       IN SOA ns dnsmaster (
                2026101201 ; Serial
                3600       ; Refresh
                900        ; Retry
                4800     ; Expire
                86400      ; Negative Cache TTL
)

        IN NS   ns

ns      IN A    192.168.56.20
www     IN A    192.168.56.100
mail    IN A    192.168.56.50
@       IN MX   10 mail.child.lab.test.# Serialを変更
@       IN TXT  "v=spf1 ip4:192.168.56.50 -all" # SPFの設定を追記

# 構文チェック
$ sudo named-checkzone child.lab.test /etc/bind/db.child.lab.test
zone child.lab.test/IN: loaded serial 2026101201
OK

# BINDを再読み込み
$ sudo rndc reload child.lab.test
zone reload queued

# Clientで確認
$ dig @192.168.56.30 child.lab.test TXT +short
"v=spf1 ip4:192.168.56.50 -all"

# メールサーバーにDNSの参照先を設定
$ sudo vim /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    enp0s3:
      dhcp4: true
      dhcp6: true
      match:
        macaddress: macaddress
      set-name: enp0s3

    enp0s8:
      dhcp4: false
      addresses:
        - 192.168.56.50/24
      nameservers:
        addresses:
          - 192.168.56.30
        search:
          - ~child.lab.test # 追記部分
  version: 2
$ sudo netplan generate
$ sudo netplan try

# pypolicyd-spfをインストール
$ sudo apt install postfix-policyd-spf-python

# pypolicyd-spfの設定確認
$ cat /etc/postfix-policyd-spf-python/policyd-spf.conf
#  For a fully commented sample config file see policyd-spf.conf.commented

debugLevel = 1         # ログの詳細度
TestOnly = 1         # テストモード。SPFの判定結果による拒否を実施しない

HELO_reject = Fail         # HELOドメインのSPF結果がFailの場合の拒否方針
Mail_From_reject = Fail         # MAIL FROMドメインのSPF結果がFailの場合の拒否方針

PermError_reject = False         # SPFの恒久的な評価エラーでは拒否しない
TempError_Defer = False         # SPFの一時的な評価エラーでは配送を延期しない

skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1      # 指定したループバックアドレスを検査対象から除外

# Mail_From_rejectをFalseへ変更
$ sudo vim /etc/postfix-policyd-spf-python/policyd-spf.conf
Mail_From_reject = False 

# Postfix設定を確認
$ postconf -n smtpd_recipient_restrictions smtpd_relay_restrictions smtpd_sasl_auth_enable mynetworks
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_sasl_auth_enable = yes
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

# SPFポリシーサービスをPostfixに登録
$ sudo postconf -M 'policyd-spf/unix=policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spf'
$ sudo postconf -e 'smtpd_recipient_restrictions = check_policy_service unix:private/policyd-spf'

# Postfixの再読み込み
$ sudo postfix check
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system

# 設定が反映されているか確認
$ postconf -n smtpd_recipient_restrictions
smtpd_recipient_restrictions = check_policy_service unix:private/policyd-spf

SPFの検証

# Clientからメールサーバーへメールを送信
~$ openssl s_client -connect mail.child.lab.test:25 -starttls smtp -servername mail.child.lab.test -CAfile ~/mail-server.crt -verify_hostname mail.child.lab.test -verify_return_error -crlf -quiet
Connecting to 192.168.56.50
depth=0 CN=mail.child.lab.test
verify return:1
250 CHUNKING
EHLO client.child.lab.test
250-mail.child.lab.test
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
AUTH PLAIN Base64の文字列を入力
235 2.7.0 Authentication successful
MAIL FROM:<sender@child.lab.test>
250 2.1.0 Ok
RCPT TO:<mailadmin@child.lab.test>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: sender@child.lab.test
To: mailadmin@child.lab.test
Subject: SPF Test

This is an SPF test mail.
.
250 2.0.0 Ok: queued as 4765340192
QUIT
221 2.0.0 Bye

# メールサーバーで受信メールを確認
$ sudo cat /var/mail/mailadmin
From sender@child.lab.test  Mon Oct 12 06:22:57 2026
Return-Path: <sender@child.lab.test>
X-Original-To: mailadmin@child.lab.test
Delivered-To: mailadmin@child.lab.test
Received-SPF: Fail (mailfrom) identity=mailfrom; client-ip=192.168.56.40; helo=client.child.lab.test; envelope-from=sender@child.lab.test; receiver=child.lab.test  # 192.168.56.50だけを許可しているため、192.168.56.40からの送信はFail
Received: from client.child.lab.test (unknown [192.168.56.40])
        by mail.child.lab.test (Postfix) with ESMTPSA id 4765340192  # SMTP AUTH:成功   
        for <mailadmin@child.lab.test>; Mon, 12 Oct 2026 06:22:33 +0000 (UTC)
From: sender@child.lab.test
To: mailadmin@child.lab.test
Subject: SPF Test

This is an SPF test mail.

# 一時的にSPFレコードへクライアントのIPを追加
@       IN TXT  "v=spf1 ip4:192.168.56.50 ip4:192.168.56.40 -all"

# 構文チェック
$ sudo named-checkzone child.lab.test /etc/bind/db.child.lab.test
zone child.lab.test/IN: loaded serial 2026101201
OK

# BINDを再読み込み
$ sudo rndc reload child.lab.test
zone reload queued

# メールサーバーでSPFレコードを確認
$ dig @192.168.56.30 child.lab.test TXT +short
"v=spf1 ip4:192.168.56.50 ip4:192.168.56.40 -all"

# Clientからメールサーバーへメールを送信
$ openssl s_client -connect mail.child.lab.test:25 -starttls smtp -servername mail.child.lab.test -CAfile ~/mail-server.crt -verify_hostname mail.child.lab.test -verify_return_error -crlf -quiet
(以下省略)

# メールサーバーで受信メールを確認
# SPF:Passを確認
$ sudo cat /var/mail/mailadmin
From sender@child.lab.test  Mon Oct 12 06:44:42 2026
Return-Path: <sender@child.lab.test>
X-Original-To: mailadmin@child.lab.test
Delivered-To: mailadmin@child.lab.test
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.168.56.40; helo=client.child.lab.test; envelope-from=sender@child.lab.test; receiver=child.lab.test
Received: from client.child.lab.test (unknown [192.168.56.40])
        by mail.child.lab.test (Postfix) with ESMTPSA id AC4CD40192
        for <mailadmin@child.lab.test>; Mon, 12 Oct 2026 06:44:11 +0000 (UTC)
From: sender@child.lab.test
To: mailadmin@child.lab.test
Subject: SPF Test2

This is an SPF test mail2.

DKIM

DKIMの設定

# OpenDKIMのインストール
$ sudo apt update
$ sudo apt install opendkim opendkim-tools
$ opendkim -V
opendkim: OpenDKIM Filter v2.11.0
        Compiled with OpenSSL 3.5.5 27 Jan 2026
(以下省略)
~$ sudo systemctl status opendkim
● opendkim.service - OpenDKIM Milter
     Loaded: loaded (/usr/lib/systemd/system/opendkim.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-10-12 06:57:57 UTC; 53s ago

# 鍵の保存ディレクトリを作成
$ sudo mkdir -p /etc/opendkim/keys/child.lab.test

# DKIM署名に使用する秘密鍵と公開鍵を生成
$ cd /etc/opendkim/keys/child.lab.test
$ sudo opendkim-genkey -b 2048 -s mail2026 -d child.lab.test
$ sudo ls -l /etc/opendkim/keys/child.lab.test/
total 8
-rw------- 1 root root 1704 Oct 12 07:01 mail2026.private
-rw------- 1 root root  512 Oct 12 07:01 mail2026.txt
$ sudo chown opendkim:opendkim /etc/opendkim/keys/child.lab.test/mail2026.private
$ sudo chmod 600 /etc/opendkim/keys/child.lab.test/mail2026.private
$ sudo ls -l /etc/opendkim/keys/child.lab.test/
total 8
-rw------- 1 opendkim opendkim 1704 Oct 12 07:01 mail2026.private
-rw------- 1 root     root      512 Oct 12 07:01 mail2026.txt
$ sudo cat mail2026.txt
mail2026._domainkey     IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+gujScccmTP7w433GOLV0ddx7/jHv/WVMtn/6JxyVhcFQpCkr6oi13zR6yQPcgoDxvInlk1FkVcB2OfCO/18zxeSLLpoH0FqVGemSInM5lkc/ZLPEIbdgTqOki3i/0ZcYKo7KVE173FyA109a3SuJoEPHn6RFWsAXFwAvzF5FUTBMyCEXwHBCRdyCr8OMbSwqH6zS6Q4Kyizx"
          "q9GGqweQwWYmruZcXArwEaFI3iYDZF5T9rfbfwRoAe6tAzdRgjIl7ntFa9PrKauSfUp8hCiKFg+rSErvNec5wBx8Sq1MyKJ77EQ8DkqtpE1/P+FWc72oD/IWkO+xgA/V9tkDHKnwIDAQAB" )  ; ----- DKIM key mail2026 for child.lab.test

# Child DNSのゾーンファイルにTXTレコードを追記
$ sudo vim /etc/bind/db.child.lab.test
$TTL 3600

@       IN SOA ns dnsmaster (
                2026101202 ; Serial
                3600       ; Refresh
                900        ; Retry
                4800     ; Expire
                86400      ; Negative Cache TTL
)

        IN NS   ns

ns      IN A    192.168.56.20
www     IN A    192.168.56.100
mail    IN A    192.168.56.50
@       IN MX   10 mail.child.lab.test.
@       IN TXT  "v=spf1 ip4:192.168.56.50 ip4:192.168.56.40 -all" # Serialを変更
# DKIM公開鍵のTXTレコードを追記
mail2026._domainkey     IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+gujScccmTP7w433GOLV0ddx7/jHv/WVMtn/6JxyVhcFQpCkr6oi13zR6yQPcgoDxvInlk1FkVcB2OfCO/18zxeSLLpoH0FqVGemSInM5lkc/ZLPEIbdgTqOki3i/0ZcYKo7KVE173FyA109a3SuJoEPHn6RFWsAXFwAvzF5FUTBMyCEXwHBCRdyCr8OMbSwqH6zS6Q4Kyizx"
          "q9GGqweQwWYmruZcXArwEaFI3iYDZF5T9rfbfwRoAe6tAzdRgjIl7ntFa9PrKauSfUp8hCiKFg+rSErvNec5wBx8Sq1MyKJ77EQ8DkqtpE1/P+FWc72oD/IWkO+xgA/V9tkDHKnwIDAQAB" )  ; ----- DKIM key mail2026 for child.lab.test

# 構文チェック
$ sudo named-checkzone child.lab.test /etc/bind/db.child.lab.test
zone child.lab.test/IN: loaded serial 2026101202
OK

# BINDを再読み込み
$ sudo rndc reload child.lab.test
zone reload queued

# 設定が反映されているか確認
# Child DNSで確認
$ dig @127.0.0.1 mail2026._domainkey.child.lab.test TXT +noall +answer
mail2026._domainkey.child.lab.test. 3600 IN TXT "v=DKIM1; h=sha256; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+gujScccmTP7w433GOLV0ddx7/jHv/WVMtn/6JxyVhcFQpCkr6oi13zR6yQPcgoDxvInlk1FkVcB2OfCO/18zxeSLLpoH0FqVGemSInM5lkc/ZLPEIbdgTqOki3i/0ZcYKo7KVE173FyA109a3SuJoEPHn6RFWsAXFwAvzF5FUTBMyCEXwHBCRdyCr8OMbSwqH6zS6Q4Kyizx" "q9GGqweQwWYmruZcXArwEaFI3iYDZF5T9rfbfwRoAe6tAzdRgjIl7ntFa9PrKauSfUp8hCiKFg+rSErvNec5wBx8Sq1MyKJ77EQ8DkqtpE1/P+FWc72oD/IWkO+xgA/V9tkDHKnwIDAQAB"

# Clientで確認
$ dig @192.168.56.30 mail2026._domainkey.child.lab.test TXT +noall +answer
mail2026._domainkey.child.lab.test. 3600 IN TXT "v=DKIM1; h=sha256; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+gujScccmTP7w433GOLV0ddx7/jHv/WVMtn/6JxyVhcFQpCkr6oi13zR6yQPcgoDxvInlk1FkVcB2OfCO/18zxeSLLpoH0FqVGemSInM5lkc/ZLPEIbdgTqOki3i/0ZcYKo7KVE173FyA109a3SuJoEPHn6RFWsAXFwAvzF5FUTBMyCEXwHBCRdyCr8OMbSwqH6zS6Q4Kyizx" "q9GGqweQwWYmruZcXArwEaFI3iYDZF5T9rfbfwRoAe6tAzdRgjIl7ntFa9PrKauSfUp8hCiKFg+rSErvNec5wBx8Sq1MyKJ77EQ8DkqtpE1/P+FWc72oD/IWkO+xgA/V9tkDHKnwIDAQAB"

# DKIMの設定ファイルを編集
# 末尾に設定を追加、TrustAnchorFileをコメントアウト
$ sudo vim /etc/opendkim.conf
# TrustAnchorFile               /usr/share/dns/root.key
Domain                  child.lab.test
Selector                mail2026
KeyFile                 /etc/opendkim/keys/child.lab.test/mail2026.private
InternalHosts 127.0.0.1,192.168.56.40,192.168.56.50
$ sudo systemctl restart opendkim
$ sudo systemctl is-active opendkim
active

# Postfixにアクセス権限を付与
$ sudo usermod -aG opendkim postfix
$ id postfix
uid=104(postfix) gid=108(postfix) groups=108(postfix),113(opendkim)

# PostfixにMilterを設定
$ sudo postconf -e 'milter_default_action = accept'  # OpenDKIMに接続できなくてもメール配送を継続する
$ sudo postconf -e 'milter_protocol = 6'  # Milterの通信バージョンを指定する
$ sudo postconf -e 'smtpd_milters = unix:/run/opendkim/opendkim.sock'  # SMTP経由のメールをOpenDKIMに渡す
$ sudo postconf -e 'non_smtpd_milters = $smtpd_milters'  # SMTP以外の方法で投入したメールもOpenDKIMに渡す
$ sudo postfix check
$ sudo systemctl restart postfix
$ postconf -n | grep -i milter
milter_default_action = accept
milter_protocol = 6
non_smtpd_milters = $smtpd_milters
smtpd_milters = unix:/run/opendkim/opendkim.sock

DKIMの検証

# Clientからメールを送信
$ openssl s_client -connect mail.child.lab.test:25 \
  -starttls smtp \
  -servername mail.child.lab.test \
  -CAfile ~/mail-server.crt \
  -verify_hostname mail.child.lab.test \
  -verify_return_error -crlf -quiet
Connecting to 192.168.56.50
(以下省略)

# メールサーバーで受信メールを確認
# DKIM-Signatureが付与されていることを確認
From sender@child.lab.test  Mon Oct 12 08:54:54 2026
Return-Path: <sender@child.lab.test>
X-Original-To: mailadmin@child.lab.test
Delivered-To: mailadmin@child.lab.test
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=child.lab.test;
        s=mail2026; t=1791795294;
        bh=HVREf258z0xWefGDJ0Yl3/J6t5bA18K5/8ObJPMRfHw=;
        h=From:To:Subject:From;
        b=I99FPsCf8csL+TX07Xxw+iuEQigTv073pNf3OEVyHRk2hupX4uMrY9imolccLIA5s
         5j6ZROnAIf9Cal6vYTNEsczcV41lODJzE9i3sYHJO0sXdR8ul0sl3y5jMYYlEikRYD
         dU8LQb4tO4FKoxzUmeMZYQntV8No2JlwROflgyNpAf5CBY4j20QgXZX2BkLWpExTkf
         jInayD52LQSnN1SwPTcAMRrE/+ay4WCr9iIZxDGFx68kmnwPtBlQPa6kNu+W5hUszC
         PMma5U0rIIyCPqfqy8pphp73b3SATSRQ2vAMOq6a1i/sMEtwLrwGghBXhHFx7shagZ
         zCEygIX68tHkg==
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.168.56.40; helo=client.child.lab.test; envelope-from=sender@child.lab.test; receiver=child.lab.test
Received: from client.child.lab.test (unknown [192.168.56.40])
        by mail.child.lab.test (Postfix) with ESMTPSA id A4FDB4048A
        for <mailadmin@child.lab.test>; Mon, 12 Oct 2026 08:53:56 +0000 (UTC)
From: sender@child.lab.test
To: mailadmin@child.lab.test
Subject: DKIM Test2

This is a DKIM test mail.

DMARC

DMARCの設定

# Child DNSのゾーンファイルにTXTレコードを追記
$ sudo cat /etc/bind/db.child.lab.test
$TTL 3600

@       IN SOA ns dnsmaster (
                2026101301 ; Serial
                3600       ; Refresh
                900        ; Retry
                4800     ; Expire
                86400      ; Negative Cache TTL
)

        IN NS   ns

ns      IN A    192.168.56.20
www     IN A    192.168.56.100
mail    IN A    192.168.56.50
@       IN MX   10 mail.child.lab.test.
@       IN TXT  "v=spf1 ip4:192.168.56.50 ip4:192.168.56.40 -all" # Serialを変更
_dmarc  IN TXT  "v=DMARC1; p=none"                # DMARCのTXTレコードを追記
mail2026._domainkey     IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+gujScccmTP7w433GOLV0ddx7/jHv/WVMtn/6JxyVhcFQpCkr6oi13zR6yQPcgoDxvInlk1FkVcB2OfCO/18zxeSLLpoH0FqVGemSInM5lkc/ZLPEIbdgTqOki3i/0ZcYKo7KVE173FyA109a3SuJoEPHn6RFWsAXFwAvzF5FUTBMyCEXwHBCRdyCr8OMbSwqH6zS6Q4Kyizx"
          "q9GGqweQwWYmruZcXArwEaFI3iYDZF5T9rfbfwRoAe6tAzdRgjIl7ntFa9PrKauSfUp8hCiKFg+rSErvNec5wBx8Sq1MyKJ77EQ8DkqtpE1/P+FWc72oD/IWkO+xgA/V9tkDHKnwIDAQAB" )  ; ----- DKIM key mail2026 for child.lab.test

# 構文チェック
$ sudo named-checkzone child.lab.test /etc/bind/db.child.lab.test
zone child.lab.test/IN: loaded serial 2026101301
OK

# BINDを再読み込み
$ sudo rndc reload child.lab.test
zone reload queued

# 設定が反映されているか確認
$ dig @192.168.56.30 _dmarc.child.lab.test TXT +short
"v=DMARC1; p=none"

# システムのパッケージリストを更新
$ sudo apt update

# opendmarcのインストール
$ sudo apt install opendmarc
opendmarc_install  # インストール中にConfiguration opendmarcという画面が表示された場合は、Noを選択
$ sudo systemctl status opendmarc
● opendmarc.service - OpenDMARC Milter
     Loaded: loaded (/usr/lib/systemd/system/opendmarc.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-10-13 01:35:28 UTC; 11min ago

# DMARCの設定確認
$ sudo grep -Ev '^\s*(#|$)' /etc/opendmarc.conf
PidFile /run/opendmarc/opendmarc.pid
PublicSuffixList /usr/share/publicsuffix/public_suffix_list.dat
Socket local:/run/opendmarc/opendmarc.sock
Syslog true
UMask 0002
UserID opendmarc

# OpenDMARCのソケットを確認
$ sudo ls -l /run/opendmarc/opendmarc.sock
srwxrwxr-x 1 opendmarc opendmarc 0 Oct 13 01:35 /run/opendmarc/opendmarc.sock

# Postfixにアクセス権限を付与
$ id postfix
uid=104(postfix) gid=108(postfix) groups=108(postfix),113(opendkim)
$ sudo usermod -aG opendmarc postfix
$ id postfix
uid=104(postfix) gid=108(postfix) groups=108(postfix),113(opendkim),114(opendmarc)

# PostfixのMilter設定を確認
$ postconf -n | grep -E '^(smtpd_milters|non_smtpd_milters|milter_)'
milter_default_action = accept
milter_protocol = 6
non_smtpd_milters = $smtpd_milters
smtpd_milters = unix:/run/opendkim/opendkim.sock

# OpenDMARCをPostfixに追加する
$ sudo postconf -e 'smtpd_milters = unix:/run/opendkim/opendkim.sock, unix:/run/opendmarc/opendmarc.sock'
$ postconf smtpd_milters
smtpd_milters = unix:/run/opendkim/opendkim.sock, unix:/run/opendmarc/opendmarc.sock

# SPF認証の設定追加
# SPFSelfValidate trueを末尾に追記
$ sudo vim /etc/opendmarc.conf
SPFSelfValidate true

# 設定を反映
$ sudo systemctl restart opendmarc
$ sudo systemctl restart postfix
$ systemctl is-active opendmarc postfix
active
active

DMARCの検証

# Clientからメールを送信
$ openssl s_client -connect mail.child.lab.test:25 \
  -starttls smtp \
  -servername mail.child.lab.test \
  -CAfile ~/mail-server.crt \
  -verify_hostname mail.child.lab.test \
  -verify_return_error -crlf -quiet
Connecting to 192.168.56.50
(以下省略)

# メールサーバーで受信メールを確認
# dmarc=passを確認
From sender@child.lab.test  Tue Oct 13 02:09:08 2026
Return-Path: <sender@child.lab.test>
X-Original-To: mailadmin@child.lab.test
Delivered-To: mailadmin@child.lab.test
Authentication-Results: mail.child.lab.test; dmarc=pass (p=none dis=none) header.from=child.lab.test
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=child.lab.test;
        s=mail2026; t=1791857348;
        bh=UH5pfhxH2N0PJp+Qxwe04zP8C0HOnIaxyKHuTHJezRQ=;
        h=From:To:Subject:From;
        b=Vxh0p/nQOggKGNdP0qnKZuyeqAZBG540j5PxQt97MUNr3rYnoRhiafxrE7LBvVbdn
         vohjxAPat9DhLCKXKJMaUKDsWhn/al7qSQQf6k6uNrW2RjAA6XGML8DjaJfm83Ib9M
         OFqoTtk0EykEYNQIgcekzktfTtAOtLY5Dg7AjkFX5l2DIZYatUM4z3TPaaOKPbbgqH
         9JWWwI9UOFQ8A4olnGIoKEmNaal8IpjIRoln6pUs73VAFZnES3Sfg3nmRjzGY8ayjY
         okLCnruNPAs9IAzoROsXO/IYAAZ4VVML9exLy++qjrDoH0OX5VWiZ7az4gWkmfYhmI
         eToD1Km3UKDYQ==
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.168.56.40; helo=client.child.lab.test; envelope-from=sender@child.lab.test; receiver=child.lab.test
Received: from client.child.lab.test (unknown [192.168.56.40])
        by mail.child.lab.test (Postfix) with ESMTPSA id 368E44048B
        for <mailadmin@child.lab.test>; Tue, 13 Oct 2026 02:08:39 +0000 (UTC)
From: sender@child.lab.test
To: mailadmin@child.lab.test
Subject: DMARC Pass Test

This is a DMARC test.

# dmarc=fail の確認
# Clientからメールを送信
# MAIL FROM:<sender@child.lab.test>、From: sender@example.com で送信元を不一致にする
$ openssl s_client -connect mail.child.lab.test:25 \
  -starttls smtp \
  -servername mail.child.lab.test \
  -CAfile ~/mail-server.crt \
  -verify_hostname mail.child.lab.test \
  -verify_return_error -crlf -quiet
Connecting to 192.168.56.50
(以下省略)

# メールサーバーで受信メールを確認
# dmarc=fail、Received-SPF: Pass、DKIM-Signature:なし
From sender@child.lab.test  Tue Oct 13 02:15:27 2026
Return-Path: <sender@child.lab.test>
X-Original-To: mailadmin@child.lab.test
Delivered-To: mailadmin@child.lab.test
Authentication-Results: mail.child.lab.test; dmarc=fail (p=reject dis=none) header.from=example.com
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.168.56.40; helo=client.child.lab.test; envelope-from=sender@child.lab.test; receiver=child.lab.test
Received: from client.child.lab.test (unknown [192.168.56.40])
        by mail.child.lab.test (Postfix) with ESMTPSA id 7DAB04048B
        for <mailadmin@child.lab.test>; Tue, 13 Oct 2026 02:15:04 +0000 (UTC)
From: sender@example.com
To: mailadmin@child.lab.test
Subject: DMARC Fail Test

This is a DMARC fail test.

まとめ

今回の検証では、前回構築したメールサーバーにSMTP AUTHとSTARTTLSを導入し、ユーザー認証と通信の暗号化が正常に行われることを確認した。
また、SPF・DKIM・DMARCを導入し、SPFによる送信元IPアドレスの認証、DKIMによる電子署名の付与、DMARCによる認証結果の評価を確認した。
今回の検証から、SMTP AUTHはメール送信時のユーザー認証、STARTTLSは通信経路の暗号化、SPF・DKIM・DMARCは送信ドメインの認証やメールの改ざん検知などそれぞれ異なる役割を持つことが分かった。
メールの安全性を高めるためには、これらの技術を組み合わせて利用することが重要だと理解できた。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

勉強中のセキュリティエンジニアです。
初心者の目線で学んだことをまとめています。

コメント

コメントする

CAPTCHA


目次