kikumotoのメモ帳

インフラ・ミドル周りを中心に、興味をもったことを適当な感じで。twitter : @takakiku

JTF2016で話してきました - HashiCorp Vault + LDAP + MySQL

先日(2017/7/24)に行われた July Tech Festa 2016 でトークが採択されたので話してきました。

タイトル: HashiCorp VaultでMySQLアカウント管理はもう怖くない 2016.techfesta.jp

基本的に前回のエントリ YAPC::Asia Hachioji 2016 mid in Shinagawaで話した、スタッフした! - kikumotoのメモ帳 と同じ内容をしゃべりました。

基本的に話した内容はスライドにある通りです。

一番のポイントは、Vault では認証基盤とアクセス管理対象を、Vault が提供している Auth / Secret Backend の範囲で自由に組みわせられるということです。

GitHub Token を使って、PostgreSQL のアカウント管理なんかもできてしまいます。これを理解していただけると、自分の環境のニーズに合わせて、アカウント管理が安全に柔軟にできるのではと思っています。

あと今回出た質問と回答をまとめておきます。

  • すでにMySQLにアカウントが登録されていた状態だったのか?

    • 私の環境では、そうではなくて管理したいアカウントを新規に作っていくという感じでしたので、既存アカウントの移行という感じではありませんでした。
  • 今回の話し人がアクセスするという話しだったように思えるが、アプリケーションの場合はどうなるのか?

    • Auth Backend に App ID というのがあり、Vault 自体がアプリケーションのにアクセスKeyみたいなのを発行する仕組みがあります。これにより、アプリケーションは必要に応じて都度MySQLのアカウントを生成できて、アプリケーションがconfigに書かれた固定的なMySQLのアカウント・パスワードを使う必要がなくなります。

ということで、7月の2つもトークすることができて満足です。

聞きにきてくださった皆様、本当にありがとうございました。

また、JTFのスタッフの皆様、よいイベントにしていただきありがとうございました。

YAPC::Asia Hachioji 2016 mid in Shinagawaで話した、スタッフした!

YAPC::Asia Hachioji 2016 mid in Shinagawa が、7/2,7/3 で開催されました。 yapcasia8oji-2016mid.hachiojipm.org

トークのお話し

トークが採択されたので、YAPC::Asia Hachioji 2016 mid in Shinagawa の1日目夕方に

github.com

ということで話してきました。

スライドを下記に公開しています。

データのアクセス管理をきちんとしないといけないような環境が前提であったので、ちょっと話しとしてはお堅い内容になってしまったかなとは思います。

それでも必要なところには1つの事例として参考になれば幸いです。

1つ質問をうけて、Consul 側のアクセス管理はどうしているのか、というのをいただきました。

答えとしては、Consul はシステム管理者以外には公開していないので現状はなにもしていないという感じです。

Consul に直接アクセスされてもデータは暗号化されているので情報が取得される心配はないのですが、逆にデータは消そうと思えば消せるので、本質的には良い状態ではないかなと認識しています。ただし、現状ではそのデータを消されても、MySQLの動的アカウントが発行できなくなる程度な使い方しかしていないので、そのうち対策しようかなという感じです。

トークを聞きに来ていただいた皆様ありがとうございました。

スタッフのお話し

また、今回はボランティアスタッフにも参加させてもらいました。担当は受付でしたので、何人かの方は私がチケットをお渡ししていた感じになります。

こういうイベントでのスタッフというのは初体験でしたが、リーダの方々があらかじめ段取りをしておいていただいたおかげで無事に役割をまっとうできたかなと思います。ありがとうございましした。

スタッフやってみて良かったのは、やはり仲間が増えたことでしょうか。第1回ヤパチーのスタッフという共通体験をできた仲間がいるということは今後のいろいろな支えになる気がします。

次回ヤパチーがあれば(あるような流れ)、またスタッフとして参加したいと思える体験でした。

最後に、このYAPC::Asia Hachioji 2016 mid in Shinagawaを開催してくれた @uzulla , @makamaka さんに感謝です。

二日間通し券はないYAPC::Asia Hachioji 2016 mid in Shinagawaで話します!

タイトルは注意喚起を込めています!

2016/7/2(土),3(日)に開催されるYAPC::Asia Hachioji 2016 mid in Shinagawaで話すことができることなりましたー!

タイトルに入れたようにこのイベントでは

  • 二日間通し券はありません

それぞれの日でなんらかの登録が必須です。

すでに一般枠は定員オーバー抽選必須となっているので、どうしても参加したいかたはその他の枠をうまく利用するしかないでしょう!

本題

7/2(土)の最後の時間帯で話します。

github.com

事例があるのかないのかよくわからない Vault ですが実際に MySQL アカウント管理のために導入してみたお話しです。興味あるかたは是非お越しくださいませ〜。

Vault の説明と事例の説明という感じの予定です。できれば、他の方がどのように使われているかも知りたいので、質問タイムや懇親会などでお話しできると嬉しいです!

あ、懇親会は懇親会で申し込み必須です。

connpass.com

私は、今回スタッフとしても参加させていただおり、受付担当予定です。ですので、皆様まずは当日受付でお会いしましょう。

繰り返しますが、

  • 二日間通し券はありません

各日それぞれ登録し、もちろん受付も各日で行ってください。

また、

  • 入館証は当日限りで、再発行はありません

絶対になくさないで!お願い!

ということで、当日皆様とお会いできることと、有意義なイベントになることを楽しみにしております!

TLS1.2が使えない環境のためのProxy (squid)設定

TL;DR

接続先がTLS1.1、TLS1.2 以降しか接続を許可しなくなるけど、環境そのもののアップデートができなくて、Proxy でとりあえず逃げたいという方向けです。

Squid を使った設定例を書いてます。(参考情報 - Intercept HTTPS CONNECT messages with SSL-Bump

目次

背景

PCI DSSというクレジット業界におけるグローバルセキュリティ基準があるらしく(詳しくないです)、これのv3.2が2016/04/28が公開されました。 それによると、PCI DSSを取得している業者は

  • 2016/06/30 までに TLS1.1 以上の通信をサポートしなければならない
  • 2018/06/30 までに SSL および TLS1.0 の通信を無効化しなければならない

ことになるようです。

参考記事

実際PayPal は 2017/06 には TLS1.2 のみの接続しかできなくなるようです。

まぁ普通はOpenSSLの1.0/1.1系の最新バージョンを使っていればなんの問題もないです。

しかし、世の中には様々な闇のような理由でSSL3ぐらいまでしかサポートしていない環境で運用している人もいるでしょう。

そこでProxyで頑張ってみる(臭いものに蓋をする)にはどうすればいいのかを調べてみました。

今回試す構成

client(CentOS5 + curl) <--> Proxy (CentOS7 + squid 3.5) <--> Web

というイメージです。

Squid

3.5インストール

Squid 3.5 を使います。

/etc/yum.repos.d/squid.conf を下記のように用意して

[squid]
name=Squid repo for CentOS Linux - $basearch
#IL mirror
baseurl=http://www1.ngtech.co.il/repo/centos/$releasever/$basearch/
failovermethod=priority
enabled=1
gpgcheck=0

epelも有効にしたうえで yum コマンドでインストール

yum install perl-Crypt-OpenSSL-X509 squid squid-helpers

自己署名証明書作成

クライアントから見るとTLSでのやりとりはProxyとなるので、Proxyに証明書が必要となります。 これを準備します。

cd /etc/squid
mkdir ssl_cert
chown squid:squid ssl_cert
chmod 700 ssl_cert
cd ssl_cert
openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout myCA.pem  -out myCA.pem

squid.conf

/etc/squid/squid.conf を以下のように記述。

visible_hostname は適当。

lan のアドレス帯は自分の環境にあわせて修正ですね。

visible_hostname my.example.com

acl CONNECT method CONNECT
acl lan src 192.168.2.0/255.255.254.0

http_access allow localhost
http_access allow lan
http_access deny all

http_port 3128 ssl-bump \
  cert=/etc/squid/ssl_cert/myCA.pem \
  generate-host-certificates=on dynamic_cert_mem_cache_size=4MB

acl step1 at_step SslBump1

ssl_bump peek step1
ssl_bump bump all

sslproxy_options NO_SSLv2,NO_SSLv3,NO_TLSv1,SINGLE_DH_USE

forwarded_for off
request_header_access Referer deny all
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all

sslproxy_options ですが、TLS1.1 も制限したいなら NO_TLSv1_1 を加えます。(参考 - squid : sslproxy_options configuration directive

SSL certificates cache directory

/usr/lib64/squid/ssl_crtd -c -s /var/lib/ssl_db
chown squid:squid -R /var/lib/ssl_db

起動

systemctl start squid

結果

CentOS5 から TLS1.2 のみの環境に接続してみると(下記のコマンドの接続先は実在するものではないです)

$ curl https://hogehoge.xxxx.xxxx/
curl: (35) Unknown SSL protocol error in connection to hogehoge.xxxx.xxxx:443

となるが、proxy (ここでは 192.168.2.241 とします)を経由すると

$ curl -k --proxy 192.168.2.241:3128 https://hogehoge.xxxx.xxxx/
<!DOCTYPE html>
<html lang="en">
<head>
以下略

のように接続ができます。

Webサーバ側のログに接続に使われたSSL/TLSのバージョンを出力するようにしてあれば

xxx.xxx.xxx.xxx - - [03/Jun/2016:21:36:26 +0900] "GET / HTTP/1.1" TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256 200 45838 "-" "curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-" 

のように TLSv1.2 で繋がっていることが確認できます。

まとめ

clientがTLS1.1 TLS1.2 に対応できていなくても、Proxy 側でサーバとのTLSの接続をさせることで、なんとか接続する方法を書きました。

まぁ、普通はちゃんとclientの環境をバージョンアップしているのでこんなことはしなくてよいでしょう。臭いものに蓋をすると一生そこは闇になります。

BigQueryのテーブルを一定期間経過後削除する defaultTableExpirationMs

Google BigQuery 便利ですね。

テーブルを日毎に分割してデータを貯めていっているのですが、ある程度経過したらまぁ消してもよいかなと思うデータもあります。

そんなときに、GCSやS3のObject Lifecycle Management的なものがあると、自前でcronまわして削除するという手間とか何らかのリソースが不要になって嬉しいなということで、調べてやってみた話です。

答えはちゃんと公式ドキュメントに書いてあって、 defaultTableExpirationMs というプロパティを設定すれば良いようです。

GitHub - GoogleCloudPlatform/gcloud-ruby: Google Cloud Client Library for Ruby 使って設定するコードは以下のような感じです。

require "gcloud"

gcloud = Gcloud.new "project-id", "/path/to/keyfile.json"
bigquery = gcloud.bigquery

dataset = bigquery.dataset "mydataset"
dataset.default_expiration = 3600000

ドキュメントの通り、単位はmsecで、設定以降に作られたテーブルは、その作成した時間から上記設定時間経過後に自動的に削除されます。作成済みのテーブルには反映されませんし、作成済みのテーブル個別に対して削除期限を変更する設定はないようです(これこれで欲しいのですが)。また、1時間より短い設定はできません。

あと注意として、Datasetに対してオーナーの権限(Is owner)を持ったキー(上記のコードでいうkeyfile.json)でないと設定できませんでした。編集権限(Can edit)では設定できませんでした。

現状ではUIからは1日で削除するか否かの設定はできますが、細かい指定をするには上記のようにAPIを使って設定するしかなさそうです。

が、これでテーブルの管理の一手間が減って大変助かりますね。

エンジニアサポートクロス2016にゴールドスポンサー( Hamee )として参加してきた

2/5に横浜大桟橋で開催されたエンジニアサポートクロス2016にゴールドスポンサーのHamee

more.hamee.co.jp

の一員として参加してきました。


ISUCON5で惨敗し、その悔しさのエネルギーがあるときに、CROSS2016スポンサー募集を発見して、そのエネルギーで会社も説得し、なんとか会社として初のエンジニア系イベントのスポンサーというところにこぎつけました。

最初はシルバーくらいのつもりだったのが、結局はゴールドスポンサーでエントリー。

ゴールドなのでランチセッションもできるということで、ブースの準備はあるは、ランチの手配、セッションスピーカーの手配など、初めてづくしで、みんなでアイデア出して協力してと大変だったけどよい経験でした。もっともほとんどのことは仲間がうまくやってくれて私は大したことせず状態でしたが。仲間に感謝ですね。

ともあれ、当日はがらぽんでMacBook Airがあたるという、太っ腹!?企画でそれなりにブースも盛況になるし、twitterも賑わってくれたました。

MacBook Airはなんとしても当てて欲しかったので、結構最後の方まで出なかったのはハラハラでした。当たりでてよかったー。


ランチセッションのまとめは、こちら。まとめ、ありがとうございます!

www.shigemk2.com


とにかく、スポンサーやってみて良かったです。

いろんな方と出会いがありましたし、今まで参加するだけだったのと違って数倍楽しめました。

また、来年もなんとか会社を丸め込んで説得してスポンサーで参加したいですね。

最後に、当日一緒にHameeスタッフとして参加した皆様に感謝します。

そして、エンジニアサポートクロス2016のイベントスタッフの皆様、いろいろ手配・ご協力いただきありがとうございました。

もちろん、ブースに来てくれた参加者の皆様、本当にありがとうございました!!


ランチは小田原のはなまるキッチンさんにご用意いただきました。

マジでおいしいので、小田原きたときにはちょっと歩くけど、超オススメです。

続:Consul 0.6でユーザのいるshardを探す(Prepared Queryを使う)

この記事は HashiCorp Advent Calendar 2015 - Qiita の23日目です。(1時間ほど早めに公開したのでブログの日付は22ですが)

前回の記事 Consul 0.6でユーザのいるshardを探す(Prepared Queryを使う) - kikumotoのメモ帳 の続編です。

id:fujiwara さんの

Consul 0.6でユーザのいるshardを探す(Prepared Queryを使う) - kikumotoのメモ帳

数百万のPQがconsulに登録されても大丈夫なものだろうか

2015/12/21 07:25
b.hatena.ne.jp というコメントを受けて、Prepared Queryを100万件突っ込んでみた結果をまとめます。

結果

先に結果を。

100万件PQを突っ込みましたが、DNSの応答は10件だけ登録のときも、100万件登録後も、ほぼ2msecとなり特に性能面での変化は見られませんでした。

ただ、PQの登録については若干劣化(最初は0.9msくらいあったのが、1.5msくらいになった)するようです。ただし、環境が安定しているかどうかは確証がもてないので、参考程度に。

あと、

fujiwara on Twitter: "@takakiku ユーザーデータに関連するものは基本consulには入れないようにしています。kvは大量に更新するとメモリとdisk容量肥大化して、消しても勝手には小さくならないみたいなので"

というコメントもいただき、突っ込んだデータを削除しました。

確かに、Disk使用量が減ることはなかったです。

一方で、メモリの方は解放されているようです(Consul0.6のため?0.5では未検証)。

環境

項目 内容
Consul version 0.6
Consul server 5ノード
Consul client 4ノード
Consul データパス /dev/shm/consul_data(tmpfs)
メモリ(全ノード共通) 16GB
CPU Xeon(R) CPU E5-2407(4コア)
OS CentOS5,6,7混在

という感じで、特にデータは tmpfs 上において試しました。(これは各ノードのDisk性能が一律ではないため、今回の評価用にこの設定にしてあります。)

データの登録

データの登録は下記のようなrubyコードで行いました。Keep-Aliveしながら、一件ごとの登録にかかった時間を記録しています。

#!/usr/bin/env ruby

require 'net/https'
require 'uri'
require 'benchmark'

base_uri = "http://localhost:8500/v1/query"
uri = URI.parse(base_uri)
c = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)

c.start do |x|
  11.upto(1000000) { |i|
    id = sprintf("%07d", i)
    req.body = <<-EOS
    {"Name":"mdb-#{id}","Service":{"Service":"db01","Tags":["master"]},"DNS":{"TTL":"30s"}}
    EOS
    res = nil
    time = Benchmark.realtime do
      res = x.request(req)
    end
    puts "#{id}, #{time}, #{res.code}, #{res.body}"
  }
end

登録は、leaderノード上で実行しました。

登録前後、削除後の状況

登録前は厳密には、10件だけPQを登録した状態です。

  DNS応答(ms) データサイズ(byte) メモリ空容量(byte) 1件登録時間(ms)
登録前 2 262144 6523371520 0.9 〜 1.0(10件登録した時)
登録後 2 134217728 5202753454 1.3 〜 1.6(100万件付近)
削除後 - 134217728 6361238449 -

◼︎ 測定方法について

  • DNSはdigの結果に表示されるQuery timeを取得(CacheにのっていないURLをqueryしてます)。
  • データサイズは /dev/shm/consul_data/raft/raft.db のサイズ。ls より。
  • メモリ空容量は、freeコマンでのfeeの値。
  • 1件登録時間は、登録スクリプトの出力より、目でみておおよその値を抽出。

メモリの状況は下記グラフも載せておきます。下がり始めたところが、100万件データを入れているところ。回復しているところが削除しているタイミングなので、メモリは回復する感じです。

f:id:kikumoto:20151222112055p:plain

まとめ

  • 100万件PQ入れてもDNS引きに関して性能面での劣化はない。
  • データ登録については性能劣化がある。
  • データ削除しても、Disk容量は減らない。
  • データ削除するとメモリは解放される。

実際は各自の用法・設定に合わせて確認してもらうのが一番なので、以上の結果は参考程度にどうぞ。

また、利用用途としても多分ソシャゲのような数百万ユーザが対象なものについて、この方法を採るのはちょっと微妙かなという印象です。DNS引きに影響はないにしても、登録や削除が頻繁なものにはちょっとという気がします。(障害時のデータ復元も大変そう)

自分の想定環境では多くて10万ユーザ、多分1万ユーザくらいの登録で、変動も頻繁でなく、PQのデータはすべてDBから復元可能なので、DNS引きだけでshardを解決できるという利点をとって採用方向で、今後本番環境内でConsulの動作試験していくかなぁという感じです。

何がご要望がいただければ、お正月に試すかもしれません。(ただ寝てるかもしれません)