未設定のドメインでも
ELB 経由で proxy.pac を使って
https で接続する方法
天野卓
JAWS-UG 長野支部 勉強会 #2
NSEG #58
AWS上の構成
運用中のウェブサイトを
この環境に移行する
DNSのレコードの設定を
更新する前に
ブラウザで確認したい
• 割りと頻繁にIPアドレスが変わるのでhosts
ファイルでは設定しにくい
• DNSサーバーを用意するのは面倒
• proxy.pac で指定できると嬉しい
if (host == “example.com") {
return “PROXY 123345.ap-northeast-1.elb.amazonaws.com”;
}
プロキシサーバーを経由して
HTTPSで接続する場合には
ブラウザはCONNECTメソッドを使う
CONNECTメソッドとは?
CONNECT www.example.com:443 HTTP/1.1
ELBはCONNECTメソッドに
対応していない
CONNECTメソッドに
対応しているプロキシサーバー
を準備すれば接続できそう
• Apache
• Squid
• 等 …
• このためだけに入れるのは面倒くさい
• 設定ファイルを書くのも面倒くさい
• 移行後にアンインストールするのも面倒くさい
• シングルバイナリでコピーすればそのまま動く
• 設定ファイルを書かなくても動く
• シングルバイナリでコピーすればそのまま動く
• go で書いたらシングルバイナリになる
• 確かプロキシサーバーを書けるライブラリがあった
• 設定ファイルを書かなくても動く
• 接続元のIPアドレスを利用できるかも
r2proxy
means
"reflective reverse proxy"
if (host == “example.com") {
if (shExpMatch(url, "https*")) {
return “PROXY 123345.ap-northeast-1.elb.amazonaws.com:8080”;
}
else {
return “PROXY 123345.ap-northeast-1.elb.amazonaws.com”;

}
}
r2proxyの実装
github.com/elazarl/goproxy
import (
"github.com/elazarl/goproxy"
"log"
"net/http"
)
func main() {
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = true
log.Fatal(http.ListenAndServe(":8080", proxy))
}
func main() {
portRegexp := regexp.MustCompile(":([0-9]+)$")
proxy := goproxy.NewProxyHttpServer()
server := http.HandlerFunc(func(w http.ResponseWriter, r
*http.Request) {
host := strings.Split(r.RemoteAddr, ":")[0]
port := 80
matches := portRegexp.FindStringSubmatch(r.URL.Host);
if len(matches) != 0 {
port, _ = strconv.Atoi(matches[1])
}
r.URL.Host = fmt.Sprintf("%s:%d", host, port)
proxy.ServeHTTP(w, r)
})
http.ListenAndServe(":8080", server)
}
goproxyを利用する際の
注意 !
接続を制限するコードを
何も入れないと
CONNECTメソッドで
任意のサーバーの任意のポートへ
トンネルし放題になります
import (
"github.com/elazarl/goproxy"
"log"
"net/http"
)
func main() {
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = true
log.Fatal(http.ListenAndServe(":8080", proxy))
}
IAM ロールで緩めに
権限を与えていたりすると…
r2proxyの特徴
• バイナリをコピーして実行すれば動作する
• ELBのHTTPSのListenerを利用できる
• EC2のインスタンスでHTTPSの設定をする必要がない
• ELBの"Cookie Stickiness”も利用できる

(2014年10月時点)
転送料の試算
おそらく無料
(AZ内の転送なので)
r2proxyの制限事項
• ELBの現在の文書化されていない挙動に依存
• 「接続元のIPアドレスからも応答を返してくれる」
• 接続先のホスト名は暗号化されない
• HTTPSのリクエストの内容は暗号化される
r2proxyの性能
手元のGoogle Chrome で
計測した性能なので
ざっくりとした傾向のデータです
• KeepAlive で接続を確立した状態から計測
• r2proxy は KeepAlive に未対応
• ただし、HTTPS に関しては KeepAlive になる
• CONNECTメソッドで接続しているので
• キャッシュを Disable にしてページをリロード
• ロード後の以下の値の算術平均
• window.performance.timing.domComplete -
window.performance.timing.connectStart
ありがとうございました!
A theme of this presentation is
https://github.com/sanographix/azusa-keynote

未設定のドメインでも ELB 経由で proxy.pac を使って https で接続する方法