メモ Forti Tokenの代替はあるのか?(不可能では無いけどメリットが少ない)

FortinetのVPNを使う際に、Forti Tokenを使用した認証を要求されることがある。

Androidの場合 FortiToken Mobileのインストールを要求される。

しかし、Google AuthenticatorMicrosoft Authenticator があるところにさらに増やしたくないなぁ・・・ということで、代替できるのか確認

まず、Fortinet VPN管理者から「FortiToken Mobileアクティベーションコード」として16文字の文字列と、それをQRコードサイトで渡してQRコードにした画像が送られてきた

念のためそのQRコードをGoogle Authenticator, Microsoft Authenticatorの両方で読ませてみたけど、認識しなかった。

では、どうすればいいのか?

確認すると、redditの「Is it possible to use google authenticator for forticlient VPN SSL instead of fortitoken?」を発見

githubの「Fortinet Token Registration」とyoutubeの「How to extract the TOTP code from Fortinet and use Google Authenticator instead」を使うとコンバートできるとある

youtubeの方は概要欄に https://github.com/Aeroverra/openftm が掲載されていたが、https://github.com/AndreySV/openftm の方が元のようだ。

といっても元祖は https://github.com/ptrcnull/openftm で、それをいくつか改良したもののようだ

ただ、https://github.com/AndreySV/openftmhttps://github.com/ss23/fortitoken-mobile-registration の双方を確認したが、両方とも実行するクライアント固有のID、Android端末の場合はSSAIDが必要となる模様。(https://github.com/ss23/fortitoken-mobile-registration の方では mobile-id 表記)

このSSAIDは、Forti Token Mobileアプリをインストールしないと作成されないようで、どちらにしても、Forti Token Mobileアプリ自体のインストールは必要そうである。

また、openftmの方はForti Token Mobileアプリが作成したSQLite3データベースファイルよりseed値を取得してるようである。

ということで、どちらにせよ、 Forti Token Mobileアプリ をインストールする必要があるようなので、Google Authenticator / Microsoft Authenticatorで代替するメリットがあまりないな・・・ということで、おとなしくForti Token Mobileアプリをインストールしました。

doveadmとjqコマンドを組み合わせて使用率の値だけを取り出す

doveadmとjqコマンドを組み合わせて既定パーセントを超えているユーザを一覧化する、というスクリプトを考えた

前提として、LDAP連携時、1000件を超えるアドレスがある場合、doveadm quota get -A での一括取得ができない、という制約がある。

このため、ldapserchコマンドを使ってユーザ一覧を出力した上で個別に処理を行っていく必要がある。

doveadm quota get -u ユーザ名の通常出力は以下となる

[root@mail ~]# doveadm  quota get -u testuser2
Quota name Type    Value Limit                                                             %
User quota STORAGE     6    50                                                            12
User quota MESSAGE     8     -                                                             0
[root@mail ~]#

doveadmコマンドには-fオプションがあってフォーマットを変えられ、例えばdoveadm -f tab quota get -u ユーザ名を実行するとタブ区切りで処理するためタブが1個だけで表示される

[root@mail ~]# doveadm -f tab quota get -u testuser2
Quota name      Type    Value   Limit   %
User quota      STORAGE 6       50      12
User quota      MESSAGE 8       -       0
[root@mail ~]#

最近のLinuxならjqコマンドがインストールされているのでJSONで形式で出力することにする

[root@mail ~]# doveadm -f json quota get -u testuser2
[{"root":"User quota","type":"STORAGE","value":"6","limit":"50","percent":"12"},{"root":"User quota","type":"MESSAGE","value":"8","limit":"-","percent":"0"}][root@mail ~]#

これを単純にjqコマンドに通す

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r
[
  {
    "root": "User quota",
    "type": "STORAGE",
    "value": "6",
    "limit": "50",
    "percent": "12"
  },
  {
    "root": "User quota",
    "type": "MESSAGE",
    "value": "8",
    "limit": "-",
    "percent": "0"
  }
]
[root@mail ~]#

今回は 容量のみ見るので「STORAGE」に関してだけ取得したい。この場合は「.[]」で1段階掘り下げた上で「|」でその下に対する処理を行い、「select」で条件にあうものを選択する、という処理を行う

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '.[] | select(.type =="STORAGE") '
{
  "root": "User quota",
  "type": "STORAGE",
  "value": "6",
  "limit": "50",
  "percent": "12"
}
[root@mail ~]#

selectは複数つなげられる、というのでpercentについても追加するも、90以上なら表示のところ、12なのに表示されている

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '.[] | select(.type =="STORAGE" and .percent>90 ) '
{
  "root": "User quota",
  "type": "STORAGE",
  "value": "6",
  "limit": "50",
  "percent": "12"
}
[root@mail ~]#

じゃあ、percentが12なら表示に変更してみるが、何も表示されない。

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '.[] | select( .percent == 12 ) '
[root@mail ~]#

文字列問題か?ということで、数値を「””」でくくってみると表示される

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '.[] | select( .percent == "12" ) '
{
  "root": "User quota",
  "type": "STORAGE",
  "value": "6",
  "limit": "50",
  "percent": "12"
}
[root@mail ~]#

jqコマンド処理内で、文字列として認識されているものを数値として認識させるのは「tonumber」を通す

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '.[] | select(.type =="STORAGE" and (.percent|tonumber) > 90 ) '
[root@mail ~]#

10より上なら表示に変更

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '.[] | select(.type =="STORAGE" and (.percent|tonumber) > 10 ) '
{
  "root": "User quota",
  "type": "STORAGE",
  "value": "6",
  "limit": "50",
  "percent": "12"
}
[root@mail ~]# 

で、percentの数値だけを出力させるには以下となる

[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '(.[] | select(.type =="STORAGE" and (.percent|tonumber) > 10 ) ).percent'
12
[root@mail ~]# doveadm -f json quota get -u testuser2 | jq -r '(.[] | select(.type =="STORAGE" and (.percent|tonumber) > 90 ) ).percent'
[root@mail ~]#

これを環境変数で実行できるように修正を試みるがエラーとなる

[root@mail ~]# limitpercent=10
[root@mail ~]# username=testuser2
[root@mail ~]# doveadm -f json quota get -u $username | jq -r '(.[] | select(.type =="STORAGE" and (.percent|tonumber) > $limitpercent ) ).percent'
jq: error: $limitpercent is not defined at <top-level>, line 1:
(.[] | select(.type =="STORAGE" and (.percent|tonumber) > $limitpercent ) ).percent
jq: 1 compile error
[root@mail ~]#

jqコマンドの–argオプションを使って jqコマンド内部用の$limitpercentを設定する必要があった

[root@mail ~]# doveadm -f json quota get -u $username | jq --arg limitpercent 10 -r '(.[] | select(.type =="STORAGE" and (.percent|tonumber) > $limitper
cent ) ).percent'
[root@mail ~]#

今回も文字列数値問題があるようなのでtonumberを追加

[root@mail ~]# doveadm -f json quota get -u $username | jq --arg limitpercent $limitpercent -r '(.[] | select(.type =="STORAGE" and (.percent|tonumber) > ($limitpercent|tonumber) ) ).percent'
12
[root@mail ~]#

これで、使用率の値だけの取り出しが出来た。

samba 4.23.3 で立てたActive Directoryサーバの機能レベルが2008R2から動かせない件を修正する

ESXi8 Free環境上に Active Directoryサーバを立てるか、と、AlmaLinux 9 で samba 4.23.3 をソースからコンパイルして構築した

# /usr/local/samba/bin/samba-tool domain provision --use-rfc2307 --interactive
Realm [ADSAMPLE.LOCAL]:
Domain [ADSAMPLE]:
Server Role (dc, member, standalone) [dc]:
DNS backend (SAMBA_INTERNAL, BIND9_FLATFILE, BIND9_DLZ, NONE) [SAMBA_INTERNAL]:
DNS forwarder IP address (write 'none' to disable forwarding) [8.8.8.8]:  8.8.8.8
Administrator password:
Retype password:
INFO 2025-11-10 14:24:37,370 pid:1551 /usr/local/samba/lib64/python3.9/site-packages/samba/provision/__init__.py #2112: Looking up IPv4 addresses
<略>
INFO 2025-11-10 14:24:49,826 pid:1551 /usr/local/samba/lib64/python3.9/site-packages/samba/provision/__init__.py #501: DOMAIN SID:            S-1-5-21-1830428519-1651848948-1698044471
#

これで起動したActive Directoryサーバのフォレストレベル / ドメインレベル は下記の様にWindows 2008 R2 となっていた。

# samba-tool domain level show
Domain and forest function level for domain 'DC=adsample,DC=local'

Forest function level: (Windows) 2008 R2
Domain function level: (Windows) 2008 R2
Lowest function level of a DC: (Windows) 2008 R2
#

これをアップグレードしようと samba-tool domain level raiseコマンドを実行してみてもエラーとなる。

# samba-tool domain level raise --forest-level=2012_R2
ERROR: Forest function level can't be higher than the domain function level(s). Please raise it/them first!
# samba-tool domain level raise --domain-level=2012_R2
ERROR: Domain function level can't be higher than the lowest function level of a DC!
#

これはデフォルトのsamba設定で”ad dc functional level”が2008R2までとなっているからそういうことになっているのだという(参考:Samba domain controller: raising (all kinds of) level)

testparamコマンドを実行して現在の設定値を確認する

