経緯
- Rails 5 から ActionCable が使えるようになった
- AWS 上でお手軽に試したい
- せっかくなので ELB を使って冗長構成にしよう
あまりお手軽じゃなかった
問題
- ELB が Websocket の接続に必要な
Connection
ヘッダとUpgrade
ヘッダを削る - 削らないようにプロトコルを
TCP
にすると今度はX-Fowarded-For
ヘッダをつけてくれない - ので発信元のIPアドレスがとれない
Proxy Protocol を使うしかないらしい
Proxy Protocol とは
- HAProxy が策定
- リクエストボディの1行目に発信元の情報を追加して送信する仕様
例
PROXY TCP4 198.51.100.22 203.0.113.7 80 80\r\n
GET / HTTP/1.1\r\n
Host: example.com\r\n
\r\n
全体の構成
ELB の設定
- プロトコルを両方とも
TCP
に設定しておく
肝心のProxy Protocolの設定はAWSコンソールからはできない
AWS CLI のインストール
Mac
$ brew install awscli
Linux ( Python 2.6.5 以降が必要 )
$ pip install awscli
Windows
AWS CLI の設定
- IAMユーザを追加して
Access Key ID
とSecret Access Key
を設定
$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-northeast-1
Default output format [None]: ENTER
ELB - ProxyProtocol の設定
$ aws elb create-load-balancer-policy \
--load-balancer-name {ELB Name}
--policy-name EnableProxyProtocol \
--policy-type-name ProxyProtocolPolicyType \
--policy-attributes \
AttributeName=ProxyProtocol,AttributeValue=true
$ aws elb set-load-balancer-policies-for-backend-server \
--load-balancer-name {ELB Name} \
--instance-port 80 \
--policy-names EnableProxyProtocol
ELB - Proxy Protocol 設定確認
$ aws elb describe-load-balancers \
--load-balancer-name {ELB Name}
"BackendServerDescriptions": [
{
"InstancePort": 80,
"PolicyNames": [
"EnableProxyProtocol"
]
}
],
Nginx の設定(1)
server {
listen 80 proxy_protocol;
real_ip_header proxy_protocol;
location / {
proxy_http_version "1.1";
proxy_pass http://localhost:3000/;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
proxy_set_header X-Forwarded-Host $http_host;
}
}
Nginx の設定(2)
-
Upgrade
ヘッダが空の場合はConnection
ヘッダをclose
にする
http {
...
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
...
}
まとめ
- ELBはTCPロードバランサーとして使用する
- 発信元のIPアドレスをとるために Proxy Protocol が必要
- Proxy Protocol を捌くために間に Nginx か HAProxy が必要
結局なにが嬉しい?
- マネージドなロードバランサーは管理が楽だしEC2のインスタンス立てるよりは安い
- SSL の設定はAWSコンソール上からできるし、最近だとAWS Certificate Managerの証明書が無料で使える