続 カッコの付け方

AWSを始めとしたクラウドコンピューティング全般と、唯一神emacsにおける()の付け方についてだらだら書きます

VPC Flowlogが見づらいので、htmlでViewer作ってみた

VPC flowlogという機能が最近リリースされました。SGを通過した・蹴られたのログが取れるというものです。これ自体はとてもありがたいのですが、ログの閲覧はCloudWathLogsからとなり、コレがイケてない。だから何とかしたという話

どんなふうにイケてないのか

CloudWatchLogs上の見え方ですが、こんなかんじです。 f:id:iga-ninja:20150816210033p:plain

フィルタで頑張ることも出来なくはないのです。たとえば80ポートへのアクセスで絞るなら[スペース]80[スペース]とかでフィルタかければなんとかいけます。ただ、Unixタイムスタンプはキツイよねー

で作りました

gist.github.com

f:id:iga-ninja:20150816210256p:plain

f:id:iga-ninja:20150816210238p:plain

機能解説

ローカル実行可能 Credential別サーバに投げるとかない

ローカルにおいたhtmlファイルを、ブラウザで叩いてOK。Web Storageとかも使ってない(使えてない)

ローカルファイルとしてJSONダウンロード可能

CreateDownloadLink を押してから 右のリンクをクリック。事前にデータロードした状態でないと動かない。おまけで付けた機能

各columnで絞り込み

80とかにマッチさせたければ、Regex on で ^80$とかしないとダメ。あんまりイケてない。

問題点

そんなに作りこんでいない。でかいデータをガツンとやるなら、素直にローカルにダウンロードするツール使った方がいい。

何度か実行すると Call Stackが足らんとか言われる

いつか直す。

4,5 万行ぐらいでまともに動かない

Dynatableの方がいいのかも?StartDateで絞れるようにはした。

各種部品(ライブラリ)

AWS SDK

S3は少々CORSとかで癖があるけど、それ以外は特に問題ない。必要な機能だけの最小版も作れるみたい。

Build your own AWS SDK for JavaScript

これいいね!

datatables

テーブルをいい感じに捌くやつ。調べつつ使ったけど、あんまり使いやすくない。

moment.js

jsの面倒くさいところに、日付の変換とかがありますが、こいつはいい感じに捌いてくれます。

bootstrap-datetimepicker

昔からよくあるやつだけど、こいつのお陰でmoment.jsに触れた。

File API

とりあえず使ってみたかっただけ。

感想

やっぱjs難しいな-と思った。Bootstrap以外のものを使ってみよかとおもったけど、やめた。ともかく非同期地獄をコントロールできるようにならねばな、Promiseとか。

ipv6とAWS 繋がるから、運用まで

世の中の全てのデバイスがipv6グローバルIPアドレスを持つ時代が来る。そんな時代が来ると考えていた頃が私にもありました。

f:id:iga-ninja:20150815105712p:plain

2015年になった今も、残念ながらipv4が主流のままです。また、足らないグローバルIPやら、本当はグローバルIP同士でやるべき通信をipv4で何とかしようとする技術は沢山あります、が
小手先の技術ではなく、本当に膨大なグローバルIPを割り当てる方法および実装は、ipv6以外に2015年時点では存在せず
djbが書いた大昔の予言どおりの現在であったとしても、v4との互換性がないのがアレだといわれても、2015年の今日、でデバイスレベルで実装があるのはipv6だけです。良い、悪いは置いといて、ipv6以外の代替案が無く、結果的にダメな点が多いと言われるipv6に変わるテクノロジーを作り、協議/策定することが15年たっても誰一人出来なかったというのが、今です。おかげでipv4で何とかする技術は発展したと言えますが。。

壮大な話になってしまいました。
歴史に関してはググればいくらでもでてくるので、興味があれば調べてください。また私個人はdjbの予言は的確であったと思うし、当時の私には大変分かりやすかった。djbと翻訳者ともに尊敬、感謝しています。
http://www.unixuser.org/~euske/doc/ipv6ex/

モチベーション

djbの言葉を借りますが、ipv4 -> ipv6 マイグレーションには相当な覚悟 という名のモチベーションが必要です。