# /usr/local/samba/bin/testparm -s --section-name=global --parameter-name="ad dc functional level"
Load smb config files from /usr/local/samba/etc/smb.conf
Loaded services file OK.
Weak crypto is allowed by GnuTLS (e.g. NTLM as a compatibility fallback)

2008_R2
#

現状の /usr/local/samba/etc/smb.conf に記載はないが、 samba設定としては 2008_R2 として認識されている、ということを確認出来た

この結果を受けて/usr/local/samba/etc/smb.conf のglobalセクションに「ad dc functional level = 2016」という記述を追加する

# cat /usr/local/samba/etc/smb.conf
# Global parameters
[global]
        dns forwarder = 8.8.8.8
        netbios name = ADSERVER
        realm = ADSAMPLE.LOCAL
        server role = active directory domain controller
        workgroup = ADSAMPLE
        idmap_ldb:use rfc2307 = yes
        ad dc functional level = 2016

[sysvol]
        path = /usr/local/samba/var/locks/sysvol
        read only = No

[netlogon]
        path = /usr/local/samba/var/locks/sysvol/adsample.local/scripts
        read only = No
#

testparamで記述が反映されているかを確認

# /usr/local/samba/bin/testparm -s --section-name=global --parameter-name="ad dc functional level"
Load smb config files from /usr/local/samba/etc/smb.conf
Loaded services file OK.
Weak crypto is allowed by GnuTLS (e.g. NTLM as a compatibility fallback)

2016
#

sambaを再起動して、機能レベルがどうなったのかを確認

# systemctl restart samba-ad-dc
# samba-tool domain level show
Domain and forest function level for domain 'DC=adsample,DC=local'

Forest function level: (Windows) 2008 R2
Domain function level: (Windows) 2008 R2
Lowest function level of a DC: (Windows) 2016
#

Lowest function level of a DC が変更されたので、上2つも変更できるようになった

まずはドメインの機能レベルを変更

# samba-tool domain level raise --domain-level=2012_R2
Domain function level changed!
All changes applied successfully!
# samba-tool domain level show
Domain and forest function level for domain 'DC=adsample,DC=local'

Forest function level: (Windows) 2008 R2
Domain function level: (Windows) 2012 R2
Lowest function level of a DC: (Windows) 2016
#

続いてフォレストの機能レベルを変更

# samba-tool domain level raise --forest-level=2012_R2
Forest function level changed!
All changes applied successfully!
# samba-tool domain level show
Domain and forest function level for domain 'DC=adsample,DC=local'

Forest function level: (Windows) 2012 R2
Domain function level: (Windows) 2012 R2
Lowest function level of a DC: (Windows) 2016
#

これで問題なくなった。

OCI上でローカルユーザベースのメールサーバ構築

postfix/dovecotを使ったIMAPメールサーバをOracle Linux 9.6上でOracle Cloud上のFree Tierで構築してみた

2025/10/30時点の状況としては、以下の問題が出て常用には難しい状態で、限定された用途にしか使えない、という感じとなった。

・OCIのFree TierではIPv4/IPv6アドレスに対する逆引き(PTR)が設定できないため gmailにメールが拒否される
・OCI上の仮想マシンから、外部のIPv4アドレスのポート25に対して通信が通らない。IPv6アドレスのポート25なら通る。(OCIの仕様)

準備1: 一般的な前準備

準備1-1: 日本時間にする

日本に住んでいる場合、日本時間表記の方が使いやすいので、OSも日本時間表示に設定する。

$ sudo timedatectl set-timezone Japan
$ 

手順1-2: swap追加

EPELレポジトリを追加した場合、メモリ1GB構成の場合、swapは5GB程度ないとdnfコマンドが正常に動作しないので、swapを増量する

/var/oled パーテーションに ファイルスワップを作成

$ sudo fallocate -l 4G /var/oled/swapfile
$ ls -l /var/oled/swapfile 
-rw-r--r--. 1 root root 4294967296 Sep  9 13:35 /var/oled/swapfile
$ sudo chmod 600 /var/oled/swapfile 
$ ls -l /var/oled/swapfile 
-rw-------. 1 root root 4294967296 Sep  9 13:35 /var/oled/swapfile
$ sudo mkswap /var/oled/swapfile 
Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
no label, UUID=bdd4f7a6-1dcc-43c8-bb2d-8f42ac2faf3f
$ 

作成したファイルをスワップとして登録

$ sudo swapon /var/oled/swapfile 
$ swapon --show
NAME               TYPE SIZE   USED PRIO
/.swapfile         file 951M 161.6M   -2
/var/oled/swapfile file   4G   8.2M   -3
$ cat /proc/swaps 
Filename                                Type            Size            Used            Priority
/.swapfile                              file            973820          165524          -2
/var/oled/swapfile                      file            4194300         8412            -3
$ 

/etc/fstab にスワップファイルの記述「/var/oled/swapfile none swap sw 0 0」を追加

$ sudo vi /etc/fstab
$ cat /etc/fstab 
#
# /etc/fstab
# Created by anaconda on Thu Jun 12 01:18:32 2025
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/ocivolume-root /                       xfs     defaults        0 0
UUID=dd88872e-0527-4193-8282-b8281f1ae6fd /boot                   xfs     defaults        0 0
UUID=AE3C-806E          /boot/efi               vfat    defaults,uid=0,gid=0,umask=077,shortname=winnt 0 2
/dev/mapper/ocivolume-oled /var/oled               xfs     defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults,nodev,nosuid,noexec      0 0
######################################
## ORACLE CLOUD INFRASTRUCTURE CUSTOMERS
##
## If you are adding an iSCSI remote block volume to this file you MUST
## include the '_netdev' mount option or your instance will become
## unavailable after the next reboot.
## SCSI device names are not stable across reboots; please use the device UUID instead of /dev path.
##
## Example:
## UUID="94c5aade-8bb1-4d55-ad0c-388bb8aa716a"   /data1    xfs       defaults,noatime,_netdev      0      2
##
## More information:
## https://docs.us-phoenix-1.oraclecloud.com/Content/Block/Tasks/connectingtoavolume.htm
/.swapfile      none    swap    sw      0       0
/var/oled/swapfile      none    swap    sw      0       0
$

準備2-3: パッケージを最新へアップデート

現時点での最新へアップデートする

$ sudo dnf update -y
<略>
$ sudo reboot

手順1-4: 日本語Locale対応

ja_JP.UTF-8など日本語Localeで設定した際、「Failed to set locale, defaulting to C.UTF-8」というメッセージが出力される場合があります。

その場合は日本語Localeを追加インストールします。

$ sudo dnf install langpacks-ja
<略>
$

手順1-5: kdump無効化

どうせ使わないのでkdumpを無効化

$ sudo systemctl disable kdump.service
Removed '/etc/systemd/system/multi-user.target.wants/kdump.service'.
$

手順2: EPELレポジトリの追加

EPELレポジトリを登録

$ sudo dnf config-manager --set-enabled ol10_u0_developer_EPEL
$  dnf repolist --all
repo id                                                                       repo name                                                                                                       status
ol9_MODRHCK                                                                   Latest RHCK with fixes from Oracle for Oracle Linux 9 (x86_64)                                                  disabled
ol9_RDMA                                                                      Oracle Linux 9 (x86_64) RDMA                                                                                    disabled
ol9_UEKR7                                                                     Oracle Linux 9 UEK Release 7 (x86_64)                                                                           disabled
ol9_UEKR8                                                                     Oracle Linux 9 UEK Release 8 (x86_64)                                                                           enabled
ol9_addons                                                                    Oracle Linux 9 Addons (x86_64)                                                                                  enabled
ol9_appstream                                                                 Oracle Linux 9 Application Stream Packages (x86_64)                                                             enabled
ol9_baseos_latest                                                             Oracle Linux 9 BaseOS Latest (x86_64)                                                                           enabled
ol9_codeready_builder                                                         Oracle Linux 9 CodeReady Builder (x86_64) - (Unsupported)                                                       disabled
ol9_developer                                                                 Oracle Linux 9 Development Packages (x86_64)                                                                    disabled
ol9_developer_EPEL                                                            Oracle Linux 9 EPEL Packages for Development (x86_64)                                                           enabled
ol9_developer_UEKR7                                                           Developer Preview of UEK Release 7 (x86_64)                                                                     disabled
ol9_developer_kvm_utils                                                       Oracle Linux 9 KVM Utilities for Development and test (x86_64)                                                  disabled
ol9_distro_builder                                                            Oracle Linux 9 Distro Builder (x86_64) - (Unsupported)                                                          disabled
ol9_ksplice                                                                   Ksplice for Oracle Linux 9 (x86_64)                                                                             enabled
ol9_kvm_utils                                                                 Oracle Linux 9 KVM Utilities (x86_64)                                                                           disabled
ol9_oci_included                                                              Oracle Linux 9 OCI Included Packages (x86_64)                                                                   enabled
ol9_u0_baseos_base                                                            Oracle Linux 9 BaseOS GA (x86_64)                                                                               disabled
ol9_u1_baseos_base                                                            Oracle Linux 9.1 BaseOS (x86_64)                                                                                disabled
ol9_u2_baseos_base                                                            Oracle Linux 9.2 BaseOS (x86_64)                                                                                disabled
ol9_u3_baseos_base                                                            Oracle Linux 9.3 BaseOS (x86_64)                                                                                disabled
ol9_u3_security_validation                                                    Oracle Linux 9 Update 3 (x86_64) Security Validations                                                           disabled
ol9_u4_baseos_base                                                            Oracle Linux 9.4 BaseOS (x86_64)                                                                                disabled
ol9_u5_baseos_base                                                            Oracle Linux 9.5 BaseOS (x86_64)                                                                                disabled
ol9_u6_baseos_base                                                            Oracle Linux 9.6 BaseOS (x86_64)                                                                                disabled
ol9_x86_64_userspace_ksplice                                                  Ksplice aware userspace packages for Oracle Linux 9 (x86_64)                                                    disabled
$

