未設定のドメインでも 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