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. <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 = </etc/dehydrated/certs/ホスト名/fullchain.pem
ssl_key = </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 = </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
#
# <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=<アドレス@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はブロックしてると記載されていました。



























































































