なんか上手くいったので忘れないように自分のための備忘録を。
fluentのsecure_forwardの設定をchefでばらまく時のはなし。
前提環境としてはAWSの複数アカウント間転送でVPCpeeringしてないのでsslで送りたいからSecure_forwardプラグインつかうがELB介すのはセッションぶちぶち切れて無理そげなのでEIPで制限して直に送ることにしてみてなんとかできそう。あとはそれをレシピにしようとしてました。
サーバ側(受け取る側)とクライアント側(送る側)で共通な設定が多い割に、
送る側ではユーザのデータは一人分しか要らないけどどうやってとりだしたらええねんとなって初心者なりに試行錯誤しました。
こんなかんじのjson。このユーザのデータを受け取る側では全て設定していなければならないが送る側は一人分で良い。
$ knife solo data bag create fluentd secure_forward
{
"id": "secure_forward",
"fluentusers": [
{
"username": "hoge",
"password": "hoge********"
},
{
"username": "fuga",
"password": "fuga********"
}
],
"shared_key": "piyopiyo",
"servers": [
{
"server": "log-ext1.mng.piyo.net"
},
{
"server": "log-ext2.mng.piyo.net"
}
]
}
ググりまくったりrubyのhash関連のマニュアルをガン見してトライアンドエラーした結果、以下のようなレシピに。
#~略~本体インストールとかアカウント判別データのロード
# load secure_forward data
ssl_data = Chef::EncryptedDataBagItem.load("fluentd", "secure_forward")
fluentusers = ssl_data['fluentusers']
servers = ssl_data['servers']
shared_key = ssl_data['shared_key']
ssl_conf = node['fluentd']['server_ssl_conf']
#~略~(このへんで証明書関連のデータをロード
## piyo のみ elasticsearchに送る、secure_forwardの受け取り側.
if "#{account}" == 'piyo'
## set cert files.
file "#{sslkeydir}/#{sslkeyfile}" do
notifies :restart, 'service[td-agent]'
content sslkeydata
end
file "#{sslkeydir}/#{sslcrtfile}" do
notifies :restart, 'service[td-agent]'
content sslcrtdata
end
file "#{sslkeydir}/#{sslcacrtfile}" do
notifies :restart, 'service[td-agent]'
content sslcacrtdata
end
## set elasticsearch configs.
template "/etc/td-agent/extra/td-agent-el-tag4" do
action :create
source "td-agent.conf.server-el-tag4.erb"
notifies :restart, 'service[td-agent]'
variables ({
:elasticsearch => elasticsearch
})
end
template "/etc/td-agent/extra/td-agent-el-tag3" do
action :create
source "td-agent.conf.server-el-tag3.erb"
notifies :restart, 'service[td-agent]'
variables ({
:elasticsearch => elasticsearch
})
end
include_el_tag4 = '@include /etc/td-agent/extra/td-agent-el-tag4'
include_el_tag3 = '@include /etc/td-agent/extra/td-agent-el-tag3'
## set server template for secure_forward.
template "/etc/td-agent/extra/td-agent-#{ssl_conf}.conf" do
action :create
source "td-agent.conf.server-#{ssl_conf}.erb"
notifies :restart, 'service[td-agent]'
variables ({
:shared_key => shared_key,
:sslcacrt => sslcacrtfile,
:sslcrt => sslcrtfile,
:sslkey => sslkeyfile,
:fluentusers => fluentusers
})
end
## set variables for include confs(switch distination).
variables = {}
variables.merge!({
:include_el_tag4 => include_el_tag4,
:include_el_tag3 => include_el_tag3,
})
## piyo(アカウント名)以外の場合、elasticsearchには送付しない、secure_forward送信側.
else
## set cacert file.
file "#{sslkeydir}/#{sslcacrtfile}" do
notifies :restart, 'service[td-agent]'
content sslcacrtdata
end
## set client variables for secure_forward.
sfvariables = {}
fluentusers.each do |fluentuser|
if fluentuser.has_value?("#{account}")
fluentuser.values_at(:username, :password)
sfvariables = fluentuser
end
end
sfvariables.merge! ({
:shared_key => shared_key,
:sslcacrt => sslcacrtfile,
:servers => servers,
})
## set client template for secure_forward.
template "/etc/td-agent/extra/td-agent-#{ssl_conf}" do
action :create
source "td-agent.conf.server-#{ssl_conf}.erb"
notifies :restart, 'service[td-agent]'
variables sfvariables
end
include_sslsend = '@include /etc/td-agent/extra/td-agent-ssl-send'
#ここにelに送らずpiyoにsecure_worwardで送るのをincludeさせるための変数をset.
## set variables for include confs(switch distination).
variables = {}
variables.merge!({
:include_sslsend => include_sslsend,
})
end
#~略~(他に必要なtemplateの配置など)
やりたかったのはここいらへんで使ってるeachとhas_value?とvalus_atとmerge!とかでなんとかなりました。
## set client variables for secure_forward.
sfvariables = {}
fluentusers.each do |fluentuser|
if fluentuser.has_value?("#{account}")
fluentuser.values_at(:username, :password)
sfvariables = fluentuser
end
end
sfvariables.merge! ({
:shared_key => shared_key,
:sslcacrt => sslcacrtfile,
:servers => servers,
})
eachで配列の中身をループで処理、has_value?でアカウント名の文字列が含まれる配列だけピックアップして、
values_atでkey名に含まれるやつをピックアップして(これ要らなかったかも?)別名でhashを保存して、
merge!でほかに必要なhashと結合、という具合でございますです。
template側で送るとこ切り替えるのはtype copy
の<store>~</store>
を分離したやつをincludeさせて切り替えました。
~略~
</store>
<% if @include_el_tag4 %>
<%= @include_el_tag4 %>
<% elsif @include_sslsend %>
<%= @include_sslsend %>
<% end %>
<store>
~略~
あと、ひとつのアカウントだけelasticsearchに送るけど他のアカウントはその一つのアカウントに送るみたいなことになってて
そのtemplateでの送る先の切替を読み込むincludeの文字列をifで切替えするみたいなこともやってみたりなど。
secure_forward的には送る側のtemplateがこんな↓かんじ。
<store>
type secure_forward
self_hostname <%= node['hostname'] %>
shared_key <%= @shared_key %>
secure yes
ca_cert_path /etc/td-agent/<%= @sslcacrt %>
# enable_strict_verification yes
<% for server in @servers %>
<server>
host <%= server["server"] %> # or IP
# port 24284
username <%= @username %>
password <%= @password %>
</server>
<% end %>
</store>
secure_forward的な受け取る側のtemplateはこんな↓かんじです。
<source>
type secure_forward
shared_key <%= @shared_key %>
self_hostname <%= node['hostname'] %>
# cert_auto_generate yes
secure yes
ca_cert_path /etc/td-agent/<%= @sslcacrt %>
cert_path /etc/td-agent/<%= @sslcrt %>
private_key_path /etc/td-agent/<%= @sslkey %>
private_key_passphrase
authentication yes # Deny clients without valid username/password
<% for fluentuser in @fluentusers %>
<user>
username <%= fluentuser["username"] %>
password <%= fluentuser["password"] %>
</user>
<% end %>
</source>
某アニキによると、private_key_passphraseは空でもかかないとだめっぽかったとのことでした。
で、実際適用されたあとの設定ファイルが、、
受け取る側はこんなかんじで、
<source>
type secure_forward
shared_key piyopiyo
self_hostname log2-mng****
# cert_auto_generate yes
secure yes
ca_cert_path /etc/td-agent/exsample.cacrt
cert_path /etc/td-agent/exsample.crt
private_key_path /etc/td-agent/exsample.key
private_key_passphrase
authentication yes # Deny clients without valid username/password
<user>
username hoge
password hoge********
</user>
<user>
username fuga
password fuga********
</user>
</source>
送る側はこんなかんじに。
<store>
type secure_forward
self_hostname log-fuga-mng-****
shared_key piyopiyo
secure yes
ca_cert_path /etc/td-agent/exsample.cacrt
# enable_strict_verification yes
<server>
host log-ext1.mng.piyo.net # or IP
# port 24284
username fuga
password fuga********
</server>
<server>
host log-ext2.mng.piyo.net # or IP
# port 24284
username fuga
password fuga********
</server>
</store>
参考:
・キレ者の人が書いたと思われるレシピとtemplate、
・rubyのhash関連のマニュアル
http://ref.xaio.jp/ruby/classes/hash
・data_bagsに関して試してる記事など
http://inokara.hateblo.jp/entry/2013/05/05/084251
・chefのtemplateのマニュアル
https://docs.chef.io/resource_template.html
「Chef活用ガイド」P595~のtemplateのマニュアル
感想:
いつもあんまり使ってない脳みそを結構使った感じでちょっと楽しかったです。
(うまくいかないとつらいですけれども)
初心者なのでまず取り出したいデータが配列の中の複数hashっぽいのを理解するまでがアレでした。
そこからはhashのマニュアルみて悩みつつ目的に合いそうなメソッドを単体テストしまくりました。