SSLv3亡き今、ciphersuiteはFIPS@STRENGTH:!aNULL:!eNULLでいいんじゃなかろうか
今までSSL(TLS)のciphersuite設定はmozilla wikiのSecurity/Server Side TLS]の記述を個人的に推奨してきましたが、Historyを追ってるとたまに迷走してるし、今の設定が本当に良いのか怪しくなってきたので、もう
FIPS@STRENGTH:!aNULL:!eNULL
でいいんじゃないかと思いました。 FIPS準拠、PCI準拠になるし。
https://matsuu.net/ は2014年10月現在このciphersuiteを実践中です*1。
反論お待ちしております。
追記:ciphersuite以外の設定は引き続きmozilla wikiのSecurity/Server Side TLS]を参照するか、Generate Mozilla Security Recommended Web Server Configuration Filesをオススメします。
*1:opensslのバージョンは1.0.1j
第4回ISUCON予選にチーム「ご注文はPHPですか?」で参戦して1日目暫定10位になりましたがPHP使ってません
いい感じにパフォーマンスチューニングするコンテスト第4回ISUCONに参戦しました。まだ現時点で本戦に進めるのかわからないのですが、1日目で暫定10位になりました。
PHPでも十分に戦える!と思った方、ごめんなさい。Go言語使いました。
チーム紹介
- チーム名
- ご注文はPHPですか?
- チーム略称
- ごちぺち
- 予選スコア
- 44000〜45000ぐらい(暫定)
Go言語の勉強について
Go言語の経験はほとんど無く、9/18からA Tour of Goを始めた程度の素人。
9/20あたりから前回のISUCON3予選のAMIに含まれてるGo実装でチューニング実践してみた程度。三人ともISUCON出場経験がはあったのでチューニングはなんとかなりました。ISUCON3予選問題のチューニング結果は50000ぐらい。Go言語つええええ。
ISUCON3の予選問題はGo言語の勉強に最適ですよ奥さん。
今回の予選の対応方法
基本的にnginxのアクセスログとにらめっこです。
アクセスログに応答時間を出力するようにして、リクエストURIごとのトータル時間、アクセス回数、平均応答時間を算出する簡単なスクリプトを用意。その数字をみて、どのリクエストを改善すべきかを決定していきました。
いきなりソースを見たり、topやdstatなどでボトルネックを調べたりしたくなるんだけどもそこはグッと抑える。これは過去にISUCONに出た経験から導き出されたやり方でした。
ソースの編集について
幸い全員Vim使いで、ターミナル上で編集することに抵抗がないので、3人とも1台のインスタンスにSSH接続、役割分担しながらプログラムや設定などを書き換えていく感じでした。
BitBucket上のgitにリポジトリを作りましたが、そこからデプロイ&継続的インテグレーションの類は使ってません。サーバ上で編集したものを同じユーザ名でcommit&pushした程度です。
また、リポジトリを一応用意しましたが、綺麗に保つ努力はしませんでした。時間がもったいないから。main.go.hogeファイルとか平気で作ってました。短時間決戦なので気にしない。
どんな実装になったか
ミドルウェアはGoに変えた以外殆ど変わってません。nginx+Go+MySQLです。NginxとMySQLのバージョンアップもしませんでした。
できるだけ前の方で返すべく以下のような実装にしました。
- スタイルシートや画像ファイルなどの静的ファイルはnginxから返す
- ログイン失敗でbanされたIP/ユーザをチェックするためにlogin_logをSELECTしている部分は、ログイン失敗した回数をGo上でカウント、banされたリストもGo言語上で保持してMySQLを参照しない*2
- usersテーブルは初回のデータ投入以降増えないので、初回に全部Go実装上にキャッシュしてGoで返す
- 最終ログイン日時もユーザ毎にGo上で記録しておき、Go上で返す
- トップページは出力パターンが4パターンしかないので、4パターンの静的HTMLファイルを生成しておき、nginxでCookieの値を見てrewriteして静的ファイルを返す
それぞれの修正を適用するたびにアクセスログの応答時間を見て遅いリクエストを改善していく感じですね。
結果としてこのような対策になったので、今回MySQLのチューニングは殆どやってません。my.cnfの設定も大した設定は追加してないし、インデックスも結果的には何も追加しませんでした。
なお、プログラム以外の具体的な変更内容はnetmarkjp先生がブログに詳しくかかれているのでそちらをご参照ください。
便利情報
いくつかピックアップ
BitBucketのプライベートなgitリポジトリと連携できるCIはWerckerが便利
wercker、便利ですよ!今回使ってないけど。boxにwercker/golangを使えばGo1.3系をにも対応してます。
mysqltuner.plが便利
MySQLのざっとしたチューニングはこれを少し参考にしてます。
curl http://mysqltuner.pl > mysqltuner.pl
perl mysqltuner.pl
でも今回は殆ど使わなかった。
iotopコマンドが便利
disk ioを発生させているプロセスが何かわかります。
yum install -y iotop iotop -o
dstatのオプションは-tlamp -N loが便利
今回は1台構成でloしか使わないので-N loをつけると便利です。
yum install -y dstat dstat -tlamp -N lo
loの通信量が多くなれば、おそらくたくさん捌けてるんだな(スコアがあがるかもな)と判断できます。
Goのつらかったこと
いくつかピックアップ
経験が浅い
基礎的なことを把握してなかった。例えばinit()ってどこでどう呼ばれるのか知らなかった。
まとめ
よく言われる「推測するな、計測せよ」ですね。
dstatやtopを見てると計測してる気になるんですが、計測すべきはスコアに直結する応答時間でした、って感じです。
DockerでPublic JNetHack serverを立ててみた
Dockerfileの練習も兼ねて、DockerでPublic JNetHack serverを立ててみました。UTF-8対応のtelnetクライアントを用意して、
telnet nethack.matsuu.net
でJNetHackをプレイできます。全プレーヤー統一ランキング機能があるみたいです。
詳しくはこちら → https://matsuu.net/nethack/
Docker環境があれば誰でもPublic JNetHack serverを用意できます
Docker Hubに登録したので、誰でもサーバを用意できます。
docker run --detach --publish=23:23 matsuu/jnethack-server
同じインスタンスを使っている限りはアカウントとセーブデータは残ります。
手元でこっそりプレイするためのDockerfileも用意しました
こちらもDocker Hubに登録したのですぐにプレイが可能です。
docker run -it matsuu/jnethack
毎回上記コマンドで起動するとランキングが保存されないのでよしなに頑張って下さい。
nginx-1.7.1でsyslogにログを飛ばせるようになったので試してみた
nginxのアクセスログやエラーログをsyslogに直接飛ばす機能は商用版のNGINX Plusでのみ提供されていたのだが、1.7.1でオープンソース版にもその機能が取り込まれた。
Changes with nginx 1.7.1 27 May 2014 *) Feature: the "error_log" and "access_log" directives now support logging to syslog.
早速試してみた。
docker-nginx
syslogサーバのホスト名は仮にlogserverとする。
Dockerfile
FROM centos:latest ADD nginx.repo /etc/yum.repos.d/ RUN yum install -y nginx ADD access_log.conf /etc/nginx/conf.d/ EXPOSE 80 CMD ["/usr/sbin/nginx", "-g", "daemon off; error_log syslog:server=logserver,facility=local2 notice;"]
nginx.repo
[nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=0 enabled=1
docker-rsyslog
syslogを受けるサーバはこんな感じか。
Dockerfile
FROM centos:latest RUN yum install -y rsyslog ADD remote.conf /etc/rsyslog.d/ CMD ["/sbin/rsyslogd", "-c5", "-n"]
remote.conf
$ModLoad imudp $UDPServerRun 514 $AllowedSender UDP, 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 local1.* /var/log/nginx_access_log local2.* /var/log/nginx_error_log
AllowedSenderで0/0が書けなかったのでなんかダサい。もっと良い書き方ないものか。
動作確認
Jun 3 10:53:33 c65d458cb3e9 nginx: 127.0.0.1 - - [03/Jun/2014:10:53:33 -0400] "GET / HTTP/1.1" 200 612 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
エラーログ
Jun 3 10:53:23 c65d458cb3e9 nginx: 2014/06/03 10:53:23 [notice] 23#0: start worker processes Jun 3 10:53:23 c65d458cb3e9 nginx: 2014/06/03 10:53:23 [notice] 23#0: start worker process 25
いいじゃないか、と思うでしょう。しかしsyslogには1行あたりの文字数制限があるため、長いログだとお尻が途切れて残念なことになる。
Jun 3 11:42:42 c65d458cb3e9 nginx: 127.0.0.1 - - [03/Jun/2014:11:42:42 -0400] "GET /12345678901234(中略)012345678
syslog自体は2048文字あたりが上限になるようだが、手元で試した限りは2043文字が上限になった。このあたりの詳細は調べてない。
nginxの派生で独自にsyslog対応されているTengineでも試したが、2043文字あたりが上限になるのは同じだった。syslogの制約だからそりゃそうか。
まとめ
ログをコンテナ内に蓄積しないことでよりImmutable Infrastructureっぽくなるし、1コンテナ1プロセスを実現できていいのだがsyslogには文字数制限があるので注意。
ちなみにnginxから直接fluentdに飛ばせるnginx-fluentd-moduleも試したのだが、受信側fluentdにfluent-plugin-udpが必要なのはまぁ良いとしても、記号などのエスケープ処理周りが怪しい感じで若干微妙だった。こちらもその内紹介できればと思う。
追記
@matsuu nginxのsyslog出力はNGX_MAX_ERROR_STR(2048で定義)にsyslogのヘッダを加えた文字数のバッファを持っていて、色々プラマイして実質2000文字前後ですね。
— Takashi Takizawa (@ttkzw) 2014, 6月 3
オープンソースになったFC2ブログをDockerで構築してみた
FC2ブログがオープンソースになったと聞いたので、Dockerfileの作成練習も兼ねてDockerで構築してみた。ソースはこちら。
https://github.com/matsuu/docker-fc2blog/
工夫したこと
作ってみてわかったこと
改善が必要なところ
- セキュリティを考慮してmysql_secure_installを実行したい
- ログ周りをsyslogかfluentdに吐くようにしたい
- fc2blogはMySQLのMaster-Slaveに対応してるようなので対応する
- Nginxに対応させたい
- phpのセッションをmemcachedに食わせ、ロードバランサも用意してスケールアウトしたい
クラスタ構成のCoreOSでfleetを使ってウハウハしたい- fleet経由で起動できるようにしたがetcdを活用できてない
- Apache(ブログ部分)だけ更新する手段を用意する
- テストする仕組みを考える
- プロセス監視、サービス監視
Gentoo版をまだ用意してない- 用意した
さくらのクラウドでCoreOSを動かしてみた
最近になってようやくDockerに目覚めまして、本番環境にDockerを使った場合の監視方法などを模索している今日このごろ。
ちょうどオープンソースカンファレンスでさくらのクラウドの2万円分無料クーポンをもらった*1ので、さくらのクラウドにGentooベース(のChromeOSベース)で有名なCoreOSを載せてDocker環境を構築してみた次第。さくらさんありがとう!ありがとう!ありがとう!
どうすればCoreOSを構築できるか
さくらのクラウドではKVM/QEMUを使用しており、CoreOSはQEMU用イメージを用意しているものの、ホスト側を操作できるわけではないのでこの方法は取れない。
そこでInstalling CoreOS to Diskを参考に構築することにした。
CoreOSを起動するサーバをまず用意する
さくらのクラウドはDHCPでIPアドレスが取得できず、またCoreOSのcoreユーザにはパスワードが設定されていないため、Installing CoreOS to Diskの手順でそのまま構築するとSSH、コンソールのどちらからもアクセスできなくなってしまう。
そこでまずIPアドレスを決定するためにブランクディスクでサーバを作成する。
作成後、NICタブを押して以下の4つを控えておく。
また、ディスクタブでHDDを取り外す。
Ubuntuサーバを用いてDiskにCoreOSをインストール
つづいてUbuntuでサーバを作成。先ほど取り外したディスクを接続して起動。手順はInstalling CoreOS to Diskのとおりだが、さくらのクラウドに合わせて適宜読み替え。
wget https://raw.github.com/coreos/init/master/bin/coreos-install chmod +x coreos-install sudo ./coreos-install -d /dev/vdb cat > cloud-config.yml <<EOF #cloud-config.yml ssh_authorized_keys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h...(ssh公開鍵を記述) write_files: - path: /etc/systemd/network/10-static.network content: | [Match] Name=ens* [Network] Address=(IPv4アドレス)/(ネットマスク) Gateway=(ゲートウェイ) DNS=(推奨ネームサーバ1) DNS=(推奨ネームサーバ2) EOF sudo mount /dev/vdb6 /mnt sudo cp cloud-config.yml /mnt/ sudo umount /mnt
CoreOSを起動する
ここまでできたら一旦Ubuntuサーバの電源を落として20GBの追加ディスクを取り外し、CoreOSサーバに接続しなおして起動。
ssh core@(IPv4アドレス)
で接続すればok。
______ ____ _____ / ____/___ ________ / __ \/ ___/ / / / __ \/ ___/ _ \/ / / /\__ \ / /___/ /_/ / / / __/ /_/ /___/ / \____/\____/_/ \___/\____//____/ core@localhost ~ $
ヒャッホーイ!
まとめ
*1:実はもらったクーポンを紛失したので中の人に再発行してもらった
Mac Pro(Late 2013)を火鉢に見立てて暖を取る方法
Appleの初売りに並んでる皆様、寒い中お疲れ様です。寒いですね!ツライですね!
そんな時は最新のMac ProのCPUをぶん回せば暖かくなるかもしれませんね!
え?インターネット接続環境がないからベンチマークソフトをダウンロードできない?大丈夫、Mac OS Xに標準で含まれているソフトウェアでお手軽にCPUをぶん回すことが可能です。
- Finder→アプリケーション→ユーティリティ→ターミナル
- CPUが論理12コアの場合
openssl speed -multi 12
- CPUのコア数がわからない場合
openssl speed -multi `getconf _NPROCESSORS_ONLN`
これでしばらくはCPU負荷がガンガンかかり、Mac Pro上部の排気口がほのかに暖かくなりますよ!良かったですね!良かったですね!
もしかしたらアップルストアの店員さんがMac Proを用意してくれるかもしれませんね!ご期待ください!
ご参考
きっかけはTwitterから。
【緩募】インターネットに繋がってないヨドバシのMac ProでカジュアルにCPU負荷をかける方法
— 一年の計は元旦にGentoo (@matsuu) 2013, 12月 29
@matsuu yes hoge > /dev/null で論理1コアフルに食いつぶします
— polamjag (@polamjag) 2013, 12月 29
yes > /dev/nullでもok。ただ論理CPU1つ分しか負荷がかからないので論理CPUの数だけ起動が必要となる。[ (っ´∀`)っ@友の会 ~]$ while :; do cat /dev/zero > /dev/null & done> @matsuu
— 謹賀新 (っ´∀`)っ ねーん (@nullpopopo) 2013, 12月 29
どんどんプロセスを立ち上げるのでこれはfork bombに近い。やっちゃダメー。
@matsuu openssl speed -multi X
— Mitsuru SHIMAMURA (@smbd) 2013, 12月 29
openssl speedはOpenSSLが対応するアルゴリズムの処理速度を計測するベンチマーク。-multiで指定された数だけパラレルに実行されるのでカジュアルにCPUに負荷をかけられる。これは素晴らしい。