milter-managerの設定ファイルmilter-manager.confの書き方について説明します。
ここでは/usr/local/以下にインストールされたものとして説明します。configure時に–prefix=/usr/local/オプションを指定するか、–prefixオプションを省略した場合は/usr/local/以下にインストールされます。
この場合は、設定ファイルは/usr/local/etc/milter-manager/milter-manager.confになります。インストールが成功していれば、もうすでにファイルが存在するはずです。
設定ファイルの先頭は以下のようになっています。
# -*- ruby -*-
load("applicable-conditions/*.conf")
load_default
load_if_exist("milter-manager.local.conf")
通常は、この部分はそのままにしておき、milter-manager.confと同じディレクトリにmilter-manager.local.confというファイルを作成し、そのファイルに設定を記述します。
設定項目は以下のように分類されています。
このうち、適用条件関連とデータベース関連はRubyの知識が必要になります。S25Rなどの有用な適用条件は標準で提供されているので、必ずしも自分で適用条件を定義できる必要はありません。そのため、適用条件の説明は一番最後にあります。適用条件を定義する必要がない場合は、適用条件関連の部分は読み飛ばしても構いません。
それぞれ順に説明する前に、設定をする上で便利なmilter-manager機能を紹介します。milter-managerを–show-configオプションを付きで起動すると、現在の設定内容が表示されます。
% /usr/local/sbin/milter-manager --show-config
package.platform = "debian"
package.options = nil
security.privilege_mode = false
security.effective_user = nil
security.effective_group = nil
log.level = "default"
log.path = nil
log.use_syslog = true
log.syslog_facility = "mail"
manager.connection_spec = nil
manager.unix_socket_mode = 0660
manager.unix_socket_group = nil
manager.remove_unix_socket_on_create = true
manager.remove_unix_socket_on_close = true
manager.daemon = false
manager.pid_file = nil
manager.maintenance_interval = 10
manager.suspend_time_on_unacceptable = 5
manager.max_connections = 0
manager.custom_configuration_directory = nil
manager.fallback_status = "accept"
manager.fallback_status_at_disconnect = "temporary-failure"
manager.event_loop_backend = "glib"
manager.n_workers = 0
manager.packet_buffer_size = 0
manager.connection_check_interval = 0
manager.chunk_size = 65535
manager.max_pending_finished_sessions = 0
controller.connection_spec = nil
controller.unix_socket_mode = 0660
controller.remove_unix_socket_on_create = true
controller.remove_unix_socket_on_close = true
define_applicable_condition("S25R") do |condition|
condition.description = "Selective SMTP Rejection"
end
define_applicable_condition("Remote Network") do |condition|
condition.description = "Check only remote network"
end
この内容で設定内容を確認することができます。
また、この書式はそのまま設定ファイルの書式になっているので、設定の書き方を忘れたときにはこの内容をヒントにすることができます。
それでは、それぞれの分類毎に説明します。
package.platform = "pkgsrc"既定値:
package.platform = "debian" # 環境に依存
package.options = "prefix=/etc,name=value"既定値:
package.options = nil # 環境に依存
security.privilege_mode = true既定値:
security.privilege_mode = false
security.effective_user = "nobody"既定値:
security.effective_user = nil
security.effective_group = "nogroup"既定値:
security.effective_group = nil
1.6.6から使用可能。
log.level = "all" # すべてのログを出力既定値:
log.level = "default"
log.path = nil # 標準出力に出力 log.path = "/var/log/milter-manager.log" # ファイルに出力既定値:
log.path = nil
log.use_syslog = false # syslogに出力しない既定値:
log.use_syslog = true
log.syslog_facility = "local4" # LOG_LOCAL4を使う既定値:
log.syslog_facility = "mail"
manager.connection_spec = "unix:/var/run/milter/milter-manager.sock"既定値:
manager.connection_spec = "inet:10025@[127.0.0.1]"
manager.unix_socket_mode = 0600既定値:
manager.unix_socket_mode = 0660
manager.unix_socket_group = "nobody"既定値:
manager.unix_socket_group = nil
manager.remove_unix_socket_on_create = false既定値:
manager.remove_unix_socket_on_create = true
manager.remove_unix_socket_on_close = false既定値:
manager.remove_unix_socket_on_close = true
manager.daemon = true既定値:
manager.daemon = false
manager.pid_file = "/var/run/milter/milter-manager.pid"既定値:
manager.pid_file = nil
manager.maintenance_interval = nil既定値:
manager.maintenance_interval = 10
manager.suspend_time_on_unacceptable = 10既定値:
manager.suspend_time_on_unacceptable = 5
manager.max_connections = 10 # 同時に最大10接続のみ受け付ける既定値:
manager.max_connections = 0 # 制限無し
(子milter数 + 1) * 最大同時接続数 + 10(milter-manager内部で使用 + α)プロセスが開くことができるファイルディスクリプタ数はsetrlimit(2)でソフトリミットとハードリミットを変更します。 例:
manager.max_file_descriptors = 65535既定値:
manager.max_file_descriptors = 0
manager.custom_configuration_directory = "/tmp/milter-manager/"既定値:
manager.custom_configuration_directory = nil
manager.fallback_status = "reject"既定値:
manager.fallback_status = "accept"
manager.fallback_status_at_disconnect = "discard"既定値:
manager.fallback_status_at_disconnect = "temporary-failure"
manager.event_loop_backend = "libev"既定値:
manager.event_loop_backend = "glib"
manager.n_workers = 10既定値:
manager.n_workers = 0 # ワーカープロセスを使用しない
manager.packet_buffer_size = 4096 # 4KB溜まるまで送信しない。既定値:
manager.packet_buffer_size = 0 # バッファリングを無効にする。
manager.chunk_size = 4096 # 本文データを4KBずつ送る既定値:
manager.chunk_size = 65535 # 本文データを64KBずつ送る
# セッションが終了したら毎回すぐに終了処理を行う manager.max_pending_finished_sessions = 1既定値:
# なにも処理がないときのみセッションの終了処理を行う manager.max_pending_finished_sessions = 0
manager.use_netstat_connection_checker # 5秒間隔で確認 manager.use_netstat_connection_checker(1) # 1秒間隔で確認初期値:
確認しない
manager.connection_check_interval = 5 # 5秒間隔で確認既定値:
manager.connection_check_interval = 0
# ローカルネットワーク以外からの接続は強制的に切断したとみなす
manager.define_connection_checker("netstat-check") do |context|
context.smtp_client_address.local?
endMar 28 15:16:58 mail milter-manager[19026]: [statistics] [maintain][memory] (28048KB) total:6979 Proc:44 GLib::Object:18使用例:
manager.report_memory_statistics
manager.maintained do
Milter::Logger.info("maintained!")
endmanager.event_loop_created do |loop|
loop.add_timeout(1) do
Milter::Logger.info("timeout!")
true
end
endcontroller.connection_spec = "inet:10026@localhost"既定値:
controller.connection_spec = nil
controller.unix_socket_mode = 0600既定値:
controller.unix_socket_mode = 0660
controller.remove_unix_socket_on_create = false既定値:
controller.remove_unix_socket_on_create = true
controller.remove_unix_socket_on_close = false既定値:
controller.remove_unix_socket_on_close = true
子milterに関連する設定項目について説明します。
子milterは以下の書式で登録します。
define_milter("名前") do |milter|
milter.XXX = ...
milter.YYY = ...
milter.ZZZ = ...
end
例えば、「inet:10026@localhost」で接続待ちしているmilterを「test-milter」という名前で登録する場合は以下のようになります。
define_milter("test-milter") do |milter|
milter.connection_spec = "inet:10026@localhost"
end
define_milter do … end内で設定できる項目は以下の通りです。
必須の項目はmilter.connection_specだけです。
milter.connection_spec = "inet:10026@localhost"既定値:
milter.connection_spec = nil
milter.description = "test milter"既定値:
milter.description = nil
milter.enabled = false既定値:
milter.enabled = true
milter.fallback_status = "temporary-failure"既定値:
milter.fallback_status = "accept"
milter.evaluation_mode = true既定値:
milter.evaluation_mode = false
% /usr/local/sbin/milter-manager --show-config | grep define_applicable_condition
define_applicable_condition("S25R") do |condition|
define_applicable_condition("Remote Network") do |condition|
この場合は"S25R"と"Remote Network"が利用可能です。
適用条件は標準で提供されているだけではなく、独自に定義することもできます。定義方法については適用条件定義を見てください。ただし、独自に定義する場合にはRubyの知識が必要になります。
適用条件は以下のように「,」でくぎって複数指定できます。
milter.applicable_conditions = ["S25R", "Remote Network"]例:
milter.applicable_conditions = ["S25R"]既定値:
milter.applicable_conditions = []
milter.add_applicable_condition("S25R")milter.command = "/etc/init.d/milter-greylist"既定値:
milter.command = nil
milter.command_options = "start" milter.command_options = ["--option1", "--option2"]既定値:
milter.command_options = nil
milter.user_name = "nobody"既定値:
milter.user_name = nil
milter.connection_timeout = 60既定値:
milter.connection_timeout = 297.0
milter.writing_timeout = 15既定値:
milter.writing_timeout = 7.0
milter.reading_timeout = 15既定値:
milter.reading_timeout = 7.0
milter.end_of_message_timeout = 60既定値:
milter.end_of_message_timeout = 297.0
定義された子milterを操作するために便利な機能があります。ただし、これらの機能を利用するには多少Rubyの知識が必要になります。
定義されている子milter名の一覧を取得することができます。
define_milter("milter1") do |milter|
...
end
define_milter("milter2") do |milter|
...
end
defined_milters # => ["milter1", "milter2"]
これを利用することにより、すべての子milterの設定をまとめて変更するということが簡単にできるようになります。
以下はすべての子milterを無効にする例です。
defined_milters.each do |name|
define_milter(name) do |milter|
milter.enabled = false
end
end
以下はすべての子milterの定義を削除にする例です。無効にした場合と違い、再び子milterを使いたい場合は一から定義しなおす必要があります。
defined_milters.each do |name| remove_milter(name) end
以下はすべての子milterの適用条件にS25Rを追加する例です。
defined_milters.each do |name|
define_milter(name) do |milter|
milter.add_applicable_condition("S25R")
end
end
defined_milters # => ["milter1", "milter2"]
# "milter1"という名前で定義されたmilterの定義を削除
remove_milter("milter1")組み込みの適用条件を説明します。
この適用条件を使うと、MTAっぽいSMTPクライアントには子milterを適用せず、一般PCっぽいSMTPクライアントにのみ子milterを適用します。
以下の例では一般PCっぽいSMTPクライアントにのみGreylistingを適用することで、Greylistingによる遅延の悪影響を軽減しています。これはRgreyと呼ばれる手法です。(milter-greylistで"racl greylist default"と設定している場合)
使用例:
define_milter("milter-greylist") do |milter|
milter.add_applicable_condition("S25R")
end
SMTPクライアントが一般PCっぽいかどうかはS25Rの一般規則を用います。
S25Rの一般規則は一般PC以外のホストにもマッチしてしまいます。そのため、明示的にホワイトリストを設定して誤検出を防ぐことができます。デフォルトではgoogle.comドメインのホストとobsmtp.comドメインのホストはS25Rの一般規則にマッチしても子milterを適用しません。
また、逆にS25Rの一般規則に規則を追加して例外的なホスト名に対応することもできます。
S25R適用条件は以下の設定でカスタマイズできます。
s25r.add_whitelist(/\.google\.com\z/)mx.example.comというホストをホワイトリストに入れる場合は以下のようにします。
s25r.add_whitelist("mx.example.com")
[上級者向け] 複雑な条件を指定したい場合はブロックを指定することができます。ブロックにはホスト名が引数として渡されます。例えば、午前8:00から午後7:59までの間だけ.jpトップレベルドメインをホワイトリストに入れる場合は以下のようにします。
s25r.add_whitelist do |host| (8..19).include?(Time.now.hour) and /\.jp\z/ === host end
s25r.add_blacklist(/\.evil\.example\.com\z/)black.example.comというホストをブラックリストに入れる場合は以下のようにします。
s25r.add_blacklist("black.example.com")
[上級者向け] 複雑な条件を指定したい場合はブロックを指定することができます。ブロックにはホスト名が引数として渡されます。例えば、午後8:00から午前7:59までの間だけ.jpトップレベルドメインをブラックリストに入れる場合は以下のようにします。
s25r.add_blacklist do |host| !(8..19).include?(Time.now.hour) and /\.jp\z/ === host end
trueを指定した場合はIPv4からの接続してきた場合のみS25Rのチェックを有効にします。falseを指定するとIPv6からの接続の場合でもチェックします。
例:
s25r.check_only_ipv4 = false # IPv4以外のときもチェック初期値:
IPv4の場合のみチェックする
この適用条件を使うと、外部ネットワークからアクセスしてきたSMTPクライアントにのみ子milterを適用します。
以下の例ではローカルネットワークからのメールにはスパムチェックを行わない事で誤検出を回避しています。
使用例:
define_milter("spamass-milter") do |milter|
milter.add_applicable_condition("Remote Network")
end
192.168.0.0/24などのプライベートIPアドレス以外を外部ネットワークとして扱います。プライベートIPアドレス以外もローカルネットワークとして扱いたい場合は以下の設定で追加することができます。
# 160.29.167.10からのアクセスは子milterを適用しない
remote_network.add_local_address("160.29.167.10")
# 160.29.167.0/24のネットワークからのアクセスは子milterを適用しない
remote_network.add_local_address("160.29.167.0/24")
# 2001:2f8:c2:201::fff0からのアクセスは子milterを適用しない
remote_network.add_local_address("2001:2f8:c2:201::fff0")
# 2001:2f8:c2:201::/64からのアクセスは子milterを適用しない
remote_network.add_local_address("2001:2f8:c2:201::/64")# 160.29.167.10からのアクセスは子milterを適用する
remote_network.add_remote_address("160.29.167.10")
# 160.29.167.0/24のネットワークからのアクセスは子milterを適用する
remote_network.add_remote_address("160.29.167.0/24")
# 2001:2f8:c2:201::fff0からのアクセスは子milterを適用する
remote_network.add_remote_address("2001:2f8:c2:201::fff0")
# 2001:2f8:c2:201::/64からのアクセスは子milterを適用する
remote_network.add_remote_address("2001:2f8:c2:201::/64")SMTP Authで認証済みのSMTPクライアントにのみ子milterを適用します。この適用条件を利用する場合は、MTAが認証関連のマクロをmilterに渡すようにしなければいけません。Sendmailは特に設定をする必要はありません。Postfixの場合は以下の設定を追加する必要があります。
main.cf:
milter_mail_macros = {auth_author} {auth_type} {auth_authen}
以下の例は認証済みのSMTPクライアントが送ったメール(内部から送信したメール)を監査用にBccする設定です。
使用例:
define_milter("milter-bcc") do |milter|
milter.add_applicable_condition("Authenticated")
end
SMTP Authで認証されていないSMTPクライアントにのみ子milterを適用します。Authenticationと同様に、MTAが認証関連のマクロをmilterに渡すようにしなければいけません。
以下の例は認証されていないSMTPクライアントからのメールにのみスパムチェックを行い、誤検出を回避する設定です。
使用例:
define_milter("spamass-milter") do |milter|
milter.add_applicable_condition("Unauthenticated")
end
この適用条件は少し変わっています。この適用条件を設定してもすべての子milterを適用します。では何をするのかというと、SendmailとPostfixのmilter実装の非互換を吸収し、Sendmailでしか動かないmilterをPostfixでも動くようにします。
SendmailとPostfixではmilterの実装に互換性がない部分があります。例えば、マクロ名が異なったり、マクロを渡すタイミングが異なったりします。
この適用条件を設定すると、それらの差異を吸収し、同じmilterがSendmailでもPostfixでも動作するようになります。ただし、最近のmilterはどちらでも動くように作られているのでこの適用条件が必要なくなる日は近いでしょう。これはとてもよいことです。
MTAがPostfixの場合にこの適用条件を設定しても悪影響はないので、安心してください。
以下の例はSendmail用にビルドしたmilter-greylistをPostfixでも使えるようにする設定です。
使用例:
define_milter("milter-greylist") do |milter|
milter.add_applicable_condition("Sendmail Compatible")
end
1.5.0から使用可能。
負荷に応じて動的に処理を変更する適用条件をいくつか提供しています。負荷は同時接続数で判断します。
# Postfixのデフォルト設定の場合(環境によって異なる) stress.threshold_n_connections # => 75
# 同時接続数が75以上の場合、負荷が高いと判断 stress.threshold_n_connections = 75
1.5.0から使用可能。
負荷が小さいときのみ、子milterを適用する適用条件です。
以下の例は負荷が高いときはspamass-milterを適用しない設定です。
使用例:
define_milter("spamass-milter") do |milter|
milter.add_applicable_condition("No Stress")
end
1.5.0から使用可能。
負荷が高いときに"{stress}=yes"マクロを設定し、子milterに負荷が高いことを通知する適用条件です。この適用条件は通知するだけなので、設定しても常にすべての子milterは適用されます。
以下の例は負荷が高いときはmilter-greylistにマクロで通知をする設定です。
使用例:
define_milter("milter-greylist") do |milter|
milter.add_applicable_condition("Stress Notify")
end
milter-greylist側で「負荷が高いときはGreylisting、負荷が低いときはTarpittingを使う」設定は以下のようになります。この設定を使う場合はmilter-greylist 4.3.4以降が必要です。
greylist.conf:
sm_macro "no_stress" "{stress}" unset
racl whitelist sm_macro "no_stress" tarpit 125s
racl greylist default
1.6.0から使用可能。
信用できるセッションには「trusted_XXX=yes」というマクロを設定します。設定されるマクロの一覧は以下の通りです。
以下は信用するドメインに対しては、SPFの検証が成功したらそのまま受信し、失敗したらGreylistを適用する例です。
milter-manager.local.conf:
define_milter("milter-greylist") do |milter|
milter.add_applicable_condition("Trust")
end
greylist.conf:
sm_macro "trusted_domain" "{trusted_domain}" "yes"
racl whitelist sm_macro "trusted_domain" spf pass
racl greylist sm_macro "trusted_domain" not spf pass
どの情報を使って信用するかどうかを判断するかは、以下の設定を使ってカスタマイズできます。
trust.add_envelope_from_domain("example.com")trust.clear
# コメント。この行は無視される。 gmail.com # ↑の行はgmail.comを信用するという意味 /\.example\.com/ # ↑の行はexample.comのサブドメインすべてを信用するという意味 # ↑の行は空白だけの行。空行は無視する。例:
trust.load_envelope_from_domains("/etc/milter-manager/trusted-domains.list")
# /etc/milter-manager/trusted-domains.listから信用する
# ドメインのリストを読み込みます。条件にマッチしたenvelope-recipientを含む場合に子milterを適用します。
restrict_accounts_by_list("bob@example.com", /@example\.co\.jp\z/, condition_name: "Restrict Accounts")ここからは本格的にRubyの知識が必要になります。標準でS25Rなどの有用な適用条件は用意されています。それらで十分ではない場合は、適用条件を定義することができます。適用条件を定義することにより、子milterを適用するかを動的に判断することができます。
適用条件は以下の書式で定義します。適用条件の定義にはRubyの知識が必要になります。
define_applicable_condition("名前") do |condition|
condition.description = ...
condition.define_connect_stopper do |...|
...
end
...
end
例えば、S25Rを実現する適用条件は以下のようになります。
define_applicable_condition("S25R") do |condition|
condition.description = "Selective SMTP Rejection"
condition.define_connect_stopper do |context, host, socket_address|
case host
when "unknown",
/\A\[.+\]\z/,
/\A[^.]*\d[^\d.]+\d.*\./,
/\A[^.]*\d{5}/,
/\A(?:[^.]+\.)?\d[^.]*\.[^.]+\..+\.[a-z]/i,
/\A[^.]*\d\.[^.]*\d-\d/,
/\A[^.]*\d\.[^.]*\d\.[^.]+\..+\./,
/\A(?:dhcp|dialup|ppp|[achrsvx]?dsl)[^.]*\d/i
false
else
true
end
end
end
名前解決ができなかったときはhostは"unknown"ではなく、"[IPアドレス]"になります。そのため、本当は"unknown"は必要なく、/\A[.+]\z/で十分ですが、念のため入れています。 :-)
define_applicable_condition do … end内で設定できる項目は以下の通りです。
必須の項目はありません。
condition.description = "test condition"既定値:
condition.description = nil
condition.define_connect_stopper do |context, host, socket_address|
if /\A\[.+\]\z/ =~ host
false
else
true
end
endcondition.define_helo_stopper do |context, helo| helo == "localhost.localdomain" end
condition.define_envelope_from_stopper do |context, from|
if /@example.com>\z/ =~ from
true
else
false
end
endcondition.define_envelope_recipient_stopper do |context, recipient|
if /@ml.example.com>\z/ =~ recipient
true
else
false
end
endcondition.define_data_stopper do |context| true end
condition.define_header_stopper do |context, name, value|
if ["X-Spam-Flag", "YES"] == [name, value]
true
else
false
end
endcondition.define_end_of_header_stopper do |context| true end
condition.define_body_stopper do |context, chunk|
if /^-----BEGIN PGP SIGNATURE-----$/ =~ chunk
true
else
false
end
endcondition.define_end_of_message_stopper do |context| true end
子milterを適用するかどうかを判断する時点での様々な情報を持ったオブジェクトです。(クラスはMilter::Manager::ChildContextです。)
以下の情報を持っています。
context.name # -> "clamav-milter"
context["j"] # -> "mail.example.com"
context["rcpt_address"] # -> "receiver@example.com"
context["{rcpt_address}"] # -> "receiver@example.com"context.reject? # -> false context.children["milter-greylist"].reject? # -> true or false
context.temporary_failure? # -> false context.children["milter-greylist"].temporary_failure? # -> true or false
context.accept? # -> false context.children["milter-greylist"].accept? # -> true or false
context.discard? # -> false context.children["milter-greylist"].discard? # -> true or false
context.quitted? # -> false context.children["milter-greylist"].quitted? # -> true or false
context.children["milter-greylist"] # -> milter-greylistのcontext context.children["nonexistent"] # -> nil context.children[context.name] # -> 自分のcontext
context["v"] # -> "Postfix 2.5.5" context.postfix? # -> true context["v"] # -> "2.5.5" context.postfix? # -> false context["v"] # -> nil context.postfix? # -> false
milter_mail_macros = {auth_author} {auth_type} {auth_authen}
認証されている場合はtrue、そうでない場合はfalseが返ります。
例:
context["auth_type"] # -> nil context["auth_authen"] # -> nil context.authenticated? # -> false context["auth_type"] # -> "CRAM-MD5" context["auth_authen"] # -> nil context.authenticated? # -> true context["auth_type"] # -> nil context["auth_authen"] # -> "sender" context.authenticated? # -> true
define_applicable_condition("") do |condition|
condition.define_envelope_recipient_stopper do |context, recipient|
if /\Asomeone@example.com\z/ =~ recipient
context.mail_transaction_shelf["stop-on-data"] = true
end
false
end
condition.define_data_stopper do |context|
context.mail_transaction_shelf["stop-on-data"]
end
endソケットのアドレスを表現しているオブジェクトです。IPv4ソケット、IPv6ソケット、UNIXドメインソケットそれぞれで別々のオブジェクトになります。
IPv4ソケットのアドレスを表現するオブジェクトです。以下のメソッドを持ちます。
socket_address.address # -> "192.168.1.1"
socket_address.port # -> 12345
socket_address.to_s # -> "inet:12345@[192.168.1.1]"
socket_address.to_s # -> "inet:12345@[127.0.0.1]" socket_address.local? # -> true socket_address.to_s # -> "inet:12345@[192.168.1.1]" socket_address.local? # -> true socket_address.to_s # -> "inet:12345@[160.XXX.XXX.XXX]" socket_address.local? # -> false
socket_address.to_s # -> "inet:12345@[127.0.0.1]" socket_address.to_ip_address # -> #<IPAddr: IPv4:127.0.0.1/255.255.255.255>
IPv6ソケットのアドレスを表現するオブジェクトです。以下のメソッドを持ちます。
socket_address.address # -> "::1"
socket_address.port # -> 12345
socket_address.to_s # -> "inet6:12345@[::1]"
socket_address.to_s # -> "inet6:12345@[::1]" socket_address.local? # -> true socket_address.to_s # -> "inet6:12345@[fe80::XXXX]" socket_address.local? # -> true socket_address.to_s # -> "inet6:12345@[2001::XXXX]" socket_address.local? # -> false
socket_address.to_s # -> "inet6:12345@[::1]" socket_address.to_ip_address # -> #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
UNIXドメインソケットのアドレスを表現するオブジェクトです。以下のメソッドを持ちます。
socket_address.path # -> "/tmp/local.sock"
socket_address.to_s # -> "unix:/tmp/local.sock"
socket_address.local? # -> true
socket_address.to_s # -> "unix:/tmp/local.sock" socket_address.to_ip_address # -> nil
1.6.6から使用可能。
データベース操作機能を利用する場合はRubyの知識が必要になります。データベース操作ライブラリとしてActiveRecordを採用しています。そのため、MySQLやSQLite3など多くのRDBを操作することができます。
データベース接続機能を利用する場合はActiveRecordを別途インストールする必要があります。ActiveRecordのインストールにはRuby用のパッケージ管理システムRubyGemsを用います。RubyGemsとActiveRecordのインストール方法はインストールページにあるインストールドキュメントのうち、「(任意)」の方のインストールドキュメントを参照してください。それぞれの環境でのRubyGemsとActiveRecordのインストール方法とを説明しています。
ActiveRecordをインストールしたらデータベース操作機能を利用することができます。
MySQLのusersテーブルの値を操作する場合の例を示します。
MySQLの接続情報は以下の通りとします。
まず、この接続情報をmilter-manager.local.confで指定します。ここでは、milter-manager.local.confは/etc/milter-manager/milter-manager.local.confにあるとします。
/etc/milter-manager/milter-manager.local.conf:
database.type = "mysql2" database.host = "192.168.0.1" database.name = "mail-system" database.user = "milter-manager" database.password = "secret"
次に、usersテーブルに接続するためのActiveRecrodオブジェクトを定義します。定義ファイルはmilter-manager.local.confが置いてあるディレクトリと同じパスにあるmodels/ディレクトリ以下に置きます。今回はusersテーブル用の定義ファイルなのでmodels/user.rbを作成します。
/etc/milter-manager/models/user.rb:
class User < ActiveRecord::Base end
これで準備は整ったので、再び、milter-manager.local.confへ戻ります。以下のように書いてデータベースへ接続し、データを操作します。
/etc/milter-manager/milter-manager.local.conf:
database.setup
database.load_models("models/*.rb")
User.all.each do |user|
p user.name # => "alice", "bob", ...
end
まとめると以下のようになります。
/etc/milter-manager/milter-manager.local.conf:
# 接続情報設定
database.type = "mysql2"
database.host = "192.168.0.1"
database.name = "mail-system"
database.user = "milter-manager"
database.password = "secret"
# 接続
database.setup
# 定義を読み込み
database.load_models("models/*.rb")
# データを操作
User.all.each do |user|
p user.name # => "alice", "bob", ...
end
/etc/milter-manager/models/user.rb:
class User < ActiveRecord::Base end
以下は設定項目です。
% sudo gem install mysql2
% sudo gem install sqlite3
% sudo gem install pg
database.type = "mysql2" # MySQLを利用
":memory:"を指定します。
例:
database.name = "configurations" # configurationsデータベースへ接続
database.host = "192.168.0.1" # 192.168.0.1で動いているサーバへ接続
database.port = 3306 # 3306番ポートで動いているサーバへ接続
database.path = "/var/run/mysqld/mysqld.sock" # UNIXドメインソケットでMySQLへ接続
database.user = "milter-manager" # milter-managerユーザでサーバへ接続
database.password = "secret"
:reconnectオプションを指定する場合は以下のようになります。
database.type = "mysql2" database.extra_options[:reconnect] = true指定できるオプションはデータベース毎に異なります。 例:
database.extra_options[:reconnect] = true
database.setup
# /etc/milter-manager/models/user.rb
# /etc/milter-manager/models/group.rb
# などを読み込む。
# (/etc/milter-manager/milter-manager.confを使っている場合)
database.load_models("models/*.rb")