手順3: インターネット公開用設定

手順3-1: fail2ban導入

公開サーバは各種のアタックにさらされます。管理用sshポートにもやってきます。

多少なりとも軽減するためにEPELレポジトリ収録のfail2banを使用します。

$ sudo dnf install fail2ban -y
<略>
$

カスタム設定は/etc/fail2ban/jail.local に対して行います。

$ sudo vi /etc/fail2ban/jail.local 
$ cat /etc/fail2ban/jail.local 
[DEFAULT]
# 86400秒=24時間以内に5回不審なアクセスがあったら24時間BAN
bantime  = 86400
findtime  = 86400
maxretry = 5
# 259200秒=3日以内に5回不審なアクセスがあったら3日間BAN
#bantime  = 259200
#findtime  = 259200
#maxretry = 5
# 除外IP
ignoreip = 127.0.0.1 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
[sshd]
enabled = true
banaction = firewallcmd-ipset
$ 

上記設定では24時間BANにしていますが、まぁ、3日BANでもかまわないとは思います。(本当に間違えた場合に困るのでほどほどにしておくとよい)

fail2banをOS起動時に実行する設定と、今すぐfail2banを起動するコマンドを実行します。

$ sudo systemctl enable --now fail2ban
Created symlink '/etc/systemd/system/multi-user.target.wants/fail2ban.service' → '/usr/lib/systemd/system/fail2ban.service'.
$

以降、アタックがあると /var/log/fail2ban.log にログが出ます。

手順3-2: メールサーバ用ポート公開設定

初期設定では dhcpv6-client と ssh が許可されています。

$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
$

とりあえずは smtp port 25, smtp-submission 587, imap 143 を開けます

