GlusterFS, MySQL, Postfix-admin, HAProxy を使用したメールサーバクラスタ構築

■やりたいこと/やること

今回の目的は以下のとおり。

  • 夜中・休日に起こされないメールサーバを作りたい。(涙拭けよ)
  • 管理が楽なメールサーバを作りたい。(ブラウザからポチポチ管理したい、各ユーザに自分でPW変更とかさせたい)
これらを満たす(と思いたい)メールクラスタシステムを構築しておきます。メールサーバ一式にはPostfix,Dovecotを、メールボックスを置くストレージの冗長化には、GlusterFSを、メールユーザの情報管理にはPostfix-adminMySQL、それぞれ使用して作成していきます。アクセスを振り分けるには、ロードバランサーが必要です。設定の流れをまとめると以下のとおりです。
 
  • (1)Serverを3台準備する。(2サーバはメール用途、のこりはLB用途)
  • (2)GlusterFS setup
  • (3)必要なソフトウェアのinstall ,download
  • (4)MySQLの初期設定・REPLICATION設定
  • (5)Postfixの設定
  • (6)Dovecotの設定
  • (7)Apacheの設定
  • (8)Postfix-Adminの初期設定(マスター側のみ)
  • (9)マスターサーバの動作テスト
  • (10)スレーブサーバの設定
  • (11)HAProxyのインストール・設定 

(1)Serverを3台準備する。

頑張って作成します。ちなみにマスター側、スレーブ側としているのは、メールアカウントの追加やドメインの追加作業以外のマスター側だけで行うことを想定して作成しているためです。メールを送信したり受信を受け付ける役割に優劣はなく、両サーバで同じふるまいをさせるようにします。
  • マスター用 10.24.96.120
  • スレーブ用 10.24.96.121
  • LB用 10.24.96.122

(2)GlusterFS setup

GlusterFSを使用する目的は、Postfixとdovecotが扱うユーザのメールボックス領域を冗長化するためです。GlusterFSを使用して共有ストレージを作成し、そこ(/mail/)にメールボックスを配置します。GlusterFSは別記事でも書いてますので細かい説明は割愛します。各サーバは平常時はローカル経由でGlusterFSをマウントし、なんらかのトラブルでローカルマウントに失敗した場合はリモート経由でマウントするようにマウント設定を行います。
ボリュームタイプには「Replicated」を使用してサーバ間でブリックを複製します。(RAID1みたいにする)
 
 ■Masterサーバ側
//リポジトリ取得、インストール、自動起動ON
yum install centos-release-gluster
yum install glusterfs-server
chkconfig glusterd on

//マウント用ディレクトリ、Gluster用ディレクトリ作成
mkdir /mail
chmod 777 /mail

//Gluster用の追加ディスクのパーティション作成、ファイルシステム構築、マウント設定
fdisk /dev/sdb
mkfs.ext4 /dev/sdb1
mount -t ext4 /dev/sdb1 /gluster/
mkdir /gluster/gs01
echo "/dev/sdb1 /gluster ext4 defaults        1 1" >> /etc/fstab

//Glusterd起動、ピア登録、DFSを作成、
etc/init.d/glusterd start
echo "10.24.96.120 gmail01.com" >> /etc/hosts
echo "10.24.96.121 gmail02.com" >> /etc/hosts
gluster peer probe 10.24.96.121
gluster volume create gs01 replica 2 gmail01.com:/gluster/gs01 gmail02.com:/gluster/gs01
mount -t glusterfs gmail01.com:/gs01 /mail

//Fail_Over & マウント設定
echo "gmail01.com:/gs01 /mail glusterfs defaults,_netdev,backupvolfile-server=gmail02.com 0 0" >> /etc/fstab

//Errorがないことを一応確認
mount -a
■Slaveサーバ側
//リポジトリ取得、インストール、自動起動ON
yum install centos-release-gluster
yum install glusterfs-server
chkconfig glusterd on

//マウント用ディレクトリ、Gluster用ディレクトリ作成
mkdir /mail
chmod 777 /mail

//Gluster用の追加ディスクのパーティション作成、ファイルシステム構築、マウント設定
fdisk /dev/sdb
mkfs.ext4 /dev/sdb1
mount -t ext4 /dev/sdb1 /gluster/
mkdir /gluster/gs01
echo "/dev/sdb1 /gluster ext4 defaults        1 1" >> /etc/fstab

//Glusterd起動、ピア登録、DFSを作成、
etc/init.d/glusterd start
echo "10.24.96.120 gmail01.com" >> /etc/hosts
echo "10.24.96.121 gmail02.com" >> /etc/hosts
mount -t glusterfs gmail02.com:/gs01 /mail

//Fail_Over & マウント設定
echo "gmail02.com:/gs01 /mail glusterfs defaults,_netdev,backupvolfile-server=gmail01.com 0 0" >> /etc/fstab

//Errorがないことを一応確認
mount -a

(3)必要なソフトウェアをインストール&ダウンロード

<マスター&スレーブサーバ共通>
//SMTPサーバ構築に必要
yum install postfix
 
//POP,IMAPサーバ構築に必要
yum install dovecot-mysql dovecot
 
//自動起動ON
chkconfig mysqld on
chkconfig httpd on
chkconfig dovecot on

 <マスターサーバ側のみ>

//Postfix-adminに必要()
yum install -y http php mysql mysql-server mysql-devel php-mysql php-mbstring php-imap mod_auth_mysql
cd /var/www/html/
wget http://nchc.dl.sourceforge.net/sourceforge/postfixadmin/postfixadmin-2.92.tar.gz
tar zxvf postfixadmin-2.92.tar.gz
mv postfixadmin-2.92 postfixadmin

(4)MySQLの初期設定・REPLICATION設定

今回、MySQLを使用する目的は、PostfixやDomainが管理する自ドメインの情報やユーザのメールボックス、転送情報を格納するためです。メールサーバの動作は今回、Master&Master構成となるので、両サーバで同じDBを参照できる必要があります。そこで、両サーバ間でMySQLのDBを同期(レプリケーション)します。データベースを使用しなくてもサーバ間でルックアップテーブル等の認証ファイルを同期・共有すれば良いのでは?と思われるかもしれないですが、MySQLのレプリケーション設定がとても容易なこと、Postfix-adminからの管理をする際にデータベースを使用する必要があることから、MySQLを採用しました。
 
■MySQL初期セットアップ・管理用のDBユーザ,DBを作成
 
<マスターで実行>
//MySQL起動、MySQL rootパスワード設定
/etc/init.d/mysqld start
/usr/bin/mysqladmin -u root password ‘PASSWORD'
mysql -u root -p
//MySQLでメール情報を格納するDB,Tableを作成
mysql> create database postfix;
mysql> create user postfix@localhost identified by ‘YourPassword';
mysql> grant all privileges on postfix.* to postfix@localhost;

//レプリケーション用ユーザ作成
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'10.24.96.0/255.255.255.0' IDENTIFIED BY ‘YourPassword';
mysql> quit

//起動
/etc/init.d/mysqld start
■MySQLレプリケーション設定
my.cnfにmysqlセクションに追記します。(server-idは各サーバで一意な値とします。1を指定することはできません。) また、レプリケーションを行うときは、スレーブサーバはマスターサーバからレプリケーションに必要な情報を取得しますので(バイナリログ)レプリケーションに必要な専用ユーザを作成します。
 
<マスター側で設定>
//MySQL rootパスワード設定
cp -a /etc/my.cnf /etc/my.cnf.default
vi /etc/my.cnf
//[mysqld]セクションに追記
#replication
server-id = 1001
log-bin = mysql-bin
relay-log = relay-log

//再起動
/etc/init.d/mysqld restart
<スレーブ側で設定>
//MySQL起動、MySQL rootパスワード設定
cp -a /etc/my.cnf /etc/my.cnf.default
vi /etc/my.cnf

//[mysqld]セクションに追記
#replication
server-id = 1002
■DBの停止・DBコピー・ポジション番号の取得
スレーブ側でレプリケーションを開始するにあたり、マスター側DBのどこ(どのポジション)から同期を開始するか指定する必要があります。ただし、データベースに書き込みが行われるとポジション番号は変更されますので、一旦データベースの書き込みを禁止します。

<マスターサーバ側で実行する。>

mysql> FLUSH TABLES WITH READ LOCK;
 
//試しにデータベースに更新系クエリを発行してみる。怒られる。
mysql> create database test;
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
停止したMySQLデータベースを丸ごとコピーし、レプリケーション開始に必要なポジション番号を取得します。作業後はスレーブサーバに必要な情報が揃いましたので、マスターで書き込みを許可します。
<マスターサーバ側で実行>
//DBディレクトリに移動、圧縮アーカイブ化、現在ポジション番号を取得
cd /var/lib/mysql
tar cpfv /var/tmp/dbm-20161006.tar .
echo "SHOW MASTER STATUS\G" | mysql -u root -p >> /var/tmp/dbm-position20161006.txt
//書き込み再開
mysql> UNLOCK TABLES;
mysql> quit
Bye
マスターサーバからDBデータとポジション番号を確認します。(下記例では5097)
<マスターサーバ側で実行>
cat /var/tmp/dbm-position20161006.txt

*************************** 1. row ***************************
            File: mysql-bin.000001
        Position: 5097
    Binlog_Do_DB:
Binlog_Ignore_DB:
マスターサーバからスレーブサーバに.tarアーカイブをコピーし、展開します。(scpとかrsync)
[root@gmail01 ~]# scp -rp /var/tmp/dbm-20161006.tar root@10.24.96.121:/var/tmp/
<スレーブ側で実行>
tar -xpf /var/tmp/dbm-snapshot-20161006.tar -C /var/lib/mysql/
[root@gmail02 mysql]# ls -l /var/lib/mysql/
合計 20504
-rw-rw---- 1 mysql mysql 5242880 10月 8 16:25 2016 ib_logfile0
-rw-rw---- 1 mysql mysql 5242880 10月 7 21:56 2016 ib_logfile1
-rw-rw---- 1 mysql mysql 10485760 10月 8 16:24 2016 ibdata1
drwx------ 2 mysql mysql 4096 10月 7 21:56 2016 mysql
-rw-rw---- 1 mysql mysql 5097 10月 8 17:01 2016 mysql-bin.000001
-rw-rw---- 1 mysql mysql 19 10月 8 16:25 2016 mysql-bin.index
drwx------ 2 mysql mysql 4096 10月 8 16:20 2016 postfix
drwx------ 2 mysql mysql 4096 10月 7 21:56 2016 test
スレーブサーバからレプリケーションを開始します。

<スレーブ側で実行>

mysql> CHANGE MASTER TO MASTER_HOST='10.24.96.120',
MASTER_USER='repl',
MASTER_PASSWORD=‘YourPasswordr',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=5097
;
 
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
レプリケーションが開始されたことを確認します。I/OスレッドとSQLスレッドがともにYesとなっているかを確認します。
  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes
<スレーブ側で実行>
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.24.96.120
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 6756
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 1910
        Relay_Master_Log_File: mysql-bin.000001
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 6756
              Relay_Log_Space: 2059
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:

(5)Postfixの設定(Masterのみ)

■自己証明書(おれおれ証明書)作成
自己証明書作成を作成し、配置します。
cd /root/
openssl genrsa 2048 > mail2016.key
openssl req -new -key mail2016.key > mail2016.csr
openssl x509 -days 365 -req -signkey mail2016.key < mail2016.csr > mail2016.crt
cp -a mail2016.key /etc/pki/tls/private/
cp -a mail2016.crt /etc/pki/tls/certs/
■Postfixコンフィグファイル編集
基本的なパラメータは変更します。該当箇所を書き換えます。
vi /etc/postfix/main.cf
 各パラメータの内容は下記のとおりです。
inet_interfaces = all
リッスンするIPアドレスを指定する。デフォルトでlocalhostのみなので、allへ変更する。
mydestination =
受け取ったメールが自分宛てのドメインかそうではないかを判断するパラメータ。今回はこのパラメータではなくMySQLのルックアップテーブルを使用するので空にしておく。
mynetworks = 10.0.0.0/8, 127.0.0.0/8
外部ドメインへメールのリレーを許可する。
#home_mailbox
このパラメータはホームディレクトリから相対パスでユーザのメールボックスを指定するためのパラメータです。今回は、メールボックスの場所の指定は、mail_spool_directoryで行うのでコメントアウトします。この設定が有効になると、mail_spool_directoryが無効化されます。
mail_spool_directory = /mail/~/
ユーザのメールボックスを指定します。末尾にスラッシュがつけばMailDir形式スラッシュがなければMbox形式になります。
 
■追記パラメータ
追記パラメータは下記のとおり。まとめてmain.cfに追記します。
#Virtual Mailbox config
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 0
virtual_mailbox_base = /mail
virtual_minimum_uid = 5000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

#SMTP-Auth config
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $myhostname
smtpd_client_restrictions = reject_rbl_client bl.spamcop.net
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes

#TLS/SSL config
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_cert_file = /etc/pki/tls/certs/mail2016.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail2016.key
smtpd_tls_auth_only = no
各パラメータの意味は下記のとおりです。
virtual domain関連 パラメータ
意味
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
Postfixが配送時に参照するmailbox情報を指定するパラメータ。
DBサーバへの接続情報や発行するSQLクエリに必要な情報を記載した
ルックアップテーブルファイルを指定する。
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
Postfixが配送時に参照するエイリアス情報を指定するパラメータ。
DBサーバへの接続情報や発行するSQLクエリに必要な情報を記載した
ルックアップテーブルファイルを指定する。
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
Postfixが配送時に参照するdomain情報を指定するパラメータ。
DBサーバへの接続情報や発行するSQLクエリに必要な情報を記載した
ルックアップテーブルファイルを指定する。
virtual_mailbox_limit = 0
virtualメールボックスのサイズ上限。(デフォルト50MB??)0にすることで無制限にすることが可能。
virtual_mailbox_base = /mail
virtualユーザのメールボックスの配送先。
今回はGlusterFS領域の/mailを指定する。
virtual_minimum_uid = 5000
virtual配送されるユーザの最小UIDを指定する。
virtual_uid_maps = static:5000
Postfixはメールを配送する場合に配送エージェントプロセス(virtual)が配送先のユーザ権限で新たなメールファイルを作成するが、バーチャルユーザにはuid,gidがないため、virtul用のuidを固定で指定する。存在しないuidでもOK。
virtual_gid_maps = static:5000
Postfixはメールを配送する場合に配送エージェントプロセス(virtual)が配送先のユーザ権限で新たなメールファイルを作成するが、バーチャルユーザにはuid,gidがないため、virtul用のuidを固定で指定する。存在しないgidでもOK。
 
 
SMTP-auth関連 パラメータ
意味など 
smtpd_sasl_auth_enable = yes
SMTP-Authを有効にする
smtpd_sasl_type = dovecot
dovecot側のsmtp-auth機能を利用する。SMTP-authを利用する場合、SASL認証ライブラリを使う必要がある。
ライブラリはCyrus-SASLとDovecot-SASLライブラリがある。Cyrusパッケージのsasl-authdデーモンを使用してCyrus-SASL認証ライブラリを使用することもできるが、別途,認証にMySQLデータベースを読ますための設定等が必要になるため、今回はdovecot-SASLを使用し、Cyrus-SASLは使用しない。
smtpd_sasl_path = private/auth
SASL認証で利用するソケットファイルを指定する。Dovecotと共用する。
/var/spool/postfix/からの相対パスで記載。
smtpd_sasl_local_domain = $myhostname
#smtpd_sasl_local_domain = $myhostname??
Cyrus-SASLを利用する場合に必要。
今回は不要?
#smtpd_client_restrictions = reject_rbl_client bl.spamcop.net
Blacklistを使用して他のメールサーバやクライアントからのメール送信
を制限する場合に使用するパラメータ。
今回は不要?
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
 
メール受付時に、リレーを制限できるパラメータ。
permit_mynetworksはmynetworksパラメータからリレーを受け付ける。
permit_sasl_authenticated SMTP認証を通過したクライアントからのリレーを許可する。
reject_unauth_destination  はSMTP-AUTHを行わないホストからのリレーを拒否するオプション。
smtpd_sasl_security_options = noanonymous
匿名でのSMTP-authを拒否する。
noplaintextを指定すると平文パスワードの使用を拒否する。
broken_sasl_auth_clients = yes
古いバージョンのAUTHコマンドを使用したクライアントからの
認証を許可するか?デフォルトはno
 
 
SSL/TLS関連 パラメータ
意味など
smtpd_tls_security_level = may
mayを指定することで、PostfixはSMTPの通信開始時、暗号化(STARTLS開始)を要求し可能なら暗号化する。encryptを指定すると強制します。master.cfでencryptedを有効化すると25ポートへも暗号化を強制するため外部サーバからのメール配送時に相手が暗号化できない場合、配送に失敗することになるので、絶対に指定しないこと。
smtpd_tls_loglevel = 1
SSL/TLS通信時のログ記録の度合いを指定する。
 
0 TLS動作に関するログ記録を無効にします。
1 TLSハンドシェイクと証明書の情報をログに記録します。
2 TLSネゴシエーションの間のレベルをログに記録します。
3 TLSネゴシエーションプロセスの16進数およびASCIIダンプを ログに記録します。
4 STARTTLS以降の通信の16進数およびASCIIダンプを完全に ログに記録します。
smtpd_tls_cert_file = /etc/pki/tls/certs/mail2016.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail2016.key
SSLの証明書、秘密鍵の置き場を指定します。
smtpd_tls_auth_only = no
認証時にTLSを強制するかしないかの指定を行います。
 
 
■テーブル操作用ファイル作成
MySQLルックアップテーブルを下記のとおり作成する。ちなみに
/etc/postfix/mysql_virtual_domains_maps.cfで、select_field = descriptionと指定されている
ブログ等をよく見る気がするが、descriptionカラムが空だった場合に自ドメインとして存在するにも
関わらず、参照クエリにヒットしない事案が発生する問題があるため、domainとしています。
---

 
■Postfix書式チェック、起動
---
postfix check
[root@gmail01 ~]# /etc/init.d/postfix restart
postfix を停止中: [ OK ]
postfix を起動中: [ OK ]

(6)Dovecotの設定(Masterのみ)

■Dovecot設定
変更箇所まとめ。(dovecot -nでデフォルトから変更されたパラメータのみ抽出できる。)
//コンフィグファイル作成
touch /etc/postfix/mysql_virtual_mailbox_maps.cf
touch /etc/postfix/mysql_virtual_alias_maps.cf
touch /etc/postfix/mysql_virtual_domains_maps.cf
//DB接続情報、SELECTクエリ発行の設定を書き込む
[root@postfix-master ~]# cat /etc/postfix/mysql_virtual_mailbox_maps.cf
user = postfix
password = YourPassword
hosts = localhost
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
 
[root@postfix-master ~]# cat /etc/postfix/mysql_virtual_alias_maps.cf
user = postfix
password = YourPassword
hosts = localhost
dbname = postfix
table = alias
select_field = goto
where_field = address
 
[root@postfix-master ~]# cat /etc/postfix/mysql_virtual_domains_maps.cf
user = postfix
password = YourPassword
hosts = localhost
dbname = postfix
table = domain
select_field = domain
where_field = domain