2012年のipv6 dayを経て、
「やっぱりipv6はまだ人類には早すぎた」
と私は思いました。それ以前にも、大手のISPは、なんだかよくわからないサービスをipv6限定にして展開し、何とかipv6キラーコンテンツをつくろうとしていましたが、まあ、結果失敗してます(現状をみれば一目瞭然) しかし最近になって、少しずつモチベーションが高まりつつ有ります。1つは Docomo / AU におけるスマートフォンipv6 IPアドレスを本当にしゃべる時代が来たという点です。しかもその端末が何と私の手元にあるのです! Next5です!
http://trendy.nikkeibp.co.jp/article/pickup/20131209/1053986/?P=3

それともう一つ、最近、iOS9 からのアプリ審査には、ipv6対応にしておけ、ニュアンスとしては、ipv4縛りをするな!という方針が組まれるようです。
http://www.internetsociety.org/deploy360/blog/2015/06/apple-will-require-ipv6-support-for-all-ios-9-apps/

急にipv6対応とはご無体な話ですが、実際に「はい、明日からipv6でないアプリはNGね」って話ではなく、「インフラ側がipv6になっても動くようにしとけ」ということだと思います(そうじゃないと困る)。ちなみにiPhoneDocomo & AUはすでに ipv4 & ipv6両方いける、softbankipv6非対応のはず、2015/08/14現在。

AWSにおけるipv6

単刀直入にいうと、ipv6非対応です。
EC2-Classic & ELBでは可能だったらしいのですが、私はClassicを触ったことがないので分かりません。現在、新規アカウントでClassicは出来ないので、実質非対応です。また、この点については、Asure, GCP(GCE), も同様です。ぱっと思い当たるので対応しているのは softlayerです、あくまで2015/08/14時点の話。

ELBはipv4/6 dualstack?

EC2-Classicであればdualstack.<elbのエンドポイント> で、 AレコードもAAAAレコードも戻ってくるので、ipv6による接続が可能でした。しかし、EC2-VPC(今のEC2)では、どうやらこれは出来ないようです。

Internet-Facing Load Balancers - Elastic Load Balancing

実際に試してみました。EC2-VPCでELBを立てても、dualstak.ipv6. も作成されます、DNS上は。実際にipv6でアクセスした場合、Connection Refused となります。この原因は私の推測ですが
EC2-VPCでも ELB自体にipv6アドレスは付く、しかしSecurity Group や Network ACL で ipv6のアドレスは指定出来ない(::/0とか無理)。よって、通信出来ない。
SGは明示的に許可されていないアドレスからのアクセスは蹴りますが、Refuseではなく、無視するので、外しているかもしれません。

Security Group と Network ACL ipv6対応状況

現状のEC2は全てVPC内に構築するため、Network ACL および Security Group側で v6 IPアドレスを制御出来ないというのが現状です。よって、グローバルであれ、ローカルであれ、仮にEC2に直接 v6のIPアドレスがふれたとしても、別マシンと一切通信出来ないということです。
しかしIPプロトコル番号41 = ipv6 には対応しています。ということは、アレですな、4to6とかのトンネルです。

ipv6 tunnel brockerを使う

グローバルで参照可能なipv6アドレスを実現するには、ipv6 tunnel brockerのちからを借ります。Hurricane Elasticというところがやっています。

www.slideshare.net

HEで実装

Hurricane Electric Free IPv6 Tunnel Broker

アカウント作成などが必要なので、サクっと作ってっください。具体的な設定方法の大まかな部分は、ググれば出てくるので、特記事項のみ書きます。

トンネルの作成

IPv4 Endpoint(Your side) は、AWSの場合はEIPとなります。トンネルを作る前に、疎通確認をHE側から行うようなので、pingが通るようにSGをいじっておきます。 f:id:iga-ninja:20150815111205p:plain

f:id:iga-ninja:20150815111327p:plain
各種OS向けの設定方法も生成してくれます。何と親切!しかし、下記に注意
1. IPプロトコル番号 41 を通過できるようにしておく。これは HEのサーバIP(v4) と EIP(v4)の話
2. localに指定するIPアドレスは、AWSの場合、EC2(ENI)のローカルIPアドレス

動作確認はpin6とかで

$ ping6 ipv6.google.com
PING ipv6.google.com(nrt13s38-in-x0e.1e100.net) 56 data bytes
64 bytes from nrt13s38-in-x0e.1e100.net: icmp_seq=1 ttl=59 time=3.85 ms
64 bytes from nrt13s38-in-x0e.1e100.net: icmp_seq=2 ttl=59 time=3.89 ms
64 bytes from nrt13s38-in-x0e.1e100.net: icmp_seq=3 ttl=59 time=4.16 ms
64 bytes from nrt13s38-in-x0e.1e100.net: icmp_seq=4 ttl=59 time=4.01 ms

Nexus5からhttpを叩いてみる

一応DNSにAAAAレコードを追加して試したが、直打ちでも多分いける。Apacheアクセスログはこんな感じ

2001:240:2401:dumm:dumm:dumm:dumm:dumm - - [15/Aug/2015:01:15:06 +0000] "GET / HTTP/1.1" 200 27 "-" "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36"

uとかmとかないからダミー。もちろん本物のIPv6アドレスが取れます。ただ、端末から確認できるv6アドレスとは異なる。今のところNexus側には/64で割り当てられるらしいので、wifiルータとしてIPv6を他の機器に付けられたらとか思うけど、今のところそんな機能は無いらしい。

ipv6のフィルタリング

SGはipv4しか捌けないので、source IPとかで絞るなら、EC2上のip6tablesにお願いするしか無いので試してみた。
http://wiki.princo.org/?ipv6%A4%C7%A5%D5%A5%A3%A5%EB%A5%BF%A5%EA%A5%F3%A5%B0(netfilter%2Fip6tables) を参考にしました。

# ip6tables -A INPUT -p tcp -s <NexusのIP 上から64>::/64 --dport 22 -j ACCEPT
# ip6tables -A INPUT -p tcp --dport 22 -j DROP

上手く動いているようです。ただし、v4/v6両方でアクセス可能としていたら、v6だと思ってたらv4でアクセスしてたことがあったので注意。

まとめ

  1. 2015/08 時点で ipv6 をネイティブ対応出来ているのはsoftlayerのみ
  2. ELBはipv6IPアドレスを持つようだが、EC2-VPCでは疎通出来ない
  3. 外部からipv6アクセス可能にするには、ipv6 tunnel brokerでなんとかできる
  4. トンネルの中の通信をSGで制御出来ないので、ip6tablesなど、EC2内部で何とかする

自分が生きている間にipv6を触ることなんてないと思っていたけど、こんなに簡単に触れるなら、一発あるかも?モバイルやIoTなど、大量のグローバルIPアドレスはやっぱりあった方がいい、と言うのはわかっているけど、そこへ至る動機がなかった、けど、今はある。ただ、softlayer以外のクラウドコンピュティングがネイティブに対応するのはきっとまだまだ先。

最近のDNS事情まとめ

私が一旦インフラを離れる10年前、もうすでに「BINDはヤバイんじゃないか? 」と言われてましたが、(自前運用では)未だにBINDは主流な気がする。Route53を始め、いまやどこのクラウドでも権威サーバはあるので、わざわざDNSをたてる意味はもうないですが。今のDNSを適当にまとめる

権威サーバ・キャッシュサーバ

一緒にするな!は10年前からすでに言われていた。BINDはごっちゃになるのと(無論、きちんと設定すれば分離可能)、セキュリティー問題が当時から多く、djb の tinydns & dnscache という(今となっては)検索しづらい名前のソフトウェアを使っていた。ココらへんの詳しい話はdjbの資料を読まなくても、世の中の常識になった感がある。

ざっとまとめ

あとは、このスライドで。

www.slideshare.net

キャッシュならunbound、結構最新版出てる。 DNSラウンドロビンもreadyになってる。 install は epelで

www.unbound.net

権威は NSD、これも最新版で標準入力からゾーン追加できる?みたい

www.nlnetlabs.nl

権威サーバをクラウド(当時はそんな言葉なかった)でサーバレス、しかもAPIでレコード追加できて、しかもしかも超安い。Route53とか使わずに権威サーバを立てる意味はほとんど無いと思う。とくに外向け。

AWS ELB + SSL Termination下でEC-CUBEを正しく動かす

EC-CUBEAWS上で運用するとき、良くある構成

f:id:iga-ninja:20150726081412p:plain

今回の構成は SSL Termination を行い、ELB -> EC2(Webサーバ)間ではHTTPS(443)通信を行いません。この場合、EC2側は常にHTTP(80)で通信を受けるので、ユーザーのELBに対するアクセスがHTTPなのかHTTPSなのか普通の方法では判断出来ません。