[opc@ocimail ~]$ sudo firewall-cmd --permanent --add-service=smtp
success
[opc@ocimail ~]$ sudo firewall-cmd --permanent --add-service=smtp-submission
success
[opc@ocimail ~]$ sudo firewall-cmd --permanent --add-service=imap
success
[opc@ocimail ~]$ sudo firewall-cmd --reload
success
[opc@ocimail ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: dhcpv6-client imap smtp smtp-submission ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[opc@ocimail ~]$ 

手順3-3: SSL更新用ポート

後述するのだが、SSLはLet’s Encryptを使う。

その際に、http ポート80と、https ポート 443が必要となるため、設定する

[opc@ocimail ~]$ sudo firewall-cmd --permanent --add-service=http
success
[opc@ocimail ~]$ sudo firewall-cmd --permanent --add-service=https
success
[opc@ocimail ~]$ sudo firewall-cmd --reload
success
[opc@ocimail ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: dhcpv6-client http https imap smtp smtp-submission ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
[opc@ocimail ~]$ 

手順4: ソフトウェアインストール

postfixとdovecotをインストールします。

[opc@ocimail ~]$ sudo dnf install postfix dovecot -y
Last metadata expiration check: 2:15:42 ago on Wed 29 Oct 2025 03:42:39 AM GMT.
Dependencies resolved.
======================================================================================================================================================================================================
 Package                                     Architecture                         Version                                                           Repository                                   Size
======================================================================================================================================================================================================
Installing:
 dovecot                                     x86_64                               1:2.3.16-15.el9                                                   ol9_appstream                               5.2 M
 postfix                                     x86_64                               2:3.5.25-1.el9                                                    ol9_appstream                               1.7 M
Installing dependencies:
 clucene-core                                x86_64                               2.3.3.4-42.20130812.e8e3d20git.el9                                ol9_appstream                               594 k
 libexttextcat                               x86_64                               3.4.5-11.el9                                                      ol9_appstream                               382 k

Transaction Summary
======================================================================================================================================================================================================
Install  4 Packages

Total download size: 7.8 M
Installed size: 24 M
Downloading Packages:
(1/4): libexttextcat-3.4.5-11.el9.x86_64.rpm                                                                                                                          1.9 MB/s | 382 kB     00:00    
(2/4): clucene-core-2.3.3.4-42.20130812.e8e3d20git.el9.x86_64.rpm                                                                                                     1.8 MB/s | 594 kB     00:00    
(3/4): dovecot-2.3.16-15.el9.x86_64.rpm                                                                                                                                12 MB/s | 5.2 MB     00:00    
(4/4): postfix-3.5.25-1.el9.x86_64.rpm                                                                                                                                6.0 MB/s | 1.7 MB     00:00    
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                  16 MB/s | 7.8 MB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                              1/1 
  Installing       : libexttextcat-3.4.5-11.el9.x86_64                                                                                                                                            1/4 
  Installing       : clucene-core-2.3.3.4-42.20130812.e8e3d20git.el9.x86_64                                                                                                                       2/4 
  Running scriptlet: dovecot-1:2.3.16-15.el9.x86_64                                                                                                                                               3/4 
  Installing       : dovecot-1:2.3.16-15.el9.x86_64                                                                                                                                               3/4 
  Running scriptlet: dovecot-1:2.3.16-15.el9.x86_64                                                                                                                                               3/4 
  Running scriptlet: postfix-2:3.5.25-1.el9.x86_64                                                                                                                                                4/4 
  Installing       : postfix-2:3.5.25-1.el9.x86_64                                                                                                                                                4/4 
  Running scriptlet: postfix-2:3.5.25-1.el9.x86_64                                                                                                                                                4/4 
  Running scriptlet: dovecot-1:2.3.16-15.el9.x86_64                                                                                                                                               4/4 
  Running scriptlet: postfix-2:3.5.25-1.el9.x86_64                                                                                                                                                4/4 
  Verifying        : clucene-core-2.3.3.4-42.20130812.e8e3d20git.el9.x86_64                                                                                                                       1/4 
  Verifying        : dovecot-1:2.3.16-15.el9.x86_64                                                                                                                                               2/4 
  Verifying        : libexttextcat-3.4.5-11.el9.x86_64                                                                                                                                            3/4 
  Verifying        : postfix-2:3.5.25-1.el9.x86_64                                                                                                                                                4/4 

Installed:
  clucene-core-2.3.3.4-42.20130812.e8e3d20git.el9.x86_64            dovecot-1:2.3.16-15.el9.x86_64            libexttextcat-3.4.5-11.el9.x86_64            postfix-2:3.5.25-1.el9.x86_64           

Complete!
[opc@ocimail ~]$ 

手順5: SSL証明書関連

手順5-1: dhパラメータファイルの作成

diffie-hellman パラメータファイル を /etc/dovecot/conf.d/10-ssl.conf にあるパス /etc/dovecot/dh.pem に作成。なお、30分以上かかる。

[opc@ocimail ~]$ sudo openssl dhparam -out /etc/dovecot/dh.pem 4096
Generating DH parameters, 4096 bit long safe prime
..............................................................................................................+......................................+................................................
<略>

手順5-2: dehydratedによるLet’s Encrypt導入

Let’s EncryptによるSSL証明書導入はcertbotを使うのが一般的ではあるのだが、python環境とあわせてパッケージサイズが大きいので、コンパクトでEPELにも収録されているdehydratedを使用する。

[opc@ocimail ~]$ sudo dnf install dehydrated -y
Last metadata expiration check: 3:29:19 ago on Wed 29 Oct 2025 03:42:39 AM GMT.
Dependencies resolved.
======================================================================================================================================================================================================
 Package                                       Architecture                              Version                                          Repository                                             Size
======================================================================================================================================================================================================
Installing:
 dehydrated                                    noarch                                    0.7.1-6.el9                                      ol9_developer_EPEL                                    154 k
Installing dependencies:
 s-nail                                        x86_64                                    14.9.22-6.el9                                    ol9_appstream                                         626 k

Transaction Summary
======================================================================================================================================================================================================
Install  2 Packages

Total download size: 780 k
Installed size: 1.4 M
<略>
Installed:
  dehydrated-0.7.1-6.el9.noarch                                                                      s-nail-14.9.22-6.el9.x86_64                                                                     

Complete!
[opc@ocimail ~]$

dehydratedによるSSL証明書取得処理にはhttp port80アクセスと /var/www/dehydrated が使用されるためhttpdのインストールとディレクトリを作成します。

[opc@ocimail ~]$ sudo dnf install httpd -y
Last metadata expiration check: 3:31:07 ago on Wed 29 Oct 2025 03:42:39 AM GMT.
Dependencies resolved.
======================================================================================================================================================================================================
 Package                                           Architecture                          Version                                               Repository                                        Size
======================================================================================================================================================================================================
Installing:
 httpd                                             x86_64                                2.4.62-4.0.1.el9_6.4                                  ol9_appstream                                     64 k
Installing dependencies:
 apr                                               x86_64                                1.7.0-12.el9_3                                        ol9_appstream                                    131 k
 apr-util                                          x86_64                                1.6.1-23.el9                                          ol9_appstream                                     99 k
 apr-util-bdb                                      x86_64                                1.6.1-23.el9                                          ol9_appstream                                     12 k
 httpd-core                                        x86_64                                2.4.62-4.0.1.el9_6.4                                  ol9_appstream                                    1.8 M
 httpd-filesystem                                  noarch                                2.4.62-4.0.1.el9_6.4                                  ol9_appstream                                     11 k
 httpd-tools                                       x86_64                                2.4.62-4.0.1.el9_6.4                                  ol9_appstream                                     93 k
 oracle-logos-httpd                                noarch                                90.4-1.0.1.el9                                        ol9_baseos_latest                                 37 k
Installing weak dependencies:
 apr-util-openssl                                  x86_64                                1.6.1-23.el9                                          ol9_appstream                                     14 k
 mod_http2                                         x86_64                                2.0.26-4.el9_6.1                                      ol9_appstream                                    171 k
 mod_lua                                           x86_64                                2.4.62-4.0.1.el9_6.4                                  ol9_appstream                                     58 k

Transaction Summary
======================================================================================================================================================================================================
Install  11 Packages

Total download size: 2.5 M
Installed size: 6.1 M
Downloading Packages:
<略>
Installed:
  apr-1.7.0-12.el9_3.x86_64                  apr-util-1.6.1-23.el9.x86_64                    apr-util-bdb-1.6.1-23.el9.x86_64                      apr-util-openssl-1.6.1-23.el9.x86_64            
  httpd-2.4.62-4.0.1.el9_6.4.x86_64          httpd-core-2.4.62-4.0.1.el9_6.4.x86_64          httpd-filesystem-2.4.62-4.0.1.el9_6.4.noarch          httpd-tools-2.4.62-4.0.1.el9_6.4.x86_64         
  mod_http2-2.0.26-4.el9_6.1.x86_64          mod_lua-2.4.62-4.0.1.el9_6.4.x86_64             oracle-logos-httpd-90.4-1.0.1.el9.noarch             

Complete!
[opc@ocimail ~]$ sudo mkdir /var/www/dehydrated
[opc@ocimail ~]$ 

http://~/.well-known/acme-challenge でアクセスした時に上記ディレクトリが開くようApacheの設定を /etc/httpd/conf.d/dehydrated.conf として作成します。(sudo vi /etc/httpd/conf.d/dehydrated.conf )

[opc@ocimail ~]$ sudo vi /etc/httpd/conf.d/dehydrated.conf 
[opc@ocimail ~]$ cat /etc/httpd/conf.d/dehydrated.conf 
Alias /.well-known/acme-challenge /var/www/dehydrated
<Directory /var/www/dehydrated/>
</Directory>
[opc@ocimail ~]$ 

httpdを起動します

[opc@ocimail ~]$ sudo systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[opc@ocimail ~]$ 

SSL証明書を発行するホスト名を /etc/dehydrated/domains.txt に記載する。(sudo vi /etc/dehydrated/domains.txt)

$ sudo vi /etc/dehydrated/domains.txt
$ sudo cat /etc/dehydrated/domains.txt
ホスト1名.ドメイン名 ホスト2名.ドメイン名
$

登録操作を開始します。

[opc@ocimail ~]$ sudo dehydrated --register
# INFO: Using main config file /etc/dehydrated/config
# INFO: Using additional config file /etc/dehydrated/conf.d/local.sh

To use dehydrated with this certificate authority you have to agree to their terms of service which you can find here: https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf

To accept these terms of service run "/bin/dehydrated --register --accept-terms".
[opc@ocimail ~]$ sudo dehydrated --register --accept-terms
# INFO: Using main config file /etc/dehydrated/config
# INFO: Using additional config file /etc/dehydrated/conf.d/local.sh
+ Generating account key...
+ Registering account key with ACME server...
+ Fetching account URL...
+ Done!
[opc@ocimail ~]$ 

初回のSSL証明書発行処理を実行します。

[opc@ocimail ~]$ sudo dehydrated --cron
# INFO: Using main config file /etc/dehydrated/config
# INFO: Using additional config file /etc/dehydrated/conf.d/local.sh
Processing ocimail.websa.jp
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting new certificate order from CA...
 + Received 1 authorizations URLs from the CA
 + Handling authorization for ホスト名
 + 1 pending challenge(s)
 + Deploying challenge tokens...
 + Responding to challenge for ocimail.websa.jp authorization...
 + Challenge is valid!
 + Cleaning challenge tokens...
 + Requesting certificate...
Warning: Will read cert request from stdin since no -in option is given
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!
 + Running automatic cleanup
Moving unused file to archive directory: ホスト名/cert-1761722366.csr
Moving unused file to archive directory: ホスト名/cert-1761722366.pem
Moving unused file to archive directory: ホスト名/privkey-1761722366.pem
[opc@ocimail ~]$ 

これで/etc/dehydrated/certs/ホスト名/ にSSL証明書が作成される

[opc@ocimail ~]$ sudo ls -l /etc/dehydrated/certs/ホスト名/
total 20
-rw-------. 1 root root 1655 Oct 29 07:26 cert-1761722787.csr
-rw-------. 1 root root 2134 Oct 29 07:26 cert-1761722787.pem
lrwxrwxrwx. 1 root root   19 Oct 29 07:26 cert.csr -> cert-1761722787.csr
lrwxrwxrwx. 1 root root   19 Oct 29 07:26 cert.pem -> cert-1761722787.pem
-rw-------. 1 root root 1802 Oct 29 07:26 chain-1761722787.pem
lrwxrwxrwx. 1 root root   20 Oct 29 07:26 chain.pem -> chain-1761722787.pem
-rw-------. 1 root root 3936 Oct 29 07:26 fullchain-1761722787.pem
lrwxrwxrwx. 1 root root   24 Oct 29 07:26 fullchain.pem -> fullchain-1761722787.pem
-rw-------. 1 root root 3272 Oct 29 07:26 privkey-1761722787.pem
lrwxrwxrwx. 1 root root   22 Oct 29 07:26 privkey.pem -> privkey-1761722787.pem
[opc@ocimail ~]$ 

dovecot設定

dovecot ssl設定

/etc/dovecot/conf.d/10-ssl.conf にて

「ssl = required」を「ssl = yes」に変更

# SSL/TLS support: yes, no, required. &lt;doc/wiki/SSL.txt>
# disable plain pop3 and imap, allowed are only pop3+TLS, pop3s, imap+TLS and imaps
# plain imap and pop3 are still allowed for local connections
ssl = yes

ssl_certとssl_keyをdehydratedが出力したファイルに置き換え

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert = &lt;/etc/dehydrated/certs/ホスト名/fullchain.pem
ssl_key = &lt;/etc/dehydrated/certs/ホスト名/privkey.pem

dhパラメータのコメントを取る

# SSL DH parameters
# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
# Or migrate from old ssl-parameters.dat file with the command dovecot
# gives on startup when ssl_dh is unset.
ssl_dh = &lt;/etc/dovecot/dh.pem

dovecotのメイン設定ファイル

/etc/dovecot/dovecot.conf に以下の変更

標準だと「imap pop3 lmtp submission」となっているものから、imapとsubmissionとする

# Protocols we want to be serving.
#protocols = imap pop3 lmtp submission
protocols = imap submission

dovecotのメール保存に関するファイル

/etc/dovecot/conf.d/10-mail.conf に以下の変更

maildir形式で各ユーザのホームディレクトリに保存する設定

#   mail_location = maildir:~/Maildir
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# &lt;doc/wiki/MailLocation.txt>
#
mail_location = maildir:~/Maildir

quotaを有効化するため、mail_plugins に「$mail_plugins quota」を追加

# Space separated list of plugins to load for all services. Plugins specific to
# IMAP, LDA, etc. are added to this list in their own .conf files.
mail_plugins = $mail_plugins quota

mailboxのindexを有効にする設定「mailbox_list_index = yes」を入れる

##
## Mailbox handling optimizations
##

# Mailbox list indexes can be used to optimize IMAP STATUS commands. They are
# also required for IMAP NOTIFY extension to be enabled.
mailbox_list_index = yes

IMAPログイン時のパスワード取り扱い設定

IMAPログイン時のパスワードを暗号化して送信する、というのが現代の設定となる。

古い仕様のメールクラインとがいたとすると、平文パスワードを許可する設定を /etc/dovecot/conf.d/10-auth.conf に追加する必要がある。

その場合は下記を「disable_plaintext_auth = no」に変更する

# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
# See also ssl=required setting.
#disable_plaintext_auth = yes

また、下記を「auth_mechanism = plain login」に変更する

# Space separated list of wanted authentication mechanisms:
#   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp
#   gss-spnego
# NOTE: See also disable_plaintext_auth setting.
auth_mechanisms = plain

dovecotのSMTP-auth動作時の設定

/etc/dovecot/conf.d/10-master.conf でコメントアウトされている smtp-authに関する設定を少し修正して設定する

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }

dovecotのIMAP設定

/etc/dovecot/conf.d/20-imap.conf にて mail_plugin として「imap_quota」を追加

protocol imap {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins imap_quota

  # Maximum number of IMAP connections allowed for a user from each IP address.
  # NOTE: The username is compared case-sensitively.
  #mail_max_userip_connections = 10
}

dovecotのメールボックス取り扱い設定

/etc/dovecot/conf.d/15-mailboxes.conf を修正することで、メールソフトによってフォルダ名に微妙な違いがあるのをある程度吸収できる。

##
## Mailbox definitions
##

# Each mailbox is specified in a separate mailbox section. The section name
# specifies the mailbox name. If it has spaces, you can put the name
# "in quotes". These sections can contain the following mailbox settings:
#
# auto:
#   Indicates whether the mailbox with this name is automatically created
#   implicitly when it is first accessed. The user can also be automatically
#   subscribed to the mailbox after creation. The following values are
#   defined for this setting:
# 
#     no        - Never created automatically.
#     create    - Automatically created, but no automatic subscription.
#     subscribe - Automatically created and subscribed.
#  
# special_use:
#   A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the
#   mailbox. There are no validity checks, so you could specify anything
#   you want in here, but it's not a good idea to use flags other than the
#   standard ones specified in the RFC:
#
#     \All       - This (virtual) mailbox presents all messages in the
#                  user's message store.
#     \Archive   - This mailbox is used to archive messages.
#     \Drafts    - This mailbox is used to hold draft messages.
#     \Flagged   - This (virtual) mailbox presents all messages in the
#                  user's message store marked with the IMAP \Flagged flag.
#     \Important - This (virtual) mailbox presents all messages in the
#                  user's message store deemed important to user.
#     \Junk      - This mailbox is where messages deemed to be junk mail
#                  are held.
#     \Sent      - This mailbox is used to hold copies of messages that
#                  have been sent.
#     \Trash     - This mailbox is used to hold messages that have been
#                  deleted.
#
# comment:
#   Defines a default comment or note associated with the mailbox. This
#   value is accessible through the IMAP METADATA mailbox entries
#   "/shared/comment" and "/private/comment". Users with sufficient
#   privileges can override the default value for entries with a custom
#   value.

# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox "下書き" {
    special_use = \Drafts
  }
  mailbox INBOX.Drafts {
    special_use = \Drafts
  }

  mailbox Junk {
    special_use = \Junk
  }
  mailbox "迷惑メール" {
    special_use = \Junk
  }
  mailbox "Junk Email" {
    special_use = \Junk
  }
  mailbox "INBOX.Junk Email" {
    special_use = \Junk
  }

  mailbox Trash {
    special_use = \Trash
  }
  mailbox "削除済みアイテム" {
    special_use = \Trash
  }
  mailbox "Deleted Items" {
    special_use = \Trash
  }
  mailbox "INBOX.Deleted Items" {
    special_use = \Trash
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
  mailbox "送信済みアイテム" {
    special_use = \Sent
  }
  mailbox "Sent Items" {
    special_use = \Sent
  }
  mailbox "INBOX.Sent Items" {
    special_use = \Sent
  }

  # If you have a virtual "All messages" mailbox:
  #mailbox virtual/All {
  #  special_use = \All
  #  comment = All my messages
  #}

  # If you have a virtual "Flagged" mailbox:
  #mailbox virtual/Flagged {
  #  special_use = \Flagged
  #  comment = All my flagged messages
  #}

  # If you have a virtual "Important" mailbox:
  #mailbox virtual/Important {
  #  special_use = \Important
  #  comment = All my important messages
  #}
}

dovecotのquota設定

既存の /etc/dovecot/conf.d/90-quota.conf の最後に下記を追加する

これは100MBで制限する例

mailbox_list_index = yes

# Avoid spending excessive time waiting for the quota calculation to finish
# when mails' vsizes aren't already cached. If this many mails are opened,
# finish the quota calculation on background in indexer-worker process. Mail
# deliveries will be assumed to succeed, and explicit quota lookups will
# return internal error. (v2.2.28+)
protocol !indexer-worker {
  mail_vsize_bg_after_count = 100
}

plugin {
  quota = count:User quota
  quota_rule = *:storage=100M
  #quota_rule2 = Trash:storage=+100M

  # This is required - it uses "virtual sizes" rather than "physical sizes"
  # for quota counting:
  quota_vsizes = yes
}

dovecotのsmtp submission設定

/etc/dovecot/conf.d/20-submission.conf にて設定する

dovecot自体ではメール配送を行わないので、postfix側に引き渡すのだが、同じホスト上にあったとしてもlocalhost指定ではなく、外部から見えるホスト名で指定する。

# Relay server configuration:
#
# The Dovecot SMTP submission service directly proxies the mail transaction
# to the SMTP relay configured here.

# Host name for the relay server (required)
submission_relay_host = ホスト名.ドメン名

postfix側設定

postfix側は /etc/postfix/main.cf へ設定を行う

Oracle Cloud上だとホスト名が内部のみの ホスト名.subnet<数字>.vcn<数字>.oraclevcn.comといったものとなっているので、DNS上のホスト名をmyhostnameで設定する

# INTERNET HOST AND DOMAIN NAMES
# 
# The myhostname parameter specifies the internet hostname of this
# mail system. The default is to use the fully-qualified domain name
# from gethostname(). $myhostname is used as a default value for many
# other configuration parameters.
#
#myhostname = host.domain.tld
#myhostname = virtual.domain.tld
myhostname = ホスト名.ドメイン名

続いてmydomain も 外部で認識させたいドメイン名を入れる

# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
# $mydomain is used as a default value for many other configuration
# parameters.
#
#mydomain = domain.tld
mydomain = ドメイン名

外部に送信するメールの@以降の部分はドメイン名としたいので「myorigin = $mydomain」の方を有効にします。

# SENDING MAIL
# 
# The myorigin parameter specifies the domain that locally-posted
# mail appears to come from. The default is to append $myhostname,
# which is fine for small sites.  If you run a domain with multiple
# machines, you should (1) change this to $mydomain and (2) set up
# a domain-wide alias database that aliases each user to
# user@that.users.mailhost.
#
# For the sake of consistency between sender and recipient addresses,
# myorigin also specifies the default domain name that is appended
# to recipient addresses that have no @domain part.
#
#myorigin = $myhostname
myorigin = $mydomain

外部からpostfixにアクセスする必要があるので「inet_interfaces = all」を有効にします

# The inet_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on.  By default,
# the software claims all active interfaces on the machine. The
# parameter also controls delivery of mail to user@[ip.address].
#
# See also the proxy_interfaces parameter, for network addresses that
# are forwarded to us via a proxy or network address translator.
#
# Note: you need to stop/start Postfix when this parameter changes.
#
inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
#inet_interfaces = localhost

# Enable IPv4, and IPv6 if supported
inet_protocols = all

自サーバで受信するメールドメインの設定は2番目のドメイン宛ても受け取るやつにします

# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
#mydestination = $myhostname, localhost.$mydomain, localhost
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
#       mail.$mydomain, www.$mydomain, ftp.$mydomain

ローカルユーザとしてメールを受け取りたいので、local_recipient_mapsを明示的に有効にします。

# The right-hand side of the lookup tables is conveniently ignored.
# In the left-hand side, specify a bare username, an @domain.tld
# wild-card, or specify a user@domain.tld address.
# 
local_recipient_maps = unix:passwd.byname $alias_maps
#local_recipient_maps = proxy:unix:passwd.byname $alias_maps
#local_recipient_maps =

postfixでメールを送信できるようにする設定

メール送信を許可するネットワークを mynetworks で行う

#mynetworks = 168.100.189.0/28, 127.0.0.0/8
#mynetworks = $config_directory/mynetworks
#mynetworks = hash:/etc/postfix/network_table

また、以下を追加

# With Postfix version before 2.10, use smtpd_recipient_restrictions
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

postfixのssl証明書設定

/etc/postfix/main.cf の最後の方にSSL関連の設定がある

# The full pathname of a file with the Postfix SMTP server RSA certificate
# in PEM format. Intermediate certificates should be included in general,
# the server certificate first, then the issuing CA(s) (bottom-up order).
#
smtpd_tls_cert_file = /etc/dehydrated/certs/ocimail.websa.jp/fullchain.pem
# The full pathname of a file with the Postfix SMTP server RSA private key
# in PEM format. The private key must be accessible without a pass-phrase,
# i.e. it must not be encrypted.
#
smtpd_tls_key_file = /etc/dehydrated/certs/ocimail.websa.jp/privkey.pem

postfix側からdovecotを起動する設定

/etc/postfix/master.cf の最終行に以下を追加

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}

postfixからSASLを使ってdovecot連携する手法は使わない

今回はsmtp submissionはdovecot側で行うので、SASLを使ってdovecotと連携するための下記設定は行わない。

smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
# dovecot sasl configuration
smtpd_sasl_type = dovecot
# Can be an absolute path, or relative to $queue_directory
# Debian/Ubuntu users: Postfix is setup by default to run chrooted, so it is best to leave it as-is below
smtpd_sasl_path = private/auth
# and the common settings to enable SASL:
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous 

トラブル対応

gmail宛てがgmail側で受け取り拒否

gmailに送ったところ、メールがなかなか届かないので/var/log/maillogを確認

