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がブロックされます

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください