ã“れ㯠Postfix Advent Calendar 2014 ã®15æ—¥ã‚ã®è¨˜äº‹ã§ã™ã€‚
Postfix Advent Calendar 2014 - Qiita
ルックアップテーブル
Postfix ã®ãƒ«ãƒƒã‚¯ã‚¢ãƒƒãƒ—テーブル㯠Linux ã ã¨é€šå¸¸ã¯ hash å½¢å¼ã®ãƒ•ァイルã§ã™ãŒã€ãƒ•ァイルã®ä»£ã‚り㫠MySQL, PostgreSQL, LDAP ç‰ã‚’å‚ç…§ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
ã©ã®å½¢å¼ãŒä½¿ãˆã‚‹ã‹ã¯ postconf -m
コマンドã§ä½¿ç”¨ã§ãã‚‹å½¢å¼ã®ä¸€è¦§ã‚’見るã“ã¨ãŒã§ãã¾ã™ã€‚Ubuntu ã ã¨æ¬¡ã®ã‚ˆã†ã«ãªã£ã¦ã¾ã™ã€‚
% postconf -m btree cidr environ fail hash internal memcache nis proxy regexp sdbm socketmap sqlite static tcp texthash unix
Ubuntu ã§ã¯ deb ã§å¯¾å¿œå½¢å¼ã‚’è¿½åŠ ã§ãるよã†ã«ãªã£ã¦ã„ã¾ã™ã€‚
% sudo apt-get install postfix-cdb postfix-ldap postfix-mysql postfix-pcre postfix-pgsql ... % postconf -m btree cdb cidr environ fail hash internal ldap memcache mysql nis pcre pgsql proxy regexp sdbm socketmap sqlite static tcp texthash unix
ã‚ã¨ã‹ã‚‰è¿½åŠ ã§ãã‚‹ã®ã¯ Ubuntu(Debian?)ã®ç‹¬è‡ªæ‹¡å¼µã§ã€é€šå¸¸ã¯ã‚³ãƒ³ãƒ‘ã‚¤ãƒ«æ™‚ã«æŒ‡å®šã—ãŸã‚‚ã®ã—ã‹ä½¿ãˆã¾ã›ã‚“。 CentOS ã®å ´åˆã¯ mysql ã¯ã‚りã¾ã™ãŒã€pgsql(PostgreSQL) ã¯ã‚りã¾ã›ã‚“。Postfix をコンパイルã—ç›´ã•ãªã„é™ã‚Šã€ã‚ã¨ã§è¿½åŠ ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“。
% postconf -m btree cidr environ fail hash internal ldap memcache mysql nis pcre proxy regexp socketmap static tcp texthash unix
MySQL
ルックアップテーブルã¯ã€ã‚る値(ã‚ー)を与ãˆã‚‹ã¨ãれã«å¯¾å¿œã™ã‚‹å€¤ã‚’è¿”ã™ãƒ†ãƒ¼ãƒ–ルã§ã€*_maps
ã¨ã„ã†åå‰ã®ãƒ‘ラメータやã€smtpd_*_restrictions
ã«æŒ‡å®šã™ã‚‹ã‚¢ã‚¯ã‚»ã‚¹åˆ¶å¾¡ã§ä½¿ç”¨ã•れã¾ã™ã€‚
ãŸã¨ãˆã° alias_maps
パラメータ㧠MySQL ã‚’å‚ç…§ã—ãŸã„å ´åˆã¯æ¬¡ã®ã‚ˆã†ã«æŒ‡å®šã—ã¾ã™ã€‚
[main.cf]
alias_maps = mysql:/etc/postfix/alias.mysql
/etc/postfix/alias.mysql
ファイルã«ã¯ MySQL æŽ¥ç¶šç”¨ã®æƒ…å ±ã¨ã‚¯ã‚¨ãƒªã‚’記述ã—ã¾ã™ã€‚
[hoge.mysql]
hosts = mysql_server user = mysql_user password = user_password dbname = some_db query = select result from alias_table where name='%s'
ã“ã®ä¾‹ã§ã¯ã€æ¤œç´¢ã‚ー㌠alias_table ã® name カラムã«ä¸€è‡´ã—ãŸã‚‰ result カラムã®å€¤ã‚’è¿”ã—ã¾ã™ã€‚
%s
内㮠'
ã‚„ "
ã¯ã¡ã‚ƒã‚“ã¨ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã•れるã®ã§ã€SQL インジェクションã«ã¤ã„ã¦ã¯æ°—ã«ã—ãªãã¦ã‚‚大丈夫ã§ã™ã€‚
クエリãŒè¤‡æ•°ã‚«ãƒ©ãƒ や複数レコードを返ã™å ´åˆã¯ã€,
ã§çµåˆã•れã¦è¿”りã¾ã™ã€‚
my.cnf
Postfix 2.11 ã‹ã‚‰ my.cnf ã‚„ä»–ã®ãƒ•ァイルをèªã‚€ã“ã¨ãŒã§ãるよã†ã«ãªã‚Šã¾ã—ãŸã€‚
option_group = group option_file = /etc/postfix/mysql.cnf
option_file
㯠my.cnf ファイルã®ä»£ã‚りã«èªã¿è¾¼ã‚€ãƒ•ァイルåを指定ã—ã¾ã™ã€‚
option_group
㯠cnf ファイルä¸ã®ã‚°ãƒ«ãƒ¼ãƒ—を指定ã—ã¾ã™ã€‚
option_file
ã‚‚ option_group
も指定ã•れãªã„å ´åˆã¯ã€my.cnf ã‚‚èªã¿è¾¼ã¾ã‚Œã¾ã›ã‚“。
ã“れを使用ã™ã‚‹ã“ã¨ã§ã€default-character-set
ã‚„ init-command
ç‰ã® MySQL ã®è‰²ã‚“ãªã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæŒ‡å®šã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
charset
Postfix ã‹ã‚‰ MySQL ã¸ã®æŽ¥ç¶šã® charset 㯠Ubuntu ã§ã¯ãƒ‡ãƒ•ォルト㯠latin1 ã«ãªã£ã¦ã„ã¾ã™ã€‚
試ã—ã¦ã¿ã¾ã™ã€‚
[/tmp/hoge.mysql]
hosts = localhost user = test password = abcdefg dbname = test query = show variables like 'character_set_connection'
% postmap -q hoge mysql:/tmp/hoge.mysql character_set_connection,latin1
上述ã—ãŸã‚ˆã†ã« Postfix 2.11 ã§ã¯ my.cnf ã‚’èªã¾ã›ã‚‹ã“ã¨ãŒã§ãã‚‹ã®ã§ã€my.cnf ã§ default-character-set
ã‚’è¨å®šã™ã‚Œã°ãれã«å¾“ã„ã¾ã™ã€‚
[/tmp/hoge.mysql]
hosts = localhost user = test password = abcdefg dbname = test query = show variables like 'character_set_connection' option_group = hoge
[/etc/mysql/my.cnf]
[hoge] default-character-set = utf8mb4
% postmap -q hoge mysql:/tmp/hoge.mysql character_set_connection,utf8mb4
Postfix 2.11 未満ã§ã¯ my.cnf ã‚’èªã‚€ã“ã¨ãŒã§ããªã„ã®ã§ã€charset を指定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
接続用㮠charset ãŒã‚«ãƒ©ãƒ ã® charset ã¨ç•°ãªã‚‹å ´åˆã€ã‚¯ã‚¨ãƒªãŒã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚
ãŸã¨ãˆã°ã€ascii ã®ã‚«ãƒ©ãƒ ã«ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒæ ¼ç´ã•れã¦ã„ã‚‹å ´åˆã€æŽ¥ç¶šãŒ latin1 ã 㨠8bit æ–‡å—ã‚’ã‚¯ã‚¨ãƒªã«æ¸¡ã™ã¨ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã™ã€‚
[/tmp/virtual_alias.mysql] *1
hosts = 127.0.0.1 user = test password = abcdefg dbname = test query = select address from alias where alias='%s'
[main.cf]
virtual_alias_maps = mysql:/tmp/virtual_alias.mysql
[SMTP]
MAIL FROM:<hoge> 250 2.1.0 Ok RCPT TO:<ã»ã’> rcpt to:<ã»ã’@example.com> 451 4.3.0 < @example.com>: Temporary lookup failure
[mail.log]
Dec 15 02:51:38 x220 postfix/smtpd[9860]: connect from localhost[127.0.0.1] Dec 15 02:51:48 x220 postfix/smtpd[9860]: warning: mysql query failed: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' Dec 15 02:51:48 x220 postfix/smtpd[9860]: warning: mysql:/tmp/virtual_alias.mysql lookup error for "??????@example.com" Dec 15 02:51:48 x220 postfix/smtpd[9860]: NOQUEUE: reject: RCPT from localhost[127.0.0.1]: 451 4.3.0 < @example.com>: Temporary lookup failure; from=<hoge> to=<??????@example.com> proto=SMTP Dec 15 02:51:52 x220 postfix/smtpd[9860]: disconnect from localhost[127.0.0.1]
Postfix ã¯ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã®ãƒãƒ¼ã‚«ãƒ«ãƒ‘ート㫠8bit æ–‡å—ãŒã‚ã£ã¦ã‚‚エラーã«ã¯ã›ãšã€ãã®ã¾ã¾å‡¦ç†ã‚’行ãŠã†ã¨ã—ã¾ã™*2。ãã®ãŸã‚ ascii カラム㨠latin1 リテラルを比較ã—よã†ã¨ã—㦠MySQL エラーã«ãªã£ã¦ã—ã¾ã„ã¾ã™ã€‚
クエリを次ã®ã‚ˆã†ã«å¤‰æ›´ã™ã‚‹ã¨ã€ãƒªãƒ†ãƒ©ãƒ«ã‚’強制的㫠ascii ã¨ã¿ãªã™ã‚ˆã†ã«ãªã‚‹ãŸã‚ã€MySQL エラーã«ã¯ãªã‚Šã¾ã›ã‚“。
[/tmp/virtual_alias.mysql]
query = select address from alias where alias=_ascii'%s'
[SMTP]
RCPT TO:<ã»ã’@example.com> 550 5.1.1 < @example.com>: Recipient address rejected: example.com
[mail.log]
Dec 15 02:53:13 x220 postfix/smtpd[10080]: connect from localhost[127.0.0.1] Dec 15 02:53:21 x220 postfix/smtpd[10080]: NOQUEUE: reject: RCPT from localhost[127.0.0.1]: 550 5.1.1 < @example.com>: Recipient address rejected: example.com; from=<hoge> to=<??????@example.com> proto=SMTP Dec 15 02:53:23 x220 postfix/smtpd[10080]: disconnect from localhost[127.0.0.1]
一旦 Temporary lookup failure ã®ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ã¨ã€ã—ã°ã‚‰ãエラーã®çŠ¶æ…‹ãŒè¨˜æ†¶ã•れã¦ã—ã¾ã†ãŸã‚ã€ãã®å¾Œã®ã‚¯ã‚¨ãƒªã‚‚エラーã«ãªã£ã¦ã—ã¾ã„ã¾ã™ã€‚
MySQL を使用ã™ã‚‹å ´åˆã«ã¯æ³¨æ„ã—ã¾ã—ょã†ã€‚
*1:Ubuntu ã§ã¯ Postfix ã®ãƒ‡ãƒ¼ãƒ¢ãƒ³ã¯ chroot 下ã§å‹•作ã™ã‚‹ãŸã‚ã€MySQL ã® socket ファイルãŒè¦‹ã‚Œãªã„ã®ã§ã€localhost ã§ã¯ãªã 127.0.0.1 を指定ã—㦠TCP 接続を使用ã™ã‚‹ã‚ˆã†ã«ã—ã¦ã„ã¾ã™ã€‚
*2:ドメインパート㫠8bit æ–‡å—ãŒã‚る㨠SMTP エラーã«ãªã‚Šã¾ã™ã€‚
PlanetMySQL Voting: Vote UP / Vote DOWN