[root@postfix-master ~]# dovecot -n
# 2.0.9: /etc/dovecot/dovecot.conf
# OS: Linux 2.6.32-504.el6.x86_64 x86_64 CentOS release 6.6 (Final)
auth_debug = yes
auth_debug_passwords = yes
auth_mechanisms = plain LOGIN CRAM-MD5
first_valid_gid = 5000
first_valid_uid = 5000
mail_location = maildir:~/
mbox_write_locks = fcntl
passdb {
  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = sql
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
}
ssl_cert = </etc/pki/tls/certs/jimae.crt
ssl_key = </etc/pki/tls/private/jimae.key
userdb {
  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = sql
}
■基本設定ファイルを編集する。
//config Backup
cp -a /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.defaut
vi /etc/dovecot/conf.d/10-mail.conf
//Postfixのバーチャル設定と合わせる。
diff /etc/dovecot/conf.d/10-mail.conf /etc/dovecot.default/conf.d/10-mail.conf
30c30
< mail_location = maildir:~/
---
> #mail_location =
167c167
< first_valid_uid = 5000
---
> #first_valid_uid = 500
174c174
< first_valid_gid = 5000
---
> #first_valid_gid = 1
■ユーザ認証にDBを参照させる,
//ConfigをBackupします。
cp -a /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.default
vi /etc/dovecot/conf.d/10-master.conf
//
[root@gmail01 ~]# diff /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.defaut
81c81
< #unix_listener auth-userdb {
---
> unix_listener auth-userdb {
85c85
< #}
---
> }
88,92c88,90
< unix_listener /var/spool/postfix/private/auth {
< mode = 0660
< user = postfix
< group = postfix
< }
---
> #unix_listener /var/spool/postfix/private/auth {
> # mode = 0666
> #}
114,117d111
<
< auth_debug_passwords = yes
< auth_verbose = no
< auth_debug = yes
■認証時に発行するSQLクエリを定義します。
user_queryはDBからユーザ情報を参照するクエリで、concatで静的な'/mail'ディレクトリとmaildirカラムの値を結合し、配送先ディレクトリを取得します。
password_queryはを参照するクエリです。
[root@gmail01 ~]# cat /etc/dovecot/dovecot-sql.conf.ext
driver = mysql
default_pass_scheme = MD5-CRYPT
connect = dbname=postfix user=postfix host=/var/lib/mysql/mysql.sock password=YourPassword
password_query = SELECT password FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT concat('/mail/', maildir) as home, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = '%u' AND active = '1'
参考までに発行されるクエリを実際にMySQLで叩いてみました。メール配送時にどのようなレコードを取得しているかよくわかりますね。
mysql> SELECT concat('/mail/', maildir) as home, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = 'testuser@test01.com';+----------------------------+------+------+
| home | uid | gid |
+----------------------------+------+------+
| /mail/test01.com/testuser/ | 5000 | 5000 |
+----------------------------+------+------+
1 row in set (0.00 sec)mysql> SELECT password FROM mailbox WHERE username = 'testuser@test01.com';
+------------------------------------+
| password |
+------------------------------------+
| $1$4dc08f18$LwbAjclR/irDpJA/2SVlk. |
+------------------------------------+
1 row in set (0.00 sec)
 
■証明書ファイルを設置
Postfixと同一のパスを指定しておきます。
//config Backup
cp -a /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.default
vi /etc/dovecot/conf.d/10-ssl.conf

//下記SSL設定パラメータを書き換える。
[root@postfix-master ~]# diff /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.default
ssl_cert = </etc/pki/dovecot/certs/mail2016.crt
ssl_key = </etc/pki/dovecot/private/mail2016.key
■プロセス再起動
/etc/init.d/postfix restart
/etc/init.d/dovecot restart
/etc/init.d/dovecot start
(7)Apacheの設定
<マスターサーバ側のみで実行>
Postfix-adminを使用することでブラウザ経由で、メールユーザやドメインの設定を行うことができます。
ApacheはPostfix-adminが動作するためのWEBサーバとして使用します。特に難しい設定ではないですが、
管理情報を扱うページのため、アクセス制限や認証を設定したほうがベターですね。
 
■Apache exec-cgiを有効化、接続制限(ローカルネットワークのみ)を有効化
cp -a /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.default
vi /etc/httpd/conf/httpd.conf

//設置対象ディレクトリのディレクティブ内を変更、追加する。
<Directory "/var/www/html">
Options Indexes FollowSymLinks ExecCGI
order deny,allow
deny from all
allow from 10.24.96.0/24

//起動する。
/etc/init.d/httpd start
 

(8)Postfix-Adminの初期設定

<マスターサーバ側のみで実行>
 
■Postfix-adminの初期設定
//Config Backup , テンプレートへアクセス権限付与、
cp -a /var/www/html/postfixadmin/config.inc.php /var/www/html/postfixadmin/config.inc.php.default
chmod 777 /var/www/html/postfixadmin/templates_c/