X-Forwarded-[xxx]ヘッダ

ELBを通過するときに、X-Forwarded-Port/Proto等のヘッダが付きます。これを判別することにより見分けることが出来ます。 http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/x-forwarded-headers.html

EC-CUBE内部におけるHTTPS判定

EC-CUBEに対してGREPかけると

./data/module/Net/URL.php:            $this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http');
./data/module/Net/URL.php:            case 'https':   return 443;
./data/class/util/SC_Utils.php:        if (SC_Utils_Ex::sfIsHTTPS()) {
./data/class/util/SC_Utils.php:            $proto = "https://";
./data/class/util/SC_Utils.php:            $domain  = SC_Utils_Ex::sfIsHTTPS() ? HTTPS_URL : HTTP_URL;
./data/class/util/SC_Utils.php:     * HTTPSかどうかを判定
./data/class/util/SC_Utils.php:    function sfIsHTTPS () {
./data/class/util/SC_Utils.php:        // HTTPS時には$_SERVER['HTTPS']には空でない値が入る
./data/class/util/SC_Utils.php:        // $_SERVER['HTTPS'] != 'off' はIIS用
./data/class/util/SC_Utils.php:        //if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
./data/class/util/SC_Utils.php:        #if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
./data/class/util/SC_Utils.php:        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
./data/class/util/SC_Utils.php:        } else if(ereg("^https://", $istr)) {
./data/class/util/SC_Utils.php:            $head = "https://";

このように方方で$_SERVER['HTTP']で判定しています。これらをすべて $_SERVER['HTTP_X_FORWARDED_PROTO']に変換していくのは至難の業です。
じゃあどうするか。無い変数はつけてしまえばいいです。

mod_setenvif

apacheモジュールで setEnvIfというのがあります。これを使って$_SERVER変数を無理やり追加します。

SetEnvIf X-Forwarded-Proto ^https$ HTTPS=on

リダイレクトで片っ端からSSLにする

SetEnvIf X-Forwarded-Proto ^https$ HTTPS=on

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

せっかく HTTPS変数にするんだから、そいつを使えばいいと考えるなら、RewriteCondで HTTP:HTTPSを指定すること。

もう一つの解法、ソースをちょっといじって解消する

https://forge.typo3.org/issues/29693

f ($_SERVER['X-Forwarded-Proto'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
}

phpの初手でこいつをかませばいい。

まとめ

  • EC-CUBEHTTPS判定は、サーバ変数 $_SERVER['HTTPS']
  • HTTPS -> X-Forwarded-Protoに判定をまるっと変えるようなconfigはない
  • SetEnvIfで HTTPSサーバ変数を付与するのが楽

X-Forwarded-Protoでリダイレクトだけかけても、商品をカートに入れるときにエラーが出ます。これの対処方法がわからない場合、参考に。 ちなみに、EC-CUBEはセッションをDBに保存するらしいので、(デフォルト) StickySessionは必須ではないはず。

iPhoneやAndroidでドメイン開通前のサイトにアクセスする、結構簡単な方法

まだドメインが決まっていないサイトリニューアルで本番サーバからの切替前などの理由より、正式なFQDNがまだDNSから引けない状態で試しにアクセスしたいとき、ありますよね?
PCのブラウザであればhostsファイルを弄るのが俗手ですが、iPhoneiPad さらに Androidなどで実機テストしたいとき、どうすればいいでしょうか?

いきなり結論 Proxyを使おう

今日はじめて知りました。じつはiOSAndroidも、Wifi設定の画面でなんとProxyを指定出来ます。と、いうことは!自分のディスクトップ or ラップトップPCで Proxyサーバを立てて、それを指定すればOKとなります!Proxyサーバのhostsをいじっておけば、DNS開通前でも、サイトリニュアル前でFQDNがすでに存在していても、デバックが可能です、素晴らしい!

構成

こんな感じです。Wifi APの下にProxyサーバとなるPCと、iOS/Androidスマホ/タブレットがぶら下がっているよくある光景です。

f:id:iga-ninja:20150725205600p:plain

Proxy何がいいかな?

MacSquidが多分いいんじゃないでしょうか?今回はWindowsでやりましたが、ググるSquidが多いみたいですね。でもなんか(わけもなく)嫌なんでCCProxyというWindows用のものを使いました。ここは趣味ですのでお好きなモノを選んでOK

CCProxyセットアップ

www.youngzsoft.net

ざっとこんな感じです。
Windows FireWallの警告 f:id:iga-ninja:20150723080516p:plain

f:id:iga-ninja:20150723080526p:plain

VMとか入れている人は、HostOnlyのIPとかに引っ張られちゃうので要注意 f:id:iga-ninja:20150723080535p:plain

後は Proxyサーバのhostsを弄ることを忘れずに

iPhone/Android設定

ご参考に

Android3.1以降ではWi-Fiアクセスポイントごとにプロキシサーバの設定が可能 | あんどろいどスマート

news.mynavi.jp

まとめ

良いデバッグを!

CetosやAmazonLinuxのマイナーバージョン固定と注意

どうしても古いバージョンのcentosを使いたいことがあったとします(やめといたほうがいいですが) そんな時どうするかと、それによる注意点を書きます。

バージョン固定の方法

centos5系

/etc/yum.repos.d/CentOS-Base.repoを直接編集
mirrorlistはバージョンが古いと、もうミラー対象からも外されています。よってbaseurlを使います。

http://vault.centos.org/5.7/os/$basearch/

とかに変更する。

centos6系

# vi /etc/yum/vars/releasever
6.5とかにする

注意点

centosRHELと同等の長いサポート期間がありますが、残念ながらマイナーバージョン固定してしまうと、パッケージの更新は無理のようです。よって、脆弱性のあるパッケージから更新出来ないという、セキュリティー上は非常によろしくない状態となってしまいます。
対策としてはyum update は実行しないが、パッケージ個別アップデートをかけるという方法が考えられます。
ただし、パッケージ個別アップデートも yumの設定でバージョン固定してしまえば、rpmだけで捌くこととなり、最近の若いもんにはどうにも出来ないでしょう。(最近の中年も嫌です、yumでやりたいです)

GCEでHTTPS負荷分散 SSL Termination

技術的に不可能だろうと思っていましたが、予告通りHTTPS負荷分散がGCEでも実現可能となりました。
これにより、SSL TerminationがGCEでも可能となりました!

HTTP負荷分散との変更点

GCEのロードバランサは2つあります
- ネットワーク負荷分散
- HTTP負荷分散
いずれもAWS - ELBに比べて暖気不要などアドバンテージがあるのは変わりませんが、本機能はHTTP負荷分散のみです。
Developers Consoleから変更可能です。

簡単ですが、一旦HTTP負荷分散として設定したものを、HTTPSへ変更する手順を記す。

HTTPSでリクエストを受ける

f:id:iga-ninja:20150712183827p:plain

SSL証明書をアップロード

f:id:iga-ninja:20150712183923p:plain

f:id:iga-ninja:20150712183932p:plain

アプリケーション側の考慮

AWSのELBと同じく、ロードバランサ側でSSLを剥がしてしまうので、バックエンドのWebサーバ側にとっては ブラウザからHTTPSかHTTPの判断がつきません。が、そもそも1つのIPアドレスで80 & 443を両方Listen出来ないので、この考慮は必要ないかもしれません。

HTTPヘッダ

ここから書くことはドキュメンテーションにも記載がない内容となります。今後変更される可能性は極めて高いと思います!

ダサくて嫌だけど、おなじみphpinfo()でのぞきます。#もっとイケてるカッコイイ方法を探そう

f:id:iga-ninja:20150712183943p:plain

これを見てわかることは
- HTTPSは何かのリソースでSSLを解いている
ということは、暖気不要とはならないはず
- AWS - ELBに比べて、SSLを解く専用のナニかが在る
それが X-FORWARDED-FORに出ている。だからカンマ区切りの2段転送。

まとめ

AWSのELBとはかなり違うので注意!
1. 1つのIPアドレスで 80 & 443を Listen 出来ない
2. X-Forwarded-Forはカンマ区切りになる(これは2段リバプロとかやるとこうなる、標準の動き)
3. この構成だと、暖気無しとは行かないのではないか?
ひとまず出来ましたが、まだ課題が沢山ありますね。。Betaが切れる頃までに仕様が様変わりするかもしれないので、そこまで待つ!