2026/02/23(月)PostfixAdmin/SQLite を php-cgi として Debian にインストール
メールサーバのためだけにさくらのレンタルサーバを借りるのがもったいなく感じてました。ライトプランに変更できれば良いんですが、不可能なので、PostfixAdminを使ってWeb管理できるメールサーバを立てた記録。
- 背景
- 設定方針
- 準備
- PostfixAdminのインストール
- Postfixの設定
- Dovecotの設定
- (おまけ)DKIM設定
- (おまけ)SPAM対策/SPF検証でMilterを導入
- (おまけ)さくらのレンタルサーバのクソ仕様(脆弱性のある仕様)
- まとめ
- 参考
※メモ代わりに PostfixAdmin 以外の設定も、おまけとして記載しています。
背景
そもそも「なぜさくらのレンタルサーバでメールを管理していたのか」という話になります。
- メールサーバが落ちると致命的であるので、自前サーバに依存させたくない。
- 最悪、自前サーバを復旧させるためにメール受信が必要になると積む可能性がある。
- メールサーバは面倒な設定が多く、それでいて設定をミスると致命的であるので面倒くさい。
- Web上からメールアカウントを管理できると便利である。
この中で、一番下の要因を解決できないかと、試してみたのが PostfixAdmin です。PostfixAdmin は Postfix + DovecotによるメールサーバをWebから管理するためのツールです。PHPで作られておりブラウザからメールアカウントを管理することができます。
設定方針
- サーバは Debian 13/Trixie。
- Webサーバは稼働中の Apache を使用。
- PHPは全体で有効にするのではなく、PostfixAdminの領域に限り cgi で実行。*1
- DBエンジンは SQLite を使用。
Debian系では postfixadmin というパッケージがありますが、モジュール版PHPやMySQL(MariaDB)サーバなども一緒に入ってしまうこと、特に設定が楽になるわけではなさそうなので今回は見送りました。
準備
必要なパッケージを先にインストールしておきます。
apt-get install php-cgi php-xml php-mysql php-sqlite3 php-mbstring apt-get install postfix postfix-sqlite dovecot-core dovecot-pop3d dovecot-sqlite
php-mysqlは使用しませんが、ライブラリを入れないと、PostfixAdminが起動しません。
続いてバーチャルメールアドレス(実Linuxアカウントを保たないメールアドレス)を使用するので、そのデータを保管する専用アカウントを作成します。
# adduser vmail # id vmail uid=1001(vmail) gid=1001(vmail) groups=1001(vmail),100(users)
後で使用するので、uidとgidをメモっておきます。
ディレクトリ関連を先に設定しておきます。
chmod 770 /home/vmail mkdir /home/vmail/mail chmod 770 /home/vmail/mail
パーミッション設定の簡略化とセキュリティのため、Webサーバ、Postfix、Dovecotを同じ vmail グループに所属させておきます。
adduser www-data vmail adduser postfix vmail adduser dovecot vmail
PostfixAdminのインストール
Postfix/Dovecotの設定とは分けて解説します。
PostfixAdminのダウンロードと解凍
PostfixAdminのリポジトリのリリースから最新版をダウンロードして、これを適当なディレクトリに解凍します。この解説では /home/vmail として話を進めます。
# su vmail $ cd /home/vmail $ wget https://github.com/postfixadmin/postfixadmin/archive/refs/tags/v4.0.1.tar.gz $ tar xvf v4.0.1.tar.gz $ mv postfixadmin-4.0.1 postfixadmin
- git から clone する方法もあります。詳細は INSTALL.TXT を参照してください。
- postfixadmin/public がApache等からアクセスできるようにパーミッションに注意してください。
また template_c ディレクトリを作成し、Apache等からアクセスできるようにしておきます。
cd /home/vmail/postfixadmin mkdir template_c chmod 775 template_c
Apacheの設定
000-default.confに以下のような設定を追加します。
<Directory /usr/lib/cgi-bin>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory /home/vmail/postfixadmin>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<VirtualHost *:80>
DocumentRoot /home/vmail/postfixadmin/public
ServerName postfixadmin.example.jp
<FilesMatch \.php$>
SetHandler php-cgi
</FilesMatch>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
Action php-cgi /cgi-bin/php
</VirtualHost>
- postfixadmin/public を DocumentRoot とすることに注意してください。
- バーチャルホストで設定していますが、他の方法でも問題ありません。
- サーバ全体では PHP を無効化しているので、PostfixAdminでのみPHPを許可しています。
- 実際は「Digest認証」を追加して、容易にアクセスされないよう対策しています。
SQLite設定
SQLiteの空DBを作成しておきます。postfixやdovecotからアクセス(読み込み)可能なようにパーミッションに注意してください。*2
cd /home/vmail touch postfixadmin.sqlite chown postfix:vmail postfixadmin.sqlite chmod 660 postfixadmin.sqlite
※所有者を vmail にすると、postfix がなぜかDBファイルを読み出せないので、所有者を postfix にしています。
postfixadmin/config.local.php を作成し、以下のように記述します。
<?php
$CONF['database_type'] = 'sqlite';
$CONF['database_name'] = '/home/vmail/postfixadmin.sqlite';
$CONF['configured'] = true;
$CONF['welcome_text'] = "テストメールです。\n";
//パスワードの文字種制限を緩める(管理画面をメールユーザーに解放するならおすすめしない)
$CONF['password_validation'] = array(
'/.{8}/' => 'password_too_short 8'
);
?>
初期セットアップ
この状態でブラウザからセットアップスクリプト(http://postfixadmin.example.jp/setup.php)にアクセスします。
うまく行けば、セットアップ用パスワードを config.local.php に設定しろというメッセージが表示されると思います。「Generate setup_password」欄を使うなどしてボタンを押すと、パスワード設定が表示されます。
// PASS = "pass1234" $CONF['setup_password'] = '$2y$12$FijtslQhp/XZQGlyX66W9uQxeIHWRfCUkeCQ6ASOmzUvkHaTx7E6C';
これをコピーして、config.local.php に貼り付けます。貼り付けたら、再びセットアップスクリプトにアクセスして最初の管理者を追加してください。
無事に管理者を追加できたら、安全のため config.local.php からセットアップパスワードを削除しておきます。
初期画面(http://postfixadmin.example.jp/)にアクセスし、管理者アカウントでログイン、管理メニューが無事に表示されれば成功です。

Postfixの設定
バーチャルメールボックス対応にするため main.cf 等を変更します。バーチャルメールボックスのドメインは mydestination に記述しないことに注意してください。
# main.cf
virtual_mailbox_base = /home/vmail/mail
virtual_uid_maps = static:1001
virtual_gid_maps = static:1001
virtual_mailbox_domains =
sqlite:/etc/postfix/sql/virtual_domains_maps.cf
virtual_mailbox_maps =
sqlite:/etc/postfix/sql/virtual_mailbox_maps.cf,
sqlite:/etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf
virtual_alias_maps =
sqlite:/etc/postfix/sql/virtual_alias_maps.cf,
sqlite:/etc/postfix/sql/virtual_alias_domain_maps.cf,
sqlite:/etc/postfix/sql/virtual_alias_domain_catchall_maps.cf
uid/gid は vmail のものです。数字は環境によって違うので、必ず調べた値を記入してください。
/etc/postfix/sql 以下のファイルには、DBへのアクセス方法(SQLiteならファイルの場所)とSQL文を記述しますが、数が多いので sql/ ごとtarで固めたファイルを置きました。ダウンロードして確認するか、そのまま*3使用してください。
動作確認
ここまで設定したら、postfixをリロードした上で、PostfixAdmin上で適当なドメイン及びメールアドレスを追加します。
作成したアドレス宛に実際にメールを送信して /home/vmail/mail 以下にメールが配送されていることを確認します。またログ(mail.log)を確認するも良いでしょう。
STMP AUTH用の設定
smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
- SQLiteのDBに記録されるパスワードはハッシュですので、使用可能な認証方式は PLAIN のみです。
- 特に設定変更してなければ、submissionはSTARTTLS(SMTPS)のみ許可になります。
- 一番下の行は、デフォルトで設定済みだと思います。
その他の設定メモ
main.cf
compatibility_level = 3.6 smtpd_banner = ESMTP unknow disable_vrfy_command = yes
master.cf
smtp inet n - y - - smtpd -o smtpd_tls_security_level=may -o smtpd_recipient_restrictions=permit_mynetworks,reject_unknown_sender_domain,reject_unknown_recipient_domain,reject_unauth_pipelining,reject_unauth_destination submission inet n - y - - smtpd -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o cleanup_service_name=scleanup scleanup unix n - y - 0 cleanup -o header_checks=regexp:/etc/postfix/header_checks_submission
header_checks_submission
/^Received:.*/ IGNORE
下2つの詳細は「Postfix/Dovecot Debian/Ubuntu で SMTP Auth の設定」を参照してください。
Dovecotの設定
10-mail.conf
mail_driver = maildir
mail_path = /home/vmail/mail/%{user|domain}/%{user|username}
mail_uid = vmail
mail_gid = vmail
10-master.conf
#該当部分のコメントを外す
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0666
}
#最後のほう
#!include auth-system.conf.ext
!include auth-sql.conf.ext
auth-sql.conf.ext
sql_driver = sqlite
sqlite_path = /home/vmail/postfixadmin.sqlite
passdb sql {
query = \
SELECT username as user, password \
FROM mailbox \
WHERE username = '%{user}' AND active = '1'
}
userdb sql {
query = \
SELECT '/var/vmail/%{user|username}/%{user|domain}' as home \
FROM mailbox \
WHERE username = '%{user}' AND active = '1'
}
動作確認
すべて設定が終わったらdovecotを再起動して、Postfixの動作確認で送ったメールが受信できることを確認します。SMTP AUTHの設定も行っている場合は、送信できることも確認すると良いでしょう。
(おまけ)DKIM設定
DKIMは、概ね「DebianのPostfixでのSPF / DKIM / DMARC設定 with Route 53」の記事に従って実施しましたが、いくつか問題があったため以下メモしておきます。
- /etc/default/opendkim の RUNDIR は変更しない(変更不要)。
- ID:postfix を opendkim グループに所属させない。所属させると、opendkimに「key data is not secure: opendkim is in group (xxx) which has multiple users」と怒られ、メール送信不可になる。*4
- 代わりに「opendkim.conf」の「UMask」設定を「000」に書き換えた上で、以下を実行する。
mkdir /var/spool/postfix/opendkim chown postfix:opendkim /var/spool/postfix/opendkim chmod 750 /var/spool/postfix/opendkim service opendkim restart
(おまけ)SPAM対策/SPF検証でMilterを導入
千石電商のメールアドレス流出事件*5以来SPAMが届くようになってしまったので、SPAM対策として以下の Milter を導入しました。
Milterとは受信中メールを解析して直接「受取拒否」などができるAPI仕様です。OpenDKIM設定でも使用されています。
似たような機能として「キュー投入前コンテンツフィルタ(smtpd_proxy_filter)」というものがありますが、Milterに比べて「設定や運用が煩雑で、外部のフィルタプログラムか落ちると全メールを拒否してしまう」という問題があります。Milterは仕組みが簡単であり「柔軟なフィルタを簡潔に書ける上に、何らかの要因で外部プログラムが落ちてもメールをきちんと受信できる」という利点があります。
(おまけ)さくらのレンタルサーバのクソ仕様(脆弱性のある仕様)
DKIM検証中に気づいたさくらのレンタルサーバの致命的な不具合。
さくらのレンタルサーバに「DKIM公開鍵を登録してない」DKIM署名付きメール(つまり署名を検証不可能なメール)を送ると、署名の検証結果がpassになります。
ARC-Authentication-Results: i=1; (account).sakura.ne.jp; spf=none smtp.mailfrom=nabe@test.abk.nu smtp.helo=test.abk.nu; dkim=pass (good signature) header.d=test.abk.nu header.s=default; arc=none; Date: Mon, 23 Feb 2026 09:10:45 +0900
さくらのレンタルサーバの受信側ドメインでDKIM機能をオンにして送信時DKIM機能が有効になれば、この現象が再現できます。不具合が中の人に届いて1ヶ月以上経ちましたけど、直る気配はありません(2026/2/23現在)。
その他、さくらのレンタルサーバで、短時間に「DKIMオン&秘密鍵作成」→「DKIMオフ」→「DKIMオン&秘密鍵作成」を実行すると、DKIM署名機能が長時間(24時間程度)有効にならない不具合も見つけました。
まとめ
改めて思ったけど、メールまわりは面倒くさい。
- セキュリティ問題。
- 失敗するとメールが受け取れない可能性。
- 複数のツールを組み合わせることによる設定の複雑化(ミスが起きやすい)。
設定は面倒でしたが、Milter導入など色々と融通が効くのは良いですね。