//下記のように設定を書き換える。
[root@postfix-master ~]# diff /var/www/html/postfixadmin/config.inc.php /var/www/html/postfixadmin/config.inc.php.default
 
< $CONF['configured'] = true;
---
> $CONF['configured'] = false;
34c34
< $CONF['default_language'] = 'ja';
---
> $CONF['default_language'] = 'en';
86c86
< $CONF['database_password'] = 'YourPassword';
---
> $CONF['database_password'] = 'postfixadmin';
117c117
< $CONF['admin_email'] = 'taguchi@tagutagu.com';
---
> $CONF['admin_email'] = '';
148c148
< $CONF['dovecotpw'] = "/usr/bin/doveadm pw";
---
> $CONF['dovecotpw'] = "/usr/sbin/doveadm pw";
279,280c279,280
< $CONF['mailboxes'] = ‘0';
< $CONF['maxquota'] = ‘0';
---
> $CONF['mailboxes'] = '10';
> $CONF['maxquota'] = '10';
285c285
< $CONF['quota'] = 'yes';
---
> $CONF['quota'] = 'NO';
ブラウザでsetup画面へアクセス。(http://10.24.96.120/postfixadmin/setup.php)
セットアップパスワードはコンフィグに記載する。
stup
 
セットアップ後、ログインすると下記の画面が表示される。
setup2
 
 ■管理画面からアドレスを作る
setup3
 
setup4
 
■CSSファイルを編集(個人の好み、設定しなくても動きます。)
UIが個人的に小さすぎて見にくいのでCSSを編集してみます。(マーカー箇所)
画像は/var/www/html/postfixadmin/images/logo-default.pngを入れ替えました。
%e3%83%86%e3%82%99%e3%82%b5%e3%82%99%e3%82%a4%e3%83%b3
%e3%83%86%e3%82%99%e3%82%b5%e3%82%99%e3%82%a4%e3%83%b3%ef%bc%92
 
 
 
[root@gmail01 ~]# cat /var/www/html/postfixadmin/css/default.css
@import url(calendar.css);
body {
background: #ffffff;
color: #000000;
font-family:'Lucida Grande','Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', Meiryo, メイリオ, sans-serif;
font-size: 13px;
font-weight: normal;
text-align: left;
}#container {
width:970px;
margin:auto;
}
a {
text-decoration: none;
color: #888888;
}a:hover {
text-decoration: underline;
color: #888888;
}

a:visited, a:active {
color: #888888;
}

table {
/* border-spacing: 0; */
/* padding: 0; */
border-collapse: collapse; /* for IE */
text-align: left;
}

input, .button, textarea {
padding: 6px;
}

input, .button, textarea, select {
font-family: "BitStream Vera Sans", Verdana, Arial, Helvetica, sans-serif;
font-size: 13px;
}

.readonly {
background:#eee;
}

.button {
background: -moz-linear-gradient(top,#BFD9E5, #3D95B7 50%,#0080B3 50%,#0099CC);
background: -webkit-gradient(linear, left top, left bottom, from(#BFD9E5), color-stop(0.5,#3D95B7), color-stop(0.5,#0080B3), to(#0099CC));
color: #FFF;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border: 1px solid #0099CC;
-moz-box-shadow: 1px 1px 1px rgba(000,000,000,0.3),inset 0px 0px 3px rgba(255,255,255,0.5);
-webkit-box-shadow: 1px 1px 1px rgba(000,000,000,0.3),inset 0px 0px 3px rgba(255,255,255,0.5);
text-shadow: 0px 0px 3px rgba(0,0,0,0.5);
padding: 3px 3px 3px 3px;
font-family:'Lucida Grande','Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', Meiryo, メイリオ, sans-serif;
}

.button:hover, .button:focus {
background: #eee;
color: #666;
text-decoration:none;
}

.flat {
border: 1px solid #888888;
}

ul.flash-info {
border:2px solid #AFE1A6; /* medium green */
padding:1em;
max-width:970px;
margin-left:auto;
margin-right:auto;
list-style:none;
}

ul.flash-error {
border:2px solid #FF6347; /* tomato */
padding:1em;
max-width:970px;
margin-left:auto;
margin-right:auto;
list-style:none;
}

.error_msg {
color: #d01313;
}

#motd {
color: maroon;
padding-top:2em;
}

.standout {
color: maroon;
padding: 3px 3px 3px 3px;
text-align: center;
}

#login_header, #login, #main_menu, #overview,
#admin_domains, #admin_virtual, .nav_bar, #alias_domain_table,
#alias_table, #mailbox_table, #overview_table, #log_table,
#admin_table, #footer, .subnav {
width: 990px;
margin: 0 auto;
font-size: 5px;
}

#login_header {
padding-bottom: 10px;
text-align: left;
}

#login {
width: 970px;
margin: 0 auto;
background: url(../images/mail_bg.gif) right 50% no-repeat;
}