Oct 30 10:15:28 ocimail postfix/smtp[5898]: AA57A309E87E: to=&lt;アドレス@gmail.com>, relay=gmail-smtp-in.l.google.com[2404:6800:4008:c15::1b]:25, delay=2.6, delays=0.29/0.19/1.2/0.9, dsn=5.7.1, status=bounced (host gmail-
smtp-in.l.google.com[2404:6800:4008:c15::1b] said: 550-5.7.1 [2603:c023:f:9000:0:7a41:2e84:f27f] Gmail has detected that this 550-5.7.1 message does not meet IPv6 sending guidelines regarding PTR records 550-5.7.1 and auth
entication. For more information, go to 550 5.7.1  https://support.google.com/mail/?p=IPv6AuthError 41be03b00d2f7-b71f4ba78c7si7488417a12.1056 - gsmtp (in reply to end of DATA command))

「Gmail has detected that this 550-5.7.1 message does not meet IPv6 sending guidelines regarding PTR records 550-5.7.1 and authentication. For more information, go to 550 5.7.1 https://support.google.com/mail/?p=IPv6AuthError」という形で拒否されていた。

リンク先はGoogleの「メール送信者のガイドライン」の最後のあたりで下記の様に書かれている

IPv6 認証エラーを修正する
送信元サーバーの PTR レコードで IPv6 が使用されていない場合、IPv6 認証エラーが返される場合があります。メールサービス プロバイダを利用している場合は、プロバイダが IPv6 の PTR レコードを使用していることを確認してください。

IPv6 認証エラーの例を次に示します。
550-5.7.1: Message does not meet IPv6 sending guidelines regarding PTR records and authentication.(メールが PTR レコードと認証に関する IPv6 の送信ガイドラインに準拠していません。)

あと、最初の方に書かれているIPアドレスに対する要件も関係している

インフラストラクチャ設定の要件とガイドライン
IP アドレス
重要: 送信元 IP アドレスは、ポインタ(PTR)レコードで指定されたホスト名の IP アドレスと一致している必要があります。

送信元 SMTP サーバーのパブリック IP アドレスには、対応するホスト名を参照する PTR レコードが必要です。これは、リバース DNS ルックアップと呼ばれます。このホスト名には、送信元サーバーと同じパブリック IP アドレスを参照する A レコード(IPv4 の場合)または AAAA レコード(IPv6 の場合)も必要です。これは、フォワード DNS ルックアップと呼ばれます。
送信元サーバーの IP アドレスとドメインを対応付ける有効なリバース DNS レコードを設定します。Google 管理者ツールボックスの Dig ツールを使用して PTR レコードを確認します。
重要: 送信元 IP アドレスは、ポインタ(PTR)レコードで指定されたホスト名の IP アドレスと一致している必要があります。

つまり、IPv6アドレスのPTRレコードに対してちゃんとホスト名を設定する必要があるようだ。

じゃあ、Oracle Cloudの場合、それを設定できるのか?を確認

Oracle Cloud Infrastructureドキュメント:逆引きDNS (PTR)

クラウドIPアドレスに対してPTRレコードを確立するようにリクエストできます:
1. リクエストをオープンする前の完全修飾ドメイン名をIPに示したA (IPv4)またはAAAA (IPv6)フォワード・レコードを作成します。レコードは、Oracle Cloud Infrastructure DNSサービスまたはサードパーティDNSプロバイダを使用して作成できます。
2. サービス・リクエストをオープンして、次の情報を含めます:
a. PTRに必要なIPアドレスおよび完全修飾ドメイン名(FQDN)。
b. ステップ1で作成したフォワード・レコードのFQDN。

サービス・リクエストの受信後、フォワード(AまたはAAAA)レコード情報は、正常に解決できることが検証され、OracleによってPTRレコードが作成されます。

Web UIでは設定できないのでサービスリクエストから申請する必要がある、とのこと。

サービスリクエストのリンクを飛ぶと「サポート・リクエスト」になったが、読むと・・・

サポート・リクエストは有料アカウントでのみ利用可能です。Always Freeリソースのみを使用する顧客およびFree Tierアカウントを使用する顧客はOracle Supportの対象ではありません。サポートが必要な場合は、サポート・チャットおよびCloud Customer Connectを使用します。

とある、サポートチャットで、対応してもらえるんだろうか?

OCI CLIコマンドのdnsオプションで操作できないのか?

パッケージ oci-utils ではなく、パッケージ python39-oci-cli の方だった

[root@ocimail ~]# dnf install python39-oci-cli
Last metadata expiration check: 2:19:30 ago on Thu 30 Oct 2025 08:47:09 AM JST.
Dependencies resolved.
==============================================================================================================================================================================================================================
 Package                                                        Architecture                               Version                                               Repository                                              Size
==============================================================================================================================================================================================================================
Installing:
 python39-oci-cli                                               noarch                                     3.69.0-1.el9                                          ol9_oci_included                                        46 M
Upgrading:
 python39-oci-sdk                                               x86_64                                     2.162.0-1.el9                                         ol9_oci_included                                        91 M
Installing dependencies:
 python3-arrow                                                  noarch                                     1.2.3-5.el9                                           ol9_developer_EPEL                                     166 k
 python3-importlib-metadata                                     noarch                                     4.12.0-2.el9                                          ol9_oci_included                                        75 k
 python3-jmespath                                               noarch                                     0.10.0-4.el9                                          ol9_oci_included                                        78 k
 python3-prompt-toolkit                                         noarch                                     3.0.38-4.el9                                          ol9_oci_included                                       1.0 M
 python3-terminaltables                                         noarch                                     3.1.10-8.0.1.el9                                      ol9_oci_included                                        60 k
 python3-wcwidth                                                noarch                                     0.2.5-8.el9                                           ol9_appstream                                           65 k
 python3-zipp                                                   noarch                                     3.20.1-2.el9                                          ol9_oci_included                                        48 k

Transaction Summary
==============================================================================================================================================================================================================================
Install  8 Packages
Upgrade  1 Package

Total download size: 138 M
Is this ok [y/N]: y
<略>
Upgraded:
  python39-oci-sdk-2.162.0-1.el9.x86_64                                                                                                                                                                                       
Installed:
  python3-arrow-1.2.3-5.el9.noarch     python3-importlib-metadata-4.12.0-2.el9.noarch   python3-jmespath-0.10.0-4.el9.noarch   python3-prompt-toolkit-3.0.38-4.el9.noarch   python3-terminaltables-3.1.10-8.0.1.el9.noarch  
  python3-wcwidth-0.2.5-8.el9.noarch   python3-zipp-3.20.1-2.el9.noarch                 python39-oci-cli-3.69.0-1.el9.noarch  

Complete!
[root@ocimail ~]# 

いれたものの、DNSの逆引き設定ができそうな感じはなかった・・・

とりあえず、IPv6を使わないようにすればごまかせる、という話が「How I Fixed Gmail Rejecting Emails by Disabling IPv6 in Postfix」にあったので /etc/postfix/main.cfの「inet_protocols = all」を「inet_protocols = ipv4」に変更

# Enable IPv4, and IPv6 if supported
inet_protocols = ipv4

ただ、これをやったところ、dovecot submissionで受け取ったメールがpostfixに引き渡されてくれないという問題が発生・・・

how to set smtp-client -> submission_relay_host for IPv4 only?」で似たような感じで、IPv4だけでつなげたい場合設定はあるのか?という話があるが、/etc/hosts に書くぐらいの対処方法しかないようだ

で・・・さらに原因を調査してみて判明したこと

どうやら、Oracle Cloud内部の仮想マシン上から外部のIPv4アドレスに対してのポート25アクセスができない模様

IPv6アドレスであればいける

[root@ocimail ~]# telnet 外部メールサーバ 25
Trying <IPv6アドレス>...
Connected to 外部メールサーバ.
Escape character is '^]'.
220 外部メールサーバ ESMTP Postfix
quit
221 2.0.0 Bye
Connection closed by foreign host.
[root@ocimail ~]# telnet -4 外部メールサーバ 25
Trying <IPv4アドレス>...
^C
[root@ocimail ~]# 

ポート80だったらIPv4でも問題無いので、IPv4 ポート25に関してだけ規制されている模様

[root@ocimail ~]# telnet -4 外部メールサーバ 80
Trying <IPv4アドレス>...
Connected to 外部メールサーバ.
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 30 Oct 2025 06:02:36 GMT
Content-Type: text/html
Content-Length: 162
Connection: close
Location: https://_/
X-Frame-Options: sameorigin
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
Referrer-Policy: strict-origin

<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
Connection closed by foreign host.
[root@ocimail ~]# 

試しにOCIのセキュリティリストのセキュリティルールにて、エグレスルールとして、ポート25を追加してみたものの状況は変わりませんでした。(ステートフルのチェックを入れた場合も変化無し)

・・・Oracle Cloudドキュメントにポート25はブロックしてると記載されていました。

アウトバウンドSMTPがブロックされます

OutlookとIMAPのフォルダ事情

OutlookでIMAPメールサーバを登録した時に表示されるフォルダがいまいちなことがある

その原因についていろんな調べてみた

まだアクセスしたことないけどメールが届いているユーザのメールボックス状態とそのときのディレクトリ

# doveadm mailbox list -u testuser3
INBOX
# ls -aF /var/vmail/testuser3/Maildir/
./    dovecot-uidlist               dovecot.index.log       tmp/
../   dovecot-uidvalidity           dovecot.list.index.log
cur/  dovecot-uidvalidity.68eef53b  new/
#

このときのINBOXフォルダの実態はどこかになるかを確認すると下記の様になっており、各ユーザのメールボックスのroot がINBOXとなっている、ということがわかる。

# doveadm mailbox path -u testuser3 INBOX
/var/vmail/testuser3/Maildir
#

次に、OutlookにIMAPサーバ設定を追加してログインしてみる

上記のようなメールボックスが表示される

doveadmコマンドで確認すると日本語名のメールボックスが確認できる

# doveadm mailbox list -u testuser3
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

実際に作られているディレクトリを確認すると、日本語文字列ではない修正UTF-7と呼ばれるものになっている。(UTF-8ベースではなくUTF-7ベースなのかは2000年以前のsendmailでは8bit目を取り扱えないシステムも存在していたため7bitで表現できる範囲に収める必要があった。これを引き継いで7bit範囲内に収まるUTF-7を採用したと思われる)

# ls -aF /var/vmail/testuser3/Maildir/
 ./                            dovecot-uidvalidity.68eef53f
'.&Tgtm+DBN-'/                 dovecot.index.cache
'.&UkqWZG4IMH8wojCkMMYw4A-'/   dovecot.index.log
'.&j,dg0TDhMPww6w-'/           dovecot.list.index.log
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.mailbox.log
 ../                           new/
 cur/                          subscriptions
 dovecot-uidlist               tmp/
 dovecot-uidvalidity
#

この修正UTF-7が何を表しているかというのは、doveadmコマンドに-7,-8オプションを付与することで確認できる

# doveadm mailbox list -u testuser3 -7
&j,dg0TDhMPww6w-
&Tgtm+DBN-
&UkqWZG4IMH8wojCkMMYw4A-
&kAFP4W4IMH8wojCkMMYw4A-
INBOX
# doveadm mailbox list -u testuser3 -8
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

それぞれのメールボックスがどう変換されるのかを具体的に確認するのであれば、下記の様に「doveadm mailbox mutf7 -7 “文字列”」「doveadm mailbox mutf7 -8 “文字列”」と実行する

# doveadm mailbox mutf7 -7 "&j,dg0TDhMPww6w-"
迷惑メール
# doveadm mailbox mutf7 -8 "迷惑メール"
&j,dg0TDhMPww6w-
#

というわけで、Outlookで最初にIMAPメールを取りに行くと日本語でメールフォルダを作成する、ということがわかった。

Outlook形式メールボックスをThunderbirdメールで使う方法

同じユーザアカウントをThunderbirdメールで取得してみると、下記の様に表示される

じゃあ、下書き/削除済みアイテム/送信済みアイテムがOutlookと相互同期がとれているのかというと、そうはなっていなかった。

Thunderbirdの[アカウント設定]-[送信控えと特別なフォルダー]を見てみると、下記に様に、送信済みは「ローカルフォルダー」、下書きも「ローカルフォルダー」となっている。

これをどちらも各ユーザを指定する

かと思ったのですが、上記を設定しても、実際にメール送信や下書き保存してから設定を確認すると「ローカルフォルダー」に戻ります。

ただしい設定は「その他のフォルダーを指定する」を選んで、手動でフォルダを指定することでした

これで解決かと思ったのですが、「ゴミ箱」と「迷惑メール」についての設定がありません。

ゴミ箱は[サーバー設定]-[サーバー設定]にある「メッセージを削除する時」でゴミ箱を指定

迷惑メールは[迷惑メール]-[移動先と保存期間]で設定します。

で・・・ここまでの設定を行った段階でdoveadmコマンドでメールボックスを確認してみたところ、設定中にThunderbirdが「Junk」と「Trash」を別に作ってしまったようです。

# doveadm mailbox list -u testuser3
Junk
Trash
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

Thunderbirdメール上のメールボックス表示も「迷惑メール」が2種類、「ゴミ箱」と「削除済みアイテム」が両方ある、という状態に

Outlook側も「ゴミ箱」と「削除済みアイテム」が両方ある、という状態

これの解消についてはThunderbirdであればアカウント名の右クリックメニューから「購読」

表示される一覧の「Junk」と「Trash」のチェックを外します

下記の様に表示されます。

IMAPの購読設定はOutlook側で行うこともできます。受信トレイの右クリックメニューから「IMAPフォルダ」を選び、[クエリ]をクリックすると、下記の様にフォルダが表示されます。

「Junk」と「Trash」をそれぞれ「購読取り消し」を選んで適用します

Outlook側の表示も下記の様になります。(フォルダが残ったままの場合は一度Outlookを起動し直す)

日本語版Outlookと英語版Outlookは共存できるのか?

Outlookで自動的に作成されるのは日本語名のフォルダになっている。

じゃあ、英語環境ではどうなのか?と英語版Outlook環境を作成して、日本語版Outlook/Thunderbirdでアクセス済みのアカウントを設定してみた。

英語名のフォルダが別に作成されてしまうという事態に

# doveadm mailbox list -u testuser3
Drafts
Sent Items
Junk
Trash
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
#

英語Outlookでメール送信/下書きをすると、英語名フォルダに保存され、日本語環境のモノと同期がとれず、それぞれ別に保存されていることを確認

日本語Outlookでフォルダを確認すると下記の状態

OutlookのIMAPフォルダーでの購読状況は下記の様にどちらも共通(INBOX/受信ボックスはどちらも共通)

で・・・Thunderbirdメールの場合、とてもややこしい状態になっています

じゃあ、日本語Outlookと英語Outlookでメールボックス名を共通化することができるのか?

下書きの保存については「Change where sent email messages are saved」に記載があった

[ファイル]-[オプション]の「メール」にある「メッセージの保存」で下書きの保存場所を設定できる・・・のかと思ったら

選択できるものが、それぞれ英語/日本語でOutlookが作成したものだけとなっており、それ以外の場所が設定できないようだ。

Thunderbirdログイン後に日本語Outlookからアクセス

初回ログインはThunderbirdから行って、次に日本語Outlookからアクセスした場合の状態について確認

まずはサーバ上の初期状態を確認

# doveadm mailbox list -u testuser2
INBOX
# ls -aF testuser2/Maildir/
./  ../  cur/  dovecot.list.index.log  new/  tmp/
#

Thunderbirdに設定を入れた直後は「受信トレイ」と「ゴミ箱」のみ

# doveadm mailbox list -u testuser2
Trash
INBOX
# ls -aF testuser2/Maildir/
./       dovecot-keywords              dovecot.index.cache     new/
../      dovecot-uidlist               dovecot.index.log       subscriptions
.Trash/  dovecot-uidvalidity           dovecot.list.index.log  tmp/
cur/     dovecot-uidvalidity.68ef30a8  dovecot.mailbox.log
#

このときのThunderbird設定を確認すると[サーバー設定]-[サーバ設定]の「メッセージを削除する時」はIMAPのフォルダーになっている

それに対して[送信控えと特別なフォルダー]は、ローカルフォルダーになっている。

これを下記の設定にしても、しばらくするとローカルフォルダ設定に戻る。

動作を確認すると、ゴミ箱については、確かにTrashフォルダにメールが移動されていることを確認できた。

この状態で、OutlookでIMAP設定を行うと下記の様になった。

# doveadm mailbox list -u testuser2
迷惑メール
下書き
送信済みアイテム
Trash
INBOX
# ls -aF testuser2/Maildir/
 ./                            dovecot-uidvalidity
'.&Tgtm+DBN-'/                 dovecot-uidvalidity.68ef30ab
'.&j,dg0TDhMPww6w-'/           dovecot.index.cache
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.index.log
 ../                           dovecot.list.index.log
 .Trash/                       dovecot.mailbox.log
 cur/                          new/
 dovecot-keywords              subscriptions
 dovecot-uidlist               tmp/
#

Thunderbirdで作成されたUI上は「ごみ箱」となっていた「Trash」フォルダは、Outlook側では「Trash」と表示され、Outlook側でメールを削除すると「Trash」フォルダにメールが移動する、ということが確認できた。

つまり、「受信トレイ」と「ゴミ箱」については、ThunderbirdとOutlookとで共通利用が可能なようだ

Outlook側で作成したフォルダが追加されたあとのThunderbird側は下記の表示となった。

このときに、Outlook側と動作を揃えるためにアカウント設定では以下の様に「その他のフォルダーを指定する」の方を選んで設定する。

下記の様にフォルダーに色がついたりする

英語版Outlookで初回ログインした場合

英語版Outlookで初回ログインした場合

# doveadm mailbox list -u testuser4
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser4/Maildir/
 ./                 cur/                           dovecot.list.index.log
 ../                dovecot-uidlist                dovecot.mailbox.log
'.Deleted Items'/   dovecot-uidvalidity            new/
 .Drafts/           dovecot-uidvalidity.68ef371e   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

この状態ではThunderbirdメールから見ると以下の状態となっていた

# doveadm mailbox list -u testuser4
Trash
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
#

このとき、thunderbirdの設定は下記となっており、下書きについては、自動的に「その他のフォルダー」の方で設定されている。

しかし、Thunderbirdでメールの送信と下書き保存を行ってみると送信済みは

この状態では、英語outlookとThunderbirdではゴミ箱と送信済みの同期がとれていない状態となっていた。

英語版Outlook「Deleted Items」とThunderbird「Trash」がIMAP上の別フォルダ。
英語版Outlook「Sent Items」はIMAP上だが、Thunderbirdの「送信済みトレイ/送信済みアイテム」はローカル

続いて日本語Outlookで設定をすると下記となり、この場合はフォルダ名が英語表示ではあるものの内容は英語版Outlookと同期がとれている。

dovecotの設定調整で共有化できるのか?

ここまでのところで判明した問題点

・OutlookはIMAPアクセスした時に規定のフォルダがないと新規作成する
・英語版Outlookで作ったフォルダは日本語版Outlookでも共通で使えるが、逆は別物となる
・ThunderbirdでIMAPアクセスした時は、ゴミ箱(Trash)しか作成しない

dovecotの設定で /etc/dovecot/conf.d/15-mailboxes.conf内で下記ような設定がある

namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox Trash {
    special_use = \Trash
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }

special_use というのは RFC6154「IMAP LIST Extension for Special-Use Mailboxes」で定義されている特殊な役割をもつものとなっていて「\Drafts(下書き)」「\Junk(迷惑メール)」「\Trash(ゴミ箱)」「\Sent(送信済みアイテム)」の設定となっている。

すでに行われている設定をみると、「Sent」と「Sent Messages」は同じ「\Sent」を指す、という設定になっているように見える

この設定をこれまでに出てきたものに対して適用することで解決できるのでは?ということで並べると・・・

\Drafts 候補
下書き
Drafts

\Junk 候補
迷惑メール
Junk
Junk Email

\Trash 候補
削除済みアイテム
Trash
Deleted Items

\Sent 候補
送信済みアイテム
Sent Items

これを /etc/dovecot/conf.d/15-mailboxes.conf に設定してdovecot再起動

##
## Mailbox definitions
##

# Each mailbox is specified in a separate mailbox section. The section name
# specifies the mailbox name. If it has spaces, you can put the name
# "in quotes". These sections can contain the following mailbox settings:
#
# auto:
#   Indicates whether the mailbox with this name is automatically created
#   implicitly when it is first accessed. The user can also be automatically
#   subscribed to the mailbox after creation. The following values are
#   defined for this setting:
#
#     no        - Never created automatically.
#     create    - Automatically created, but no automatic subscription.
#     subscribe - Automatically created and subscribed.
#
# special_use:
#   A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the
#   mailbox. There are no validity checks, so you could specify anything
#   you want in here, but it's not a good idea to use flags other than the
#   standard ones specified in the RFC:
#
#     \All       - This (virtual) mailbox presents all messages in the
#                  user's message store.
#     \Archive   - This mailbox is used to archive messages.
#     \Drafts    - This mailbox is used to hold draft messages.
#     \Flagged   - This (virtual) mailbox presents all messages in the
#                  user's message store marked with the IMAP \Flagged flag.
#     \Important - This (virtual) mailbox presents all messages in the
#                  user's message store deemed important to user.
#     \Junk      - This mailbox is where messages deemed to be junk mail
#                  are held.
#     \Sent      - This mailbox is used to hold copies of messages that
#                  have been sent.
#     \Trash     - This mailbox is used to hold messages that have been
#                  deleted.
#
# comment:
#   Defines a default comment or note associated with the mailbox. This
#   value is accessible through the IMAP METADATA mailbox entries
#   "/shared/comment" and "/private/comment". Users with sufficient
#   privileges can override the default value for entries with a custom
#   value.

# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox "下書き" {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox "迷惑メール" {
    special_use = \Junk
  }
  mailbox "Junk Email" {
    special_use = \Junk
  }
  mailbox Trash {
    special_use = \Trash
  }
  mailbox "削除済みアイテム" {
    special_use = \Trash
  }
  mailbox "Deleted Items" {
    special_use = \Trash
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
  mailbox "送信済みアイテム" {
    special_use = \Sent
  }
  mailbox "Sent Items" {
    special_use = \Sent
  }

  # If you have a virtual "All messages" mailbox:
  #mailbox virtual/All {
  #  special_use = \All
  #  comment = All my messages
  #}

  # If you have a virtual "Flagged" mailbox:
  #mailbox virtual/Flagged {
  #  special_use = \Flagged
  #  comment = All my flagged messages
  #}

  # If you have a virtual "Important" mailbox:
  #mailbox virtual/Important {
  #  special_use = \Important
  #  comment = All my important messages
  #}
}

