kikumotoのメモ帳

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

ISUCON6敗退から一週間たってからの振り返り

早いもので、ISUCON6(土曜参戦)から早くも一週間過ぎた。 結果は敗退で、流れは @Leko がまとめてくれているので、基本はそちらをどうぞ。

leko.jp

まぁ今年も悔しい結果に終わったので、その悔しい気持ちのまま書いてもよかったのだけど、少しおついてから来年(?)に向けて振り返りをしてみることにする。

自分の役割は、インフラメインで、あとは全体方針を Leko と考えつつ、ボトルネックがどう変わっていくのか見ていく的な感じでした。

Keep

  • 使われるインフラの事前勉強
  • なんらかのISUCON問題をメンバーと一緒にする。
    • 今回は Pixiv さんの問題 をやった。これと去年の反省を含めて、局所最適化ではなく、大きく変更するための思考回路が多少は身についたと思う。
  • 最低限のタレの準備
    • 必要なツール類(Kataribe とか pt-query-digest とか)やアカウント作成を Ansible ですぐ入れるようにしていた。
    • また、M/W 類は状況に応じてという気がしていたので、基本のインストールスクリプトだけ用意。
  • M/W、OS関連のチューニングはすぐに着手せず、まずは準備が出来次第、自分もコードを読んで作戦面を考える。

Problem

  • Redisをわかってなかった
    • Redis は入れたものの、デフォのまま放置してしまい、アプリ側の挙動を変な状態にしてしまった。これがなければ早いうちに3、4万点台に乗せれていたのでとても悔やまれる。
    • 普段使っていないものは、その場しのぎではダメっていう良い(?)見本です!(申し訳ない)
  • アプリ実装に肩入れしすぎた
    • 今回はベンチがひたすら 0 点が続いて気持ち的な余裕がなくなって、上記 Redis の問題時に自分の本業側の方をきちんと見ずにアプリ実装側を見過ぎていた。
    • 作戦・実装方針以外はまかせて、自分の見るべきところを見るべきであった。

Try

  • ISUCONで使いそうなM/Wは使い込む
    • 普段から使えれば良いが、ISUCONで使いそうなM/Wについては使い込んで、どういう問題が発生するのか特徴を理解しておく。
  • 社内ISUCONの実施
    • いろんな意味で、社内ISUCONをすることでそもそもエンジニアとしての地力をつけたい。
  • 問題の意味することろから攻める
    • 単に重いところをどう軽くするかの方針だけでなく、問題の本質から全体最適化を考えられるようにしたい。

まとめ

今年もよい刺激となり、実力のなさを痛感しました。それでも昨年よりは、点数的にはよくなったと思うので、逆に悔しい気持ちは大きいです。これをバネに日々精進したいです。

ISUCON6の運営のみなさま、今年も楽しい場を設けていただきありがとうございます!

一方で、ISUCON6自体はまだ本線が控えているので、ぜひ諸々頑張ってください!特になにかできるわけではありませんが、応援しています!

iOSDC powered by builderscon に当日スタッフとして参加してきた

iOS Developers Conference Japan 2016 iosdc.jp に当日スタッフとして参加してきました。

(ブログが YAPCスタッフ、JTF登壇と、カンファレンス系ネタが最近多いなと、書きながら感じてるところ)

前夜祭含め、受付をさせてもらってましたので、ほとんどの方とお会いさせていただた感じとなります。 懇親会リストバンドとTシャツを渡しを担当していました。

前夜祭から多くの方にご来場いただいて、カンファレンスとしても大成功といっても良いのではないでしょうか。 受付もご来場者みなさまのおかけで、また他の受付スタッフみなさまのおかけでほぼほぼスムーズにご入場いただけたかなと思います。


ところで、タイトルにも含ませていただきましたが、iOSDC 2016 のページ最下部に

f:id:kikumoto:20160821233214p:plain

とあるのにお気づきでしたでしょうか?

iOSDCは正式に powered by builderscon がついた最初のカンファレンスとなりました(私の認識では)。

そもそも今回当日スタッフをさせていただいたのは builderscon 、およびその流れ(?)で開催された YAPC::Asia Hachioji 2016 mid in Shinagawa でファンになったw @tomzoh さんがiOSDC実行委員長をするからでした。

builderscon そして @tomzoh さんの手助けに微力ながらなれたなら、自分としても大成功だったかなと思っています。

そして builderscon は 12/3 に builderscon.io が開催されます。iOS なみなさまもぜひ参加していただけると良いんじゃないでしょうか。