#login_table {
border-left: none;
border-right: 1px solid #999;
width: 400px;
margin: 0 0 0 200px;
border-collapse: separate;
border-spacing: 10px;
}

#login_table h4 {
font-size: 13px;
}

#menu, #tabbar {
text-align:center;
float:left;
width:100%;
margin: 0 auto;
padding-top: 10px;
white-space: nowrap;
}

#menu ul, #tabbar ul {
padding: 0;
margin: 0;
margin-left:auto;
margin-right:auto;
list-style: none;
text-align: center;
position:relative;
width:990px;
float:left;

}

#menu li, #tabbar li {
background: linear-gradient(#dcffff, #4ffffd);
float: left;
/*background: #efefef; */
margin-right: 3px;
border-top: 4px solid #aaaaaa;
position:relative;
}

#menu li:hover, #menu li.sfhover, #tabbar li:hover, #tabbar li.sfhover {
/* background: #ccc; */
background: linear-gradient(to bottom, #02b0e6 0%, #99dff5 0%);
}

#menu li ul, #tabbar li ul {
position: absolute;
width: auto;
left: -999em;
right:auto;
background: #FFFFFF;
color: #999999;
border:2px solid white;
border-top:none;
}

#menu li:hover ul, #menu li.sfhover ul, #tabbar li:hover ul, #tabbar li.sfhover ul {
left: auto;
}

#menu li ul li, #tabbar li ul li {
float: none;
margin-right: 0px;
border-top:2px solid white;
text-align:left;
right:auto;
}

#menu a, #tabbar a {
display: block;
width: auto;
padding: 20px 5px 5px 5px;
}

#menu a, #tabbar a, #menu a:hover, #tabbar a:hover {
color: #888888;
}

#menu li ul li a, #tabbar li ul li a {
padding: 5px 5px 5px 5px;
}

.subnav p {
padding-left:10px;
margin-top:2em;
margin-bottom:0;
font-size:12px;
}

#edit_form table {
margin: 0 50px;
padding-top: 10px;
text-align: left;
}

#edit_form th {
text-align: left;
font-size: 12px;
margin: 0;
line-height: 25px;
}

.hlp_center {
text-align: center;
}

.help_text {
text-align: center;
padding-top: 5px;
padding-bottom: 5px;
}

#main_menu table {
margin: 0 0;
text-align: left;
padding-top: 20px;
padding-bottom: 20px;
}

#main_menu table td {
padding-left: 30px;
padding-bottom: 5px;
}

#main_menu a {
padding-left: 8px;
}

#main_menu a:hover {
color: #333;
text-decoration: none;
padding-left: 4px;
border-bottom: none;
border-left: 4px solid #333;
}

#overview h4, #overview P, #overview FORM, #admin_virtual h4, #admin_virtual P, #admin_virtual FORM {
display: inline;
padding-right: 10px;
line-height: 30px;
}

#alias_domain_table .header, #alias_table .header, #mailbox_table .header, #overview_table .header, #log_table .header, #admin_table .header {
line-height: 20px;
background: #efefef;
color: black;
}

#alias_domain_table h3, #alias_table h3, #mailbox_table h3, #overview_table h3, #log_table h3, #admin_table h3 {
text-align: left;
font-size: 12px;
font-weight: bold;
padding-left: 20px;
line-height: 25px;
margin: 0;
}

#alias_domain_table .hilightoff, #alias_table .hilightoff, #mailbox_table .hilightoff, #overview_table .hilightoff, #log_table .hilightoff, #admin_table .hilighoff {
background: white;
}

#alias_domain_table .hilighton, #alias_table .hilighton, #mailbox_table .hilighton, #overview_table .hilighton, #log_table .hilighton, #admin_table .hilighton {
background: #eee; /*#D6FF85;*/ /*#ffdddd;*/
}

#alias_domain_table tr:hover, #alias_table tr:hover, #mailbox_table tr:hover, #overview_table tr:hover, #log_table tr:hover, #admin_table tr:hover {
background: #eee; /*#D6FF85;*/ /*#ffdddd;*/
}

th {
text-align: center;
padding:7px 0;
margin: 0 0 14px 0;
border-bottom: 1px solid #bbb;
color: #555555;
}

td {
padding:7px 7px;
}

td.label {
text-align:right;
margin-right:0px;
}

label {
padding-right:0;
font-weight:bold;
vertical-align:middle;
}

#alias_domain_table td, #alias_table td, #mailbox_table td, #overview_table td, #log_table td, #admin_table td {
text-align: left;
}

#footer {
width:975px;
margin: 20px auto;
border-top: 1px solid #bbbbbb;
background: #efefef;
color: #999999;
line-height: 20px;
text-align: left;
padding-left: 15px;
font-size: 9px;
}

#footer a {
text-decoration: none;
color: #999999;
}

#footer a:hover {
text-decoration: underline;
color: #777777;
}

div.setup {
width:700px;
margin-left:auto;
margin-right:auto;
text-align: left;
}

div.setup li {
padding-bottom:1em;
}