初期状態

# doveadm mailbox list -u testuser5
INBOX
# ls -aF testuser5/Maildir/
./  ../  cur/  new/  tmp/
#

日本語Outlookで最初に作成した場合

日本語Outlookでログイン

# doveadm mailbox list -u testuser5
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
# ls -aF testuser5/Maildir/
 ./                            dovecot-uidvalidity.68ef4b2b
'.&Tgtm+DBN-'/                 dovecot.index.cache
'.&UkqWZG4IMH8wojCkMMYw4A-'/   dovecot.index.log
'.&j,dg0TDhMPww6w-'/           dovecot.list.index.log
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.mailbox.log
 ../                           new/
 cur/                          subscriptions
 dovecot-uidlist               tmp/
 dovecot-uidvalidity
#

続いて英語Outlookでログインした場合

# doveadm mailbox list -u testuser5
迷惑メール
下書き
削除済みアイテム
送信済みアイテム
INBOX
# ls -aF testuser5/Maildir/
 ./                            dovecot-uidvalidity.68ef4b2b
'.&Tgtm+DBN-'/                 dovecot.index.cache
'.&UkqWZG4IMH8wojCkMMYw4A-'/   dovecot.index.log
'.&j,dg0TDhMPww6w-'/           dovecot.list.index.log
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.mailbox.log
 ../                           new/
 cur/                          subscriptions
 dovecot-uidlist               tmp/
 dovecot-uidvalidity
#

英語版Outlookであっても、日本語文字列でのフォルダが見えており、ゴミ箱/下書き/送信済みアイテムの内容が日本語版Outlookと同期がとれていることを確認できた。

Thunderbirdで設定すると以下の状態で見れる

Thunderbirdの[サーバー設定]の「メールを削除するとき」の初期値は下記となっていて、ちゃんと選択されてるのか?という感じでしたが、メールを削除すると、IMAP上のTrashに移動してることを確認しました

[送信控えと特別なフォルダー]は下記

日本語版Outlook、英語版Outlook、Thunderbirdメールのそれぞれで同期がとれたように見える。

英語Outlookで最初に作成した場合

英語Outlookで最初にアクセスした場合に作成されるもの

# doveadm mailbox list -u testuser5
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser5/Maildir/
 ./                 cur/                           dovecot.list.index.log
 ../                dovecot-uidlist                dovecot.mailbox.log
'.Deleted Items'/   dovecot-uidvalidity            new/
 .Drafts/           dovecot-uidvalidity.68ef4f73   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

続いて日本語Outlookでログイン

実際に作成されているメールボックスは英語のまま

# doveadm mailbox list -u testuser5
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser5/Maildir/
 ./                 cur/                           dovecot.list.index.log
 ../                dovecot-uidlist                dovecot.mailbox.log
'.Deleted Items'/   dovecot-uidvalidity            new/
 .Drafts/           dovecot-uidvalidity.68ef4f73   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

最後にThunderbirdは下記状態で、特に問題は無い状態となっていた。

日本語Outlookで作成された「削除済みアイテム」の選択表示がおかしかったが、英語文字列の場合は特に問題ないようだ。

Thunderbirdで最初にアクセスした場合

Thuderbirdで最初にアクセスした場合は下記の様になった

# doveadm mailbox list -u testuser5
Trash
INBOX
# ls -aF testuser5/Maildir/
./       dovecot-keywords              dovecot.index.cache     new/
../      dovecot-uidlist               dovecot.index.log       subscriptions
.Trash/  dovecot-uidvalidity           dovecot.list.index.log  tmp/
cur/     dovecot-uidvalidity.68ef52a1  dovecot.mailbox.log
#

このとき、設定は、ゴミ箱はIMAP上を使用するが、「送信済みアイテム」と「下書き」についてはローカルに保存する設定になっていた。

この状態で、日本語Outlookからアクセスすると、日本語名で作成される

# doveadm mailbox list -u testuser5
迷惑メール
下書き
送信済みアイテム
Trash
# ls -aF testuser5/Maildir/
 ./                            dovecot-uidvalidity
'.&Tgtm+DBN-'/                 dovecot-uidvalidity.68ef52a4
'.&j,dg0TDhMPww6w-'/           dovecot.index.cache
'.&kAFP4W4IMH8wojCkMMYw4A-'/   dovecot.index.log
 ../                           dovecot.list.index.log
 .Trash/                       dovecot.mailbox.log
 cur/                          new/
 dovecot-keywords              subscriptions
 dovecot-uidlist               tmp/
#

改めてthunderbird側で確認すると、下記の状態に変更されているが下書きと送信済みアイテムの同期が出来ていない

設定を確認すると、アイコンの絵がそれっぽく表示されているだけで、設定自体は手動で変更する必要があった。

これを下記に変更したところ同期が行われるようになった

設定追加

RFC6154を読むと、special useとして定義さえている文字列には「\Archive」「\Flagged」とゴミ箱/迷惑メールを含めて全メールを表示する「\All」がある模様

「\Archive」は、Outlookの各メールの右クリックメニューにある「Archive/アーカイブ」で保存される先として使用される。

# doveadm mailbox list -u testuser4
Archive
Junk
Trash
Junk Email
Drafts
Deleted Items
Sent Items
INBOX
# ls -aF testuser4/Maildir/
 ./                 .Trash/                        dovecot.list.index
 ../                cur/                           dovecot.list.index.log
 .Archive/          dovecot-keywords               dovecot.list.index.log.2
'.Deleted Items'/   dovecot-uidlist                dovecot.mailbox.log
 .Drafts/           dovecot-uidvalidity            new/
 .Junk/             dovecot-uidvalidity.68ef3721   subscriptions
'.Junk Email'/      dovecot.index.cache            tmp/
'.Sent Items'/      dovecot.index.log
#

上記のように「Archive」フォルダが作成される。このフォルダについては日本語Outlook環境でも英語表記Archiveでアーカイブ動作をした。

次に、最初に日本語Outlook環境で「アーカイブ」した場合は、日本語で作成される

# doveadm mailbox list -u testuser5
アーカイブ
迷惑メール
下書き
送信済みアイテム
Trash
INBOX
#

英語Outlookでアーカイブを行おうとすると、日本語アーカイブフォルダは認めてくれていない

/etc/dovecot/conf.d/15-mailboxes.confに下記設定を追加してdovecot再起動

  mailbox Archive {
    special_use = \Archive
  }
  mailbox "アーカイブ" {
    special_use = \Archive
  }

これで問題無くなるかと思ったのですが、引き続き”Archive”を新規作成するダイアログが表示される状態に・・・

アーカイブの動作が謎だ・・・