dovecotの認証にmysqlを使った時、ログインのクエリを1つにする
メールサーバ立てるぞ。
環境
dovecot --version 2.2.18
dovecotというimapサーバの認証にmysqlを使う場合、そのままだとpasswordとユーザ名を取得するクエリを別々で投げるんだけど、設定すれば1クエリで押さまるらしい。
http://www.dovecot.jp/doc/dovecot-sql-example.conf, http://www.dovecot.jp/wiki/UserDatabase.Prefetch.txt にある翻訳されてる情報は1系だけどは2系とほとんど同じみたい。
/etc/dovecot/conf.d/auth-sql.conf.ext
userdb { driver = sql args = /etc/dovecot/dovecot-sql.conf.ext }
をアンコメントして,
password_query のgid, home, uidというcolun_nameにuserfhdb_というプレフィックスをつけておしまし。
before
SELECT name as user, domain, password, CONCAT("/home/virtual/", dir) as home, '5000' as uid, '5000' as gid FROM anonymous_mailboxes WHERE name = 'koji' AND domain = 'hoge.com' SELECT CONCAT("/home/virtual/", dir) as home, '5000' as uid, '5000' as gid FROM anonymous_mailboxes WHERE name = 'koji' AND domain = 'hoge.com'
after
SELECT name as user, domain, password, CONCAT("/home/virtual/", dir) as userdb_home, '5000' as userdb_uid, '5000' as userdb_gid FROM anonymous_mailboxes WHERE name = 'koji' AND domain = 'hoge.com'
になりました。
次はクォーターあたりやります。
imapログインした時にメールのルートディレクトリはどこを見ているか
maildirに配送したというログがあるのに、telnetからimapログインしたけど受け取っているはずのメールがなかった。
調べた結果、imapログインした時に見ているメールのルートディレクトリが別のところみてた。(x select inboxするとmaildir一式作成するんだね...)
環境
imapログインした時に見ているメールのルートディレクトリは、/etc/dovecot/dovecot-sql.conf.ext の usedb に書いている homeカラムかと思ったら
/etc/dovecot/conf.d/10-mail.conf にある mail_location を見ていたのでした。
なのでpostfixが配送しているディレクトリがdovcotからルートディレクトリになるようmail_locationを変更します。
mail_location = maildir:/home/virtual/%d/%n
(userdbではuidとgidだけ返せばいいってことっぽい。)
ちなみに/etc/postfix/vmailbox.mysql
query = select CONCAT(domain, '/', name, '/') from anonymous_mailboxes where name = '%u' AND domain = '%d'
公式ドキュメントを眺めた
http://wiki2.dovecot.org/VirtualUsers/Home
homeカラムではなくてmailカラムにルートディレクトリのパスを返していればmail_locationを上書きしてくれるっぽい。
とりあえず、今の環境では特異なディレクトリ名になることはないのでmail_locationに直書きでいいや。
# userdb query to retrieve the user information. It can return fields: # uid - System UID (overrides mail_uid setting) # gid - System GID (overrides mail_gid setting) # home - Home directory # mail - Mail location (overrides mail_location setting)
postgresqlと複合indexとiowait
rails4.2.0
muninを見ているとぺろぺろあんてなのサーバでiowaitが徐々に増えていることに気がついてスロークエリを探しました。
最近https://twitter.com/prprantena に1時間起きで取り込んだ記事を垂れ流すようにしたのでそのネットワークioかと思ったんですが、日々増えているのでDBあたりかなと思って、スロークエリをログに書き出す設定を有効にしてログ見てました。
# /etc/postgresql/9.4/main/postgresql.conf log_min_duration_statement = 500
遅いクエリでてきました。
SELECT "word_tags"."name" FROM "word_tags" INNER JOIN "word_taggings" ON "word_tags"."id" = "word_taggings"."word_tag_id" WHERE "word_taggings"."post_id" = $1 [["post_id", 245009]]
explainするとpost_id の検索でindexが使われていないことが発覚。
2.1.1 :004 > Post.first.word_tags.explain => EXPLAIN for: SELECT "word_tags".* FROM "word_tags" INNER JOIN "word_taggings" ON "word_tags"."id" = "word_taggings"."word_tag_id" WHERE "word_taggings"."post_id" = $1 [["post_id", 243762]] QUERY PLAN --------------------------------------------------------------------------------------- Nested Loop (cost=0.29..33102.66 rows=51 width=19) -> Seq Scan on word_taggings (cost=0.00..32710.34 rows=51 width=4) Filter: (post_id = 243762) -> Index Scan using word_tags_pkey on word_tags (cost=0.29..7.68 rows=1 width=19) Index Cond: (id = word_taggings.word_tag_id) (5 rows)
db/schema.rb を見るとindexを貼った痕跡ある。
add_index "word_taggings", ["post_id"], name: "index_word_taggings_on_post_id", using: :btree add_index "word_taggings", ["word_tag_id", "post_id"], name: "index_word_taggings_on_word_tag_id_and_post_id", using: :btree add_index "word_taggings", ["word_tag_id"], name: "index_word_taggings_on_word_tag_id", using: :btree
psql からindexが貼られているかの確認すると、post_id と word_tag_id にindexがなかった( ;´Д`)
antena_development=# \d index_word_taggings_on_post_id Did not find any relation named "index_word_taggings_on_post_id".
複合index使っていないっぽいので削除して、改めて単一indexをつけました。
class RemoveIndexWordTaggingsOnWordTagIdAndPostId < ActiveRecord::Migration def up remove_index :word_taggings, name: :index_word_taggings_on_word_tag_id_and_post_id # 複合 add_index "word_taggings", ["post_id"], name: "index_word_taggings_on_post_id", using: :btree add_index "word_taggings", ["word_tag_id"], name: "index_word_taggings_on_word_tag_id", using: :btree end def down add_index "word_taggings", ["word_tag_id", "post_id"], name: "index_word_taggings_on_word_tag_id_and_post_id" remove_index :word_taggings, name: :index_word_taggings_on_post_id remove_index :word_taggings, name: :index_word_taggings_on_word_tag_id end end
これでiowait減りそうです。
=> EXPLAIN for: SELECT "word_tags".* FROM "word_tags" INNER JOIN "word_taggings" ON "word_tags"."id" = "word_taggings"."word_tag_id" WHERE "word_taggings"."post_id" = $1 [["post_id", 243762]] QUERY PLAN ------------------------------------------------------------------------------------------------------------ Nested Loop (cost=0.72..455.48 rows=51 width=19) -> Index Scan using index_word_taggings_on_post_id on word_taggings (cost=0.43..63.16 rows=51 width=4) Index Cond: (post_id = 243762) -> Index Scan using word_tags_pkey on word_tags (cost=0.29..7.68 rows=1 width=19) Index Cond: (id = word_taggings.word_tag_id) (5 rows)
複合indexをつけると包括しているキーにはindex貼らない仕様?そもそも複合indexは不要?add_indexのmigrationで単一はindexが貼られなかった?かは不明。
とりあえずpostgresqlよくわからん( ;´Д`)
virtual_alias_maps と virtual_mailbox_maps
postfix で virtual_alias_maps で @example.jp があると、virtual_mailbox_maps に foo@example.jp があっても先に @example.jp に引っかかってしまい foo@example.jp の mailbox に辿り着かなくて悩んだ件。
以下の設定だと、 hoge1234@prpr-antena.com へメール送るとlocalがmail_userに配送(.forwardが発火)するだけで`prpr-antena.com/hoge1234/`にあるmaildirには配送してくれない。
メール受信した時に何か処理を実行したいってことなんだけど、今の状況だと肝心のメールが受信できていない状況。
# /etc/postdix/main.cf virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_alias_maps = hash:/etc/postfix/virtual mydestination = localhost
# /etc/postfix/virtual hoge1234@prpr-antena.com mail_user@localhost
# /etc/postfix/vmailbox hoge1234@prpr-antena.com prpr-antena.com/hoge1234/
virtual_alias_maps でマッチする(不適切な表現っぽい)ものがあると、virtual_mailbox_maps は参照しないらしいので、↑のようなことになっているとのこと。
どうやらvirtual_alias_maps にキーと同じ値を入れておけば、ループしないよう(?)に virtual_mailbox_maps を参照してくれるらしい。
# /etc/postfix/virtual hoge1234@prpr-antena.com mail_user@localhost, hoge1234@prpr-antena.com
できました。
rails generatorを自作
いつも同じことしているので作ってみた。
https://github.com/jiikko/admin_generator
generatorのシンタックスがシンプルなので量産できそう。
$ bundle exec rails g admin_generator:admin install gemfile sorcery exist app/controllers create app/controllers/admin/base_controller.rb create app/controllers/admin/home_controller.rb create app/controllers/admin/sessios_controller.rb exist app/views create app/views/admin/home/index.html.slim create app/views/admin/sessions/new.html.erb generate sorcery:install create config/initializers/sorcery.rb generate model User --skip-migration invoke active_record create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb insert app/models/user.rb create db/migrate/20150710150000_sorcery_core.rb generate sorcery:install gsub config/initializers/sorcery.rb insert app/models/user.rb create db/migrate/20150710150002_sorcery_activity_logging.rb create db/migrate/20150710150003_sorcery_brute_force_protection.rb route namespace :admin do root 'home#index' end
毎回作っているローカル用のunicorn.conf.rbとかのgenerator作れば楽できそうと思った。とても眠い。
routeのネストってできないのかな。
バーチャルドメインで受け取ったメールをコマンドに渡す
歌丸です。
$ postconf | grep versio mail_version = 2.11.3
# /etc/postfix/virtual root@jiikko.com deployer@localhost root@prpr-antena.com deployer@localhost
# /etc/postfix/main.cf virtual_mailbox_domains = prpr-antena.com, jiikko.com virtual_mailbox_base = /home/virtual virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_minimum_uid = 5000 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_alias_maps = hash:/etc/postfix/virtual mydestination = localhost
# /etc/aliases deployer: "| mail hoge@icloud.com"
ミソはmydestinationにlocalhostを指定するところ。
mydestinationを指定すると外に配送しないでローカルに配送してくれる。
なんでlocalhostを指定しているかというと。
/etc/postfix/virtualで
root@prpr-antena.com deployer
と書くと
root@prpr-antena.com deployer@prpr-antena.com
と解釈されているらしくunknown userになった。なのでlocalhostを指定してる。
命名めんどくない?
https://github.com/zdennis/activerecord-import/blob/master/lib/activerecord-import/import.rb
https://github.com/zdennis/activerecord-import/blob/master/lib/activerecord-import/active_record/adapters/mysql2_adapter.rb
./lib/activerecord-import/import.rb に ActiveRecord::Import::Import というクラスを定義してなかったり、ネームスペースとディレクトリ階層を合わせていないっぽい。
autoloadに頼っていないとしてもクラス名とファイルは同じにしたほうがよくない?
たまにファイル探すのめんどくない?
ディレクトリ名とネームスペースを別々で命名するのめんどくない?