.searchresult {
background:lightgreen;
}

span.active {
font-weight:bold;
}

div.nav_bar {
text-align: left;
}
.quota {
z-index:99;
height:14px;
position: absolute;
}
.quota_text {
z-index:100;
text-align: center;
font-size: 10px;
color: #666;

cursor: default;
position: absolute;
width:120px;
height:14px;
margin-top:-14px;
}
.quota_bg { background-color: white; z-index:98; width:120px; height:14px;margin-top:-1px;margin-left:-1px; border: 1px solid #999;}
.quota_high { background: url(../images/quota-colors.png) repeat-x 0 -28px #f90509; }
.quota_mid { background: url(../images/quota-colors.png) repeat-x 0 -14px #e3e909; }
.quota_low { background: url(../images/quota-colors.png) repeat-x 0 0px #05f905; }
.quota_text_high { color: white; }
.quota_text_mid { color: #666; }
.quota_text_low { color: #666; }

(9)マスターサーバの動作テスト

■メール送信テスト
メールボックスにメールが作成されていればOK.....
echo "test" | mail -s "test" hogehoge@tagutagu02.com
root@gmail01 ~]# ll /mail/test01.com/testuser/new/
合計 1
-rw------- 1 5000 5000 502 10月  7 22:56 2016 1475848566.V13Ia2d483dd21bbe46cM843374.gmail01.com
(10)スレーブサーバの設定
ここまでの設定はほとんどマスターサーバ側で行っていたので、今度はスレーブサーバ側に必要な設定をまとめて行います。
 
■設定ファイルのコピー
<スレーブサーバ側で実行>
//マスター側からPostfixとDovecotのファイルを持ってくる。
scp -rp 10.24.96.120:/etc/postfix /root/
scp -rp 10.24.96.120:/etc/dovecot /root/
mv /etc/postfix /etc/postfix.default
mv /etc/dovecot /etc/dovecot.default
cp -a /root/dovecot/ /etc/
cp -a /root/postfix /etc/
//証明書ファイルのコピー
scp 10.24.96.121:/etc/pki/tls/certs/mail2016.crt /etc/pki/tls/certs/mail2016.crt
scp 10.24.96.121:/etc/pki/tls/private/mail2016.key /etc/pki/tls/private/mail2016.key

(11)HAproxyのインストール・設定

L4ロードバランサー代わりのHAproxyを作成します。
■インストール
yum install haproxy
chkconfig haproxy stop

■設定ファイルを編集します。
vi /etc/haproxy/haproxy.cfg

//defaultセクションのmodeをhttpからTCPに書き換える
defaults
 mode tcp

//追記する。
frontend 587_smtp
 bind 0.0.0.0:587
 default_backend 587_backend_postfix

backend 587_backend_postfix
 balance roundrobin
 mode tcp
 server gmail01.com 10.24.96.120:587 check
 server gmail02.com 10.24.96.121:587 check

frontend 25_smtp
 bind 0.0.0.0:25
 default_backend 25_backend_postfix

backend 25_backend_postfix
 balance roundrobin
 mode tcp
 server gmail01.com 10.24.96.120:25 check
 server gmail02.com 10.24.96.121:25 check


frontend 110_smtp
 bind 0.0.0.0:110
 default_backend 110_backend_postfix

backend 110_backend_postfix
 balance roundrobin
 mode tcp
 server gmail01.com 10.24.96.120:110 check
 server gmail02.com 10.24.96.121:110 check

frontend 143_smtp
 bind 0.0.0.0:143
 default_backend 143_backend_postfix

backend 143_backend_postfix
 balance roundrobin
 mode tcp
 server gmail01.com 10.24.96.120:143 check
 server gmail02.com 10.24.96.121:143 check

frontend 993_smtp
 bind 0.0.0.0:993
 default_backend 993_backend_postfix

backend 993_backend_postfix
 balance roundrobin
 mode tcp
 server gmail01.com 10.24.96.120:993 check
 server gmail02.com 10.24.96.121:993 check

frontend 995_smtp
 bind 0.0.0.0:995
 default_backend 995_backend_postfix

backend 995_backend_postfix
 balance roundrobin
 mode tcp
 server gmail01.com 10.24.96.120:995 check
 server gmail02.com 10.24.96.121:995 check

//起動・リッスン確認
/etc/init.d/haproxy restart

[root@haproxy01 ~]# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1244/sshd
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 0.0.0.0:995 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 0.0.0.0:9102 0.0.0.0:* LISTEN 1254/bacula-fd
tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN 1638/haproxy
tcp 0 0 :::22 :::* LISTEN 1244/sshd

 
以上でひととおりの設定が終了しました。
VIPに対して設定を行いメールソフトで正常に送受信ができることを確認してみましょう。
参考までにThunderbirdの設定を貼っておきます。
 
mailset2
mailset1
 
長かった。。。
以上です :)

Copyright © 2021 たぐたぐ.com. All rights reserved.