障害対応の裏側で何をやっているかの話
Fusic 平田です。
基盤ユニットの追加モジュール的な何かになりました。
何書こうかなーと思い、最近あったtypoとの悲しい戦い*1をまとめなおすとかでも良かったんですが、せっかくなので違う話を。
サイトが閲覧できない!な時に何をやっているか
障害対応なんかに遭遇しやすい、あるいは呼ばれやすい性質でして。
その時何やっているのかって話を少し。
あわてない、さわがない、はしらない
まあとりあえず。
何もいい結果に繋がらないので。
起きている状況をなるべく正確に知る
「全く閲覧できない」なのか、「閲覧できるけどすごく重い」なのか、それだけでも大きな違いなので、状況確認は正確に。
ネットワーク的に到達できるのか、サーバにログインできるのか
これすらできない場合は、
- ネットワーク起因だったりするので周辺の状況(経路でネットワークダウンの障害報が出てないかなど)を確認する
- OSがハングしている場合は、再起動を試みる
といった対応にシフトします。
リソースの使用状況の確認
dstatで確認することが多いです。
リソース監視を行っているのであれば、そのグラフ状況を見るなどして、リソースの使用状況を確認します。
- メモリが枯渇している
- CPUを使い過ぎている
- I/O待ちが発生しまくっている
といった感じで、ボトルネックを特定します。
ログを見る
/var/log/
以下であったり、アプリケーションのログであったりを確認して、特異な(OOM Killerなんかは特異の典型)ログが出ていないかを確認します。
特異点の判断ポイントとしては
- 明らかに普段出ないログが出力されている
- ログの量が普段より明らかに多い
といった観点になるでしょうか。
ただ目で追うのもさすがに辛いので、grepなりwcなり、コマンドと組み合わせて原因を探る感じです。
あと、アクセスログを精査するのであれば、Kataribeが便利です。
ISUCON御用達ツールですが、負荷の高い箇所だったりアクセス増だったりの一次調査で使えます。
対策を決めて実行する
原因が明確に特定できたのであれば、対応する内容も明確になります。
アプリケーションの修正であったり、ミドルウェアの設定値変更であったり。
緊急度と対応時間とを天秤にかけて、場合によっては一次対応(応急処置)と二次対応(抜本的な対策)を分けるケースもあります。
原因が分からないケース
というのも当然あるので、その際は出力するログを増やすなどして網を張るようにしています。
実例だとこんな感じ
1ヶ月ほど前に起きた事例ですが。
- 状況としては「繋がるけどすごく重い」 → OSがハングしているとか、全く手が付けられないわけではなさそう
- ssh繋いでみたところ、接続できた → 障害報もないし、ネットワークはあまり関係なさそう
- リソースを確認するとロードアベレージが異様に高い → CPU起因だから、どこかで重い処理が走っているとか?
- ログを確認すると、httpサーバのログが大量に出ている → アクセスが相当増えた?
- アクセスログを精査する → 特定のページに対してアクセスが集中していることが分かった(原因判明)
- 特定のページと関連リソース(ページ内の画像)に対して一時的にキャッシュするよう設定変更(対策)
実例その2
こんなケースも。
- 「サイトに繋がらない」 → あらゆる可能性あり
- ssh繋いでみたところ、接続できた → ネットワークはあまり関係なさそう、OSも大丈夫そう
- リソースはどれもおおむね問題なし → 明確な原因が不明
- ログを確認するが、どれも平常通り → 明確な原因が不明だけど、httpのプロセスがうまく動作しなくなっているのかもしれない
- 応急措置としてhttpサーバを再起動(一時対応)したら復旧した → 引き続き注視しつつ、ログを精査するなどして調査
- 特定の処理が重くて落ちた可能性がある → 開発環境で再現するかを検証(原因判明)
- 再現したのでアプリケーションを修正してリリース(抜本的な対策)
というわけで
何かものすごいことをやっている話ではないので恐縮なのですが、こんな感じで障害対応していますって話でした。
余談: ログをもっといい感じに可視化して集中管理したい
可視化 + 集中管理の仕組みを設ければ、調査系で呼ばれる回数が減りそうだなーと。
前時代感なまま過ごしていたんですが、この辺をKibanaに集めるような仕掛けをぼちぼち組まねばな、と。
って書いてしまったので、今年の前半はその辺を整備していきます。
*1:100以上のコミットを経て、ようやく落ち着いた。と思う。
cakephp/cakephp にPR 出してmerge された話
(Fusic Advent Calendar 24日目)http://qiita.com/advent-calendar/2016/fusic & (CakePHP3 AdventCalendar 24日目)http://qiita.com/JoJeongMin/items/9fbc4cc1de9268b5de56http://qiita.com/advent-calendar/2016/cakephp3です。
Fusic 新卒の濱野です。
基盤ユニットに配属されてまもなく半年。
周りの席にはその道10年の職人さんが多く座っているので、
いつもつらい気持ちで席についています。
そんな肩身の狭い新卒ですが、
最近少しだけ胸をはれることがありました!
それは、、、
http://bakery.cakephp.org/2016/12/11/cakephp_3310_released.html
そう。cakephp の core に出したPR が merge されたのです!!!
これはめでたい!!!
ということで、今回は、PR がマージされるまでの模様を時系列に沿ってお伝えしようと思います。
これを機に、PRの数が増えるとうれしいです!!!
何なおしたの?
pagination のバグを修正しました。
$paginate = [ 'limit' => 30, 'maxLimit' => 20, ];
という設定をした時に、
maxLimit => 20
が無視され、
limit => 30
が採用されていました。
つまり、 maxLimit
がちゃんと動いていませんでした。
どうやって見つけたか?
プラグインを作っていたら、挙動がおかしかったのでcore を読みました。
ちなみに、core は極力読むようにしています。
そして、時々ブログなどに結果報告を書いています。
その癖をつけていたおかげで、割とすんなり問題箇所の特定ができました。
そして、何が原因なのかがわかりました。
issue を登録する
こんなissue を登録しました。
https://github.com/cakephp/cakephp/issues/9848
全部英語で書くのが意外と大変でした。
PR を投げる
ついでに、issue に紐付ける形でPR も出しました。
I showed an example to fix this bug in #9849 , please review it, and I expect for some comments. If my PullRequest is not worth to merge, don't hesitate to close it.
って書いて。
超意訳すると、
一応このissue を解決するPR 送りますー
っていう感じです。
https://github.com/cakephp/cakephp/pull/9849
中の人とやり取りする
PR を出すとすぐ、chinpei215
さんが調整してくださいました。
そして、マージされるまで面倒を見てくださいました。
この場を借りてもう一度お礼させて頂きます。
本当に有難うございました。
結局やり取りをしたのは2人でした。
一人は前述のchinpei215
さん。
もう一人は、dereuromark
さん。
お二方とやり取りし、コードを修正しました。
そして、気づいたらマージされていました。
PR を出してから Merge されるまで1日もかかりませんでした。
感想
中の人は、優しかったです。(もちろんご指摘も頂きましたが)
そして、社内の人から声をかけられる機会が増えました。
これからも何かあったらどんどんプルリク出していこうと思います。
以上、未経験から入った新人が (cakephp/cakephp)https://github.com/cakephp/cakephp/ にPR を送ってマージされた話でした!
FluentdのログフォーマットでS3に保存されたApacheのアクセスログをAmazon Athenaで集計する
突然の Amazon Web Services Advent Calendar 2016 の 15日の記事です
基盤ユニットの小山 ( @k1LoW )です。
AWS re:Invent 2016すごかったですね。
数多くのサービスが使える形でリリースされてきました。
ただ、個人的にはその後の aws-sdk-ruby が v3に上がる というエントリーを見て、awspecをどうしようか戦々恐々としています。
awspecを aws-sdk-ruby v3.0.0.rc2 で動かしてみようと思ったら、依存している https://t.co/TIuG9dGHfH のテストが v3.0.0.rc2 失敗したので、1回休み
— k1LoW (@k1LoW) 2016年12月14日
突然のアクセスログ集計
あるAWS上に構築しているシステムプロジェクトで、突然「月単位でのアクセス集計1年間分」という要望がどこからともなく降ってきました。
そのプロジェクトでは、アクセスログを含む様々なメトリクスをFluentd ( td-agent ) で収集して、S3のバケットに保存しています。
ただ、保存の目的がいざという時のためで、稼働している分析基盤はありませんでした。
そこで、まずはローカルのMacBook ProでDigdag+MySQLによる集計を試みました。
が、
1日立ってもログ取得が終わらず。。。
(そういえば今まではdstatのような定期的に取得するメトリクス情報のログ集計で、アクセスログのようなさらに大量のデータの取得はしていなかった。。。)
さてどうしようかとなった時に、ふと思い出したのが、そう、Amazon Athenaでした。
そうだ、Amazon Athena を使ってみよう
Amazon Athena、ざっくり紹介するとマネージドなPrestoです(ざっくりすぎる)。
AWS提供で、S3との相性がとてもよさそうなので、もしかしていけるのでは?と思って試してみたらできました。
前提
アクセスログは s3://[bucket-name]/access_logs/[ec2-hostname]/[year]/[month]/[day]/access_log.xxxxx.xxx.xxx.gz
みたいに保存されています。
S3のバケット自体はap-northeast-1 (Tokyoリージョン)にあります(Amazon Athena自体はTokyoリージョンではまだ提供されていませんが、S3バケットの指定はできますよ!)。
実際のアクセスログはFluentdの一般的な(?)ログフォーマットで、
2016-12-19T04:35:27Z ip-10-xx-xxx-xxx {"host":"xxx.xxx.xxx.xxx","user":"-","method":"GET","path":"/path/to/?q=query","code":"200","size":"1234","referer":"-","agent":"Some User-Agent"}
というような、タイムスタンプとhostnameとJSONの複合形式です。
テーブルの作成
本来ならば「Add Table」 リンクを押してデータベースの作成からするほうがいいのですが、今回は
Query Editorで、おもむろに以下のクエリを実行して集計用テーブルを作成しました。
CREATE EXTERNAL TABLE IF NOT EXISTS default.access_logs ( date date, hour int, min int, second int, z string, host string , ip string, user string, method string, path string, code int, size int, referer string, agent string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ( 'serialization.format' = '1', 'input.regex' = '^(.+)T(\\d+):(\\d+):(\\d+)(.+)\\t([^\\s]+)\\t\\{"host":"([^"]+)","user":"([^"]+)","method":"([^"]+)","path":"([^"]+)","code":"([^"]+)","size":"([^"]+)","referer":"([^"]+)","agent":"([^"]+)"\\}' ) LOCATION 's3://[bucket-name]/access_logs/'
ポイントは 'input.regex' = '^(.+)T(\\d+):(\\d+):(\\d+)(.+)\\t([^\\s]+)\\t\\{"host":"([^"]+)","user":"([^"]+)","method":"([^"]+)","path":"([^"]+)","code":"([^"]+)","size":"([^"]+)","referer":"([^"]+)","agent":"([^"]+)"\\}'
でFluentdのログフォーマットに合わせた正規表現を設定しているところです。
集計SQLの実行
ここからは簡単です。
1クエリごとに小さくない金額がかかりますが、突然の依頼なので悠長なことは言っていられません。
そこは札束で殴るように
SELECT MONTH(date) AS month, count(*), SUM(size) AS total_size FROM rkb_web_public_access_logs WHERE host IS NOT NULL AND date >= CAST('2016-01-01' AS DATE) GROUP BY MONTH(date) ORDER BY total_size DESC
などと、フルスキャンでがっつり集計などしました。
まとめ
Amazon Athenaは思った以上に気軽に使えました。
ただ、クエリごとに課金されるので、ご利用は計画的に。
突然のアクセスログ集計などには良いと思います。
よい突然ライフを。
おまけ
Amazon Athenaで課題解決できた話をきばんブログで書いていたのに、レビュー中に、本家に同じようなのを出されて二番煎じみたいになってしまっている(レビュー待ち)
— k1LoW (@k1LoW) 2016年12月14日
Dockerで開発環境・テスト環境を作る
こんにちは、2回目の登場になります。
基盤ユニットの櫻川です。
みなさんはDockerを利用してるでしょうか?
Fusicではまだまだ開発環境は Vagrantを複数立てる
が主流ですが、
今はDockerの布教活動を行っている真っ最中です。
そもそもDockerを導入した目的
目的は 複数PHPのバージョンを同時に起動したい!
です。
というのも、Fusicでは受託開発を行っていることもあり、プロジェクト毎に利用するPHPのバージョンやデータベースの種類・バージョンが異なること多いです。
そのため現在ではプロジェクト毎等でVagrantを新規で立ち上げたり、phpbrewを利用してPHPバージョンを切り替えたりして開発を行っています。
基本的にVagrantとphpbrewで複数PHPを利用することは可能だったのですが以下のような不満もありました。
- Vagrant
- 起動に時間がかかる
- 複数起動すると結構重くなる
- phpbrew
- バージョン切り替えにApacheの設定を変える必要がある
- 同一サーバー内で同時に複数バージョンを起動できない
そこで全てを解決してくれるDockerの出番なわけですよ!
利用している環境
Windowsです。
ただ、Docker自体はVM上のCentOS7で実行しているのでMacでも問題ないと思います。
- Windows
- Vagrant
- Hyper-V
- CentOS7(ホストOS)
- Apache(リバースプロキシ用)
- Docker + Docker Compose
- Apache + PHP
- Postgres
- MySQL
- samba
Dockerの構成
Dockerのコンテナをポート転送を設定して、最低でも3台のコンテナを起動しています。 ※必要なPHPのバージョン分 + データベース(Postgres or MySQL) + samba
この時点で「複数のPHPバージョンを同時に触りたい」という目的は達成しています。
ただし、このままだとDockerのポート転送を使っているので、PHPにアクセスするときのURLが http://example.com:8080/hoge/fuga
というようにポート指定が必要になってきます。
ポート指定
をするのは嫌なのでDockerコンテナの前にリバースプロキシを置くことでポート指定をすることなく複数のPHPにアクセスすることを実現しています。
これで完全に目的達成!
また、ファイルの修正自体はsambaを経由して行っています。
どうやって作るの?
1. Dockerインストール
DockerをホストOS(CentOS7)にインストールします。
tee /etc/yum.repos.d/docker.repo <<-'EOF' [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF yum install docker-engine systemctl enable docker.service systemctl start docker
2. sambaコンテナを立てる
samba用コンテナをCentOS6で起動します。
※dockerコンテナ内のsambaの設定は行ってください。
yum install samba
など
※ホストOS上の /var/www/html
をsambaコンテナでマウントしています
docker run -itd --name samba -p 139:139 -p 445:445 -v /var/www/html:/var/www/html centos:6 /bin/bash
3. Postgresコンテナを立てる
Postgres用イメージを利用してPostgresコンテナを起動します。
MySQLでもかまいません。
※{Postgresパスワード}
はパスワードを設定してください
docker run --name postgres -e POSTGRES_PASSWORD={Postgresパスワード} -d -p 5432:5432 -e PGDATA=/var/lib/postgresql96/data postgres
4. Apache + PHPコンテナを起動する
Apache + PHPコンテナをCentOS6で起動します。
※dockerコンテナ内のApache + PHPの設定は行ってください。
PHPの必要なバージョン分コンテナを起動します。
docker run -itd --name PHP -p 8080:80 -p 443:443 --link postgres --volumes-from=samba centos:6 /bin/bash
5. ホストOS上でリバースプロキシを設定する。
ホストOSにApacheをインストールし、リバースプロキシを設定します。
※コンテナ上にApacheを立ててリバースプロキシを行ってもいいのですが、dockerを知らない人でも触りやすいようにホストOS上にApacheをインストールしています。
PHPを複数起動したいので、実際はVertualHostと組み合わせています。
ProxyRequests Off ProxyPass / http://hoge.example.com:8080/ ProxyPassReverse / http://hoge.example.com:8080/
6. イメージをAmazon ECR上に保存する
実行しているDockerコンテナをイメージ化して、ECR上に保存してます。
- ECR上にリポジトリを構築しておいてください。
- aws cliをインストールしておいてください。
docker commit samba samba docker commit php aws ecr get-login --region ap-northeast-1 出力されたログインコマンドを実行 docker tag samba 発行されたECR用sambaリポジトリURL docker tag php 発行されたECR用phpリポジトリURL docker push 発行されたECR用sambaリポジトリURL docker push 発行されたECR用phpリポジトリURL
最後
上記を実行することで最低限のPHP開発・テスト環境を構築することができます。
ただ、公開環境で起動する場合は公開するポート等セキュリティに注意してください。
また、このままだと起動するのが非常に手間なので、Dockerfile + Docker Composeにまとめています。
Dockerを使ったことない人は是非!
ガラケー対応の話
Fusic 基盤ユニットの濱野(@gorogoroyasu) です。
全く未経験から入社した、2016年入社の新卒です。
諸先輩方のように圧倒的な記事はかけないので、僕のスマホ遍歴でも書いていこうと思います。
僕のスマホ遍歴
iPhone 4S iPhone 4 (4Sがアスファルトに直撃して画面が全壊したのでヤフオクで購入。この子は最終的に裏面が全壊) iPhone 5S arrows M02 (あまりに動作が遅く、親に譲った。使用期間半年。) iPhone SE (←今)
ずっとiPhone を使っていたからAndroid を偵察してみよう! と思って買った arrows M02 が想像以上の遅さで、
これまで以上にiPhone が好きになった。
ちなみに、最後に使ってたガラケーのことはさっぱり覚えてない。
ガラケー対応プラグインの必要性
そんな僕が、ガラケー対応のプラグインを作成した。
理由は、スマホのシェアがそこまで高くないから。
ここにシェアがまとめてある。
www.nikkei.com
その中から抜粋すると、
スマホの普及率 : 67.4%(前年度比6.8ポイント増)
スマホ以外の普及率 : 64.3%(前年度比5.5ポイント減)
という感じ。
依然としてガラケーユーザーもいる模様。
(ガラケーでWeb サイトを閲覧する人がどれだけいるのかは別の話。通話はガラケーとかいうめんどくさい選択をしている人もいるし。。。)
しかし、なぜガラケー用のプラグインなるものが必要になるのか?
それは、、、
PC、スマホとガラケーでは、色々な違いがあるから。
たくさん違いがあるが、個人的に重要だと思う違いは、
1) 文字コード
2) クッキー使用の可否
3) 外部CSS の読み込み
4) JavaScript 使用の可否
の4つ。
それぞれ簡単に説明していく。
1) 文字コード
最近のPC,スマホサイトには、文字コードは"UTF-8" が採用される。
しかし、ガラケーの文字コードは"Shift-JIS" である可能性が高い。
可能性が高いと言っているのは、
携帯キャリア、製造年月によってはUTF-8 が使用できることがあるからだ。
しかし、大事なのは、文字コードは "Shift-JIS" を使った方が安全だということだ。
ということで、全ての文字は、 UTF-8 から Shift-JIS に変換されなくてはならない。
めんどくさい。
2) クッキー使用の可否
基本的に、ガラケーではクッキーを使うことができない。
では、どうやってログイン情報等を管理するか?
URL の末尾にセッションID をつける。
それにより、ログイン情報等を管理する。
実に原始的。めんどくさい。
3) 外部CSS の読み込み
ガラケーでは外部CSS が使用できない(ことが多い)。
そのため、CSS を直書きする必要がある。
<div class="hoge" style="color: green;">hoge</div>
みたいな感じ。
めんどくさい。
4) JavaScript 使用の可否
基本的にガラケーではJS を使うことができない。
悲しい。
と、ざっくり上げただけでも4つの違いがある。
特に面倒くさいのは1) と 2) 。
ここらへん、なんとかしたい!!
作ったプラグイン
ということで、 上記 1) と 2) をいい感じで解決するプラグインを作った。
--- 追記 ---
何のプラグインを作ったかが文章だけで分からないというご指摘をいただき追記。 作成したプラグインは、CakePHP3 用のものです。
--- 追記終わり ---
本当は 3) もなかなかめんどくさいんだけど、
いい感じにテンプレートとか拾ってきて対応して下さいー。
一言対応策
1) 文字コード
本プラグインでは、文字列の変換を
public function afterLayout(Event $Event, $layoutFile)
で行った。
詳細は Garak/src/View/Helper/EncodeHelper.php
を参照。
2) クッキー問題
redirect をいじって、クッキー情報をクエリに持たせた。
詳細は、k1low/yak
を参考に実装。
プラグインはcomposer を使って ここ からインストールできます。
名前は、 "Garak" !
ぜひ使ってみて下さい。
と、言いたいけど、
近い未来このプラグインが不要になることを願ってやみません。
あとがき
というわけで、初めてのチームブログを書かせて頂きました。
いかがでしたか?
よかったら、コメントなりなんなりよろしくお願いしますー。
CakePHP3でエラーを自由自在に処理するencount
基盤ユニットリーダーの櫻川です( @kozo )。
さて今回はまたCakePHPに戻って、自分が作成しているencount プラグインについて書かせてもらいます。
encountはこちらになります。 github.com
encount 何が出来るの?
PHPが出力する Notice
、 Warning
や Exception
といったエラーに対して、簡単にフック処理するを作ることが出来るプラグインになります。
例えば、本番環境にリリースしたサービスにencountを入れておくと、Noticeが出たタイミングでメール通知を行うといったことが可能となります。
また、 Senderクラス
というencount専用のクラスを実装することで、エラー時の処理を自由にカスタマイズすることが可能です。
例えば、「Slackに通知する」や「NoticeやWarningはメールに通知するけど、FatalはSlackに通知する」といったようなことも可能となります。
※ Railsだと、 exception_notification
が近い分類になると思われます。
encountのインストール
お決まりのcomposer経由にインストールになります。
composer require fusic/encount
encountの設定
ErrorHandler
をCakeデフォルトのものから、encountのものへ切り替えます。
config/bootstrap.php
で設定されてます。
// config/bootstrap.php <?php // shell use Encount\Console\EncountConsoleErrorHandler; (new EncountConsoleErrorHandler(Configure::read('Error')))->register(); // web use Encount\Error\EncountErrorHandler; (new EncountErrorHandler(Configure::read('Error')))->register();
encountはデフォルトの状態だと、Notice等何らかしらのエラーが発生したタイミングでメールを送信します。
その為、メール送信用の設定をします。
// config/app.php <?php return [ // Errorを修正 'Error' => [ 'errorLevel' => E_ALL, // exceptionRendererを追加 'exceptionRenderer' => 'Cake\Error\ExceptionRenderer', 'skipLog' => [], 'log' => true, 'trace' => true, // encount用設定を追加 'encount' => [ 'force' => false, 'sender' => ['Encount.Mail'], 'mail' => [ 'prefix' => '', 'html' => true ] ], ], // Emailにerrorを追加する 'Email' => [ // encount用設定を追加 'error' => [ 'transport' => 'default', 'from' => 'from@example.com', 'to' => 'to@example.com' ] ], ];
encountの確認
デフォルトの設定では、 開発時はエラーを通知しないようになってます。
ですので、 debug
を0に設定して、
echo $a['test']
というような存在しないキーにアクセスしてNoticeを発生後、メールが送信されれば設定OKです。
※開発時でも通知を行いたい場合は、 app.phpに先ほど設定した、 Error.encount.force
を true
に設定してください。
Senderを使って拡張する
さて、デフォルトの設定ではなく、通知を自作したい場合は、 Senderクラス
を作成することになります。
例としてエラー内容を Slackで通知するSender
を作成します。
1.SenderClassを作成する
src/Sender/Slack.php <?php namespace App\Sender; use Encount\Sender\SenderInterface; class Slack implements SenderInterface { public function send($config, $code, $errorType, $description, $file, $line, $context) { // エラーが発生した時の処理をここに書く $url = '{{Incoming WebHooks URLを記載する}}'; $data = array( 'text' => $description, ); $options = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => json_encode($data), ) ); file_get_contents($url, false, stream_context_create($options)); } }
2. SlackSenderを使うように設定する
config/app.php <?php 'Error' => [ 'errorLevel' => E_ALL, 'exceptionRenderer' => 'Cake\Error\ExceptionRenderer', 'skipLog' => [], 'log' => true, 'trace' => true, 'encount' => [ 'force' => true, // 作成した SlackSender に切り替える 'sender' => ['Slack'], // Mail + Slack両方送信する場合は、以下のように2個並べる // 'sender' => ['Encount.Mail', 'Slack'], 'mail' => [ 'prefix' => '', 'html' => true ] ], ],
3. 動作確認
先ほどと同じく、echo $a['test']
というような存在しないキーにアクセスしてNoticeを発生してSlackが送信されればOKです。
最後に
気になった方はぜひ!encount使ってみてください!
そして、encountへの プルリク、Issue、Watch、Starよろしくお願い致します。
CentOS5/RHEL5系でSHA-2/TLS1.2のアウトバウンドのhttps通信を行う方法を検討してみる
基盤ユニットの貞方(@sadapon2008)です。
今回は刺さる人には刺さるCentOS5/RHEL5系でSHA-2/TLS1.2のアウトバウンドのhttps通信の実現方法を検討してみたいと思います。
背景
CentOS5/RHEL5系はすでにサポートが切れていますが、諸事情でまだ稼働しているシステムがあったりします。 CentOS5/RHEL5に含まれるOpenSSLは0.9.8eのため、curlなどOpenSSLをベースにアウトバウンドのhttps通信を行う場合、SHA-2やTLS1.2には未対応です(SHA-2はOpenSSL 0.9.8o以降、TLS1.2はOpenSSL 1.0.1以降が必要)。 しかし、世の中の流れでhttps通信で使うサーバ証明書の署名アルゴリズムはSHA-1からSHA-2への移行が進んでいて、 TLSのバージョンもAPIサービスによっては1.2でしか受け付けないものも出てきています。 そこで、CentOS5/RHEL5系で外部とSHA-2/TLS1.2のhttps通信を行う方法を検討してみました。
案1. 最新のOpenSSLをソースコードからコンパイルしてインストールする
最初に思いつくのは、最新のOpenSSLをソースコードからコンパイルしてインストールすることです。 ただし、ディストリビューションの標準パッケージのOpenSSLを上書きするようなことをするとOSがぶっ壊れる可能性が高いため、 標準パッケージと競合しないようにインストールしないと危険です。 その場合、コンパイルしてインストールしたOpenSSLでhttps通信するためには、curlなどOpenSSLを利用するプログラムも ソースコードからコンパイルしてインストールする必要があります。
また、PHPなどサーバサイドのアプリケーションなどでそれらを利用するには、アプリケーションのソースコードの大幅な変更も必要になります。
案2. 別途リバースプロキシサーバを用意する
CentOS5/RHEL5より新しいOpenSSLを利用できるCentOS7/RHEL7などでリバースプロキシサーバを用意して、そちら経由でhttps通信を行うことも考えられます。
例えば、「https://api.hoge.com
」のURLでアクセスしていたものが、「http://(リーバスプロキシサーバのIPアドレス)
」のURLでアクセスするように構成することが可能です。
この方法の場合、PHPなどサーバサイドのアプリケーションはアクセスするURLの修正だけで済むため、案1.に比べたら変更量を抑えられます。
ただし、別途サーバを準備する必要があります。
案3. CentOS5/RHEL5上でJava 1.7のリバースプロキシサーバを動作させる
CentOS5/RHEL5のディストリビューンの標準パッケージにはJava 1.7が含まれています。 Java 1.7自体もすでにサポートは切れていますが、実はJava 1.7はSHA-2/TLS1.2に対応していますので、Javaで動くリバースプロキシサーバを動かせば、別途サーバを用意する必要がありません。
Javaはずぶの素人なのですが、下記のGithubのコードを参考にJettyの組み込みプロキシを使うプログラムを作成してみました。
作成したものがこちらになります。
gradlewを使っていますので、以下のようすればビルドできると思います。
$ sudo yum install java-1.7.0-openjdk-devel $ chmod a+x gradlew $ ./gradlew fatJar
ビルドに成功したら、以下のようにコマンドを実行すると「http://127.0.0.1:8080
」で待ち受けするリバースプロキシとして動作します。
$ java -jar ./build/libs/simple_reverse_proxy.jar https://api.hoge.com 8080
この状態で下記のようにするとSHA-2/TLS1.2のサーバに対してhttps通信を行うことができます。
$ curl http://127.0.0.1:8080/
正直Jettyの中身はまだよくわかっていないところもあるのですが、superviosrなどと組み合わせればデーモン化したりもできそうです。