36
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS ELB 越しに WebSocket を通す

Last updated at Posted at 2016-07-03
1 / 18

経緯

  • 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_actioncable.png


ELB の設定

  • プロトコルを両方とも TCP に設定しておく
elb1.png elb2.png

肝心のProxy Protocolの設定はAWSコンソールからはできない


AWS CLI のインストール

Mac
$ brew install awscli
Linux ( Python 2.6.5 以降が必要 )
$ pip install awscli
Windows

インストーラがあるのでそれで


AWS CLI の設定

  • IAMユーザを追加して Access Key IDSecret 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の証明書が無料で使える

参考

36
33
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?