なにはともあれ、今回スタッフとして参加させていただき、また新しい仲間とめぐりあえて、とても嬉しいです。意外なつながりも発見し、やっぱりスタッフって楽しいなと思いました。 一人一人お礼をいいたいですが、書くのも大変なので、代表して、あらためて実行委員長の @tomzoh さんに感謝したいです。ありがとうございました。

もちろん、スポンサーのみなさま、参加されたみなさま、liveストリーミングで参加されたみなさま、本当にありがとうございました。

この流れだと来年もきっと開催なのかなぁ。その時はまた、なにがしかの形で関われるといいなと思います。

Terraform 0.7でterraform_remote_stateはdeprecated扱い

Terraform 0.7がリリースされましたね。

Terraform 0.7 | HashiCorp

このバージョンからterraform_remote_stateリソースがdeprecated扱いになっています。

今まで

Terraformでの出力を別なTerraformで利用する場合、今まで以下のような感じであったと思います。

出力側
output "repo1_data" {
    value = "Repo1 Data"
}

これをRemote Stateとして、S3に保存するとします。以下のような感じで。

terraform remote config \
    -backend=S3 \
    -backend-config="bucket=bucket-name" \
    -backend-config="key=remote.tfstate" \
    -backend-config="region=ap-northeast-1"
利用側

このRemote Stateを使う側は以下のような感じ。

resource "terraform_remote_state" "repo1" {
    backend = "s3"
    config {
        bucket = "bucket-name"
        key = "remote.tfstate"
        region = "${var.aws_region}"
        profile = "${var.aws_profile}"
    }
}
output "repo1_data" {
    value = "${terraform_remote_state.repo1.output.repo1_data}"
}

これを apply すると以下のように repo1 の出力を取得できます。

$ terraform apply
terraform_remote_state.repo1: Refreshing state... (ID: 2016-08-04 08:26:21.211961588 +0000 UTC)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

  repo1_data = Repo1 Data

そのままで0.7で実行すると

利用側のコードをそのまま0.7で実行すると

$ terraform apply
There are warnings and/or errors related to your configuration. Please
fix these before continuing.

Warnings:

  * terraform_remote_state.repo1: using terraform_remote_state as a resource is deprecated; consider using the data source instead

No errors found. Continuing with 1 warning(s).

terraform_remote_state.repo1: Refreshing state... (ID: 2016-08-04 08:29:31.623162303 +0000 UTC)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

と、deprecated と言われ、かつ repo1 の出力を取得できていません。

0.7でとりあえず出力するには

terraform_remote_stateリソースを使いつつ、出力するには以下のように、outputの記述をなくします。

resource "terraform_remote_state" "repo1" {
    backend = "s3"
    config {
        bucket = "bucket-name"
        key = "remote.tfstate"
        region = "${var.aws_region}"
        profile = "${var.aws_profile}"
    }
}
output "repo1_data" {
    value = "${terraform_remote_state.repo1.repo1_data}"
}

この点は、 terraform/CHANGELOG.md at master · hashicorp/terraform · GitHub に記述されているように terraform_remote_stateの出力がトップレベル属性になったからのようです。

とりあえず、0.6 を利用しているひとは、output を削除する必要があります。

これで以下のように warning は出つつ、出力をとれるようになります。

$ terraform apply
There are warnings and/or errors related to your configuration. Please
fix these before continuing.

Warnings:

  * terraform_remote_state.repo1: using terraform_remote_state as a resource is deprecated; consider using the data source instead

No errors found. Continuing with 1 warning(s).

terraform_remote_state.repo1: Refreshing state... (ID: 2016-08-04 08:50:54.409873377 +0000 UTC)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

repo1_data = Repo1 Data

これから

deprecated の出力はやはり嫌なので、正しい対応としては 0.7 から導入された Data Sources を利用することになります。

Remote Stateに対して 、下記 Data Sources が用意されました。

www.terraform.io

これを利用するには今まで resource と書いていたところを data と書き換えるだけです。出力のoutputを削るのは上記と同じ。

結局以下のような感じ。

data "terraform_remote_state" "repo1" {
    backend = "s3"
    config {
        bucket = "bucket-name"
        key = "remote.tfstate"
        region = "${var.aws_region}"
        profile = "${var.aws_profile}"
    }
}
output "repo1_data" {
    value = "${data.terraform_remote_state.repo1.repo1_data}"
}

実行すると下記のようになります。

$ terraform apply
data.terraform_remote_state.repo1: Refreshing state...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

repo1_data = Repo1 Data

ということで、これからは Data Sources を利用しましょう、ということですね。

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の環境をバージョンアップしているのでこんなことはしなくてよいでしょう。臭いものに蓋をすると一生そこは闇になります。