Memo/AmazonWebServices/ELB

https://dexlab.net:443/pukiwiki/index.php?Memo/AmazonWebServices/ELB
 

ELB


WebSocket?

  • ws://, wss:// はデフォルト設定では使えない
  • ALBはws://, wss:// をサポートしている
  • 記事

Proxy Protocolを有効にする

  • ロードバランサーの Proxy Protocol のサポートを設定する

    Proxy Protocol を有効にすると、送信元 IP アドレス、送信先 IP アドレス、ポート番号などの接続情報が含まれる、人間が読んで理解できるヘッダーがリクエストヘッダーに追加されます。これにより、ヘッダーがリクエストの一部としてバックエンドインスタンスに送信されます。

    • ELBとアプリケーション両方がproxy protocolの有効化が必要
    • 両方の切替時にサービス断が発生するので注意
  • 記事

セキュリティポリシー更新

  • aws cliを使う場合
    • ポリシー名一覧取得
      aws elb describe-load-balancer-policies --query "PolicyDescriptions[].{PolicyName:PolicyName}"
      [
          {
              "PolicyName": "ELBSecurityPolicy-2014-10"
          },
          {
              "PolicyName": "ELBSecurityPolicy-2014-01"
          },
          {
              "PolicyName": "ELBSecurityPolicy-2011-08"
          },
          {
              "PolicyName": "ELBSample-ELBDefaultNegotiationPolicy"
          },
          {
              "PolicyName": "ELBSample-OpenSSLDefaultNegotiationPolicy"
          }
      ]
    • ELBの一覧とセキュリティポリシーの取得
      aws elb describe-load-balancers --query "LoadBalancerDescriptions[].{LoadBalancerName:LoadBalancerName,Policies:Policies.OtherPolicies}"
      
      [
          {
              "Policies": [
                  "ELBSecurityPolicy-2014-01"
              ],
              "LoadBalancerName": "example-lb"
          },
      ...
      ]
    • 全リージョンのELB一覧とポリシーをファイルに出力
      AWS_PROFILE=default; for region in $(aws --profile $AWS_PROFILE ec2 describe-regions --query "Regions[].[RegionName]" --output text); do \
      echo "---- $region"; aws --profile $AWS_PROFILE --region $region elb describe-load-balancers --query "LoadBalancerDescriptions[].{LoadBalancerName:LoadBalancerName,Policies:Policies.OtherPolicies}"; \
      done > $AWS_PROFILE.elb.$(date +%Y%m%d-%H%M%S).log
    • セキュリティポリシーの更新。set-load-balancer-policies-of-listenerに直接ELBSecurityPolicy?-2014-10を指定してもエラーになった。"ELBSecurityPolicy?-*"は予約語で使えなかった。
      aws elb create-load-balancer-policy --load-balancer-name example-lb --policy-name ref-ELBSecurityPolicy-2014-10 --policy-type-name SSLNegotiationPolicyType --policy-attributes AttributeName=Reference-Security-Policy,AttributeValue=ELBSecurityPolicy-2014-10
      aws elb set-load-balancer-policies-of-listener --load-balancer-name example-lb --load-balancer-port 443 --policy-names ref-ELBSecurityPolicy-2014-10
    • セキュリティポリシーの削除。Management Consoleで設定するとセーブする度に、"AWSConsole-SSLNegotiationPolicy?-*"という名前のポリシーが増える
      aws elb delete-load-balancer-policy --load-balancer-name example-lb --policy-name AWSConsole-SSLNegotiationPolicy-example-lb-123456789
    • 指定したELBを、リージョン毎に一括更新する
      ELB_NAMES=(my-elb-01 my-elb-02)
      ELB_POLICY=ELBSecurityPolicy-2014-10
      AWS_PROFILE=default
      AWS_REGION=ap-northeast-1
      
      for elb_name in "${ELB_NAMES[@]}"; do \
      aws --profile $AWS_PROFILE --region $AWS_REGION elb create-load-balancer-policy --load-balancer-name $elb_name --policy-name ref-${ELB_POLICY} --policy-type-name SSLNegotiationPolicyType --policy-attributes AttributeName=Reference-Security-Policy,AttributeValue=$ELB_POLICY ; \
      sleep 10; \
      aws --profile $AWS_PROFILE --region $AWS_REGION elb set-load-balancer-policies-of-listener --load-balancer-name $elb_name --load-balancer-port 443 --policy-names ref-${ELB_POLICY}
      done

Cross-Zone Load Balancingは有効にする

Cross-Zone Load Balancing: Enabledにした方が良い。
デフォルトはDisabled:

  • アクセス数の例
    • ELB: 1台
    • EC2: AZ:1a(1台), 1b(2台)
    • ELBから、1aに50%, 1bに50%に割り振られる。1aには1台なので50%分のアクセス数があり、1bは2台なのでそれぞれ25%のアクセスがある。
    • Cross-Zone Load Balancing: Enabledにした場合は、それぞれ33%ずつのアクセスがある

Listener TCP/HTTPの違い

  • Listener TCP
    • リクエストをELB配下のサーバにそのまま流す
  • Listener HTTP
    • ELB配下のHTTPサーバがKeep-Aliveが使える場合、リクエストを連結し、接続を再利用する(1リクエストに異なるクライアントからのリクエストが含まれる)
    • HTTPヘッダ transfer-encoding: chunked を外し、Content-Lengthを追加し、chunkに分割されていないクライアントにレスポンスを返す

アクセス元のIPアドレスで記録/制限する

  • ELBからのアクセスの場合、ELBのIPアドレス(10.x.x.x)がアクセスログに記録される
  • httpの場合:「X-Forwarded-For」ヘッダが付く
  • httpsでELBのSSL Termination機能を使った場合:「X-Forwarded-For」ヘッダが付く
    elb-create-lb test-lb \
      --availability-zones ap-northeast-1a,ap-northeast-1b \
      --listener "protocol=HTTP, lb-port=80, instance-port=80" \
      --listener "protocol=HTTPS, lb-port=443, instance-port=80, cert-id=arn:aws:iam::ACCOUNT_NO:server-certificate/SSL-NAME"
  • httpsでELBではSSLデコードせず、ホスト側にSSL証明書をいれた場合:「X-Forwarded-For」ヘッダは付かないため、以下の方法が使えない
    elb-create-lb test-lb \
      --availability-zones ap-northeast-1a,ap-northeast-1b \
      --listener "protocol=HTTP, lb-port=80, instance-port=80" \
      --listener "protocol=TCP, lb-port=443, instance-port=443"

ELBからのアクセスのみを許可

  • api-toolから
    # httpのみ許可
    ec2-authorize test-sg -P tcp -p 80 -o amazon-elb-sg -u amazon-elb
    
    # 全許可
    ec2-authorize test-sg -o amazon-elb-sg -u amazon-elb
  • Management Consoleから
  1. EC2 > Security Groups > 該当セキュリティグループを選択
  2. Create a new rule: HTTP
  3. Source: amazon-elb/amazon-elb-sg

ELBとmod_rpafのテスト

  • セキュリティグループ作成スクリプト
    cat >> ec2_add_group.sh << 'EOS'
    #!/bin/bash
    #
    # Amazon EC2 セキュリティグループ作成
    #
    # ./ec2_add_group.sh
    #
    # $Id: 4D656D6F2F416D617A6F6E57656253657276696365732F454C42.txt 2470 2018-08-17 15:16:52Z dex $
    
    # include conf
    
    # define vars
    NAME=$1
    DESC=$2
    if [ "$NAME" == ""  ]; then
    	echo "Error : Input [Security Group Name] [Description]"
    	exit 1
    fi
    
    # add Security Groups
    add_security_groups() {
    	# Home > Your Account > Account Activity の右上にある「Account Number xxxx-xxxx-xxxx」のハイフンを除外した数字
    	ACCOUNT_NO=`ec2dgrp | grep GROUP | grep "default[[:space:]]default" | cut -f3`
    	if [ "$ACCOUNT_NO" == ""  ]; then
    		echo "AWS ACCOUNT NO Not found." 1>&2
    		return 1
    	fi
    
    	# -o [$NAME]
    	# -u [$ACCOUNT_NO]
    
    	# グループ作成
    	ec2-add-group "$NAME" -d "$DESC"
    
    	# default
    	ec2-authorize "$NAME" -P tcp -p 22 -s 0.0.0.0/0
    
    	# ping
    #	ec2-authorize "$NAME" -P icmp -t -1:-1 -s 0.0.0.0/0
    
    	# 確認
    	ec2-describe-group | grep "$NAME"
    
    	return 0
    }
    
    add_security_groups
    # vim: ts=4:sw=4:tw=80
    EOS
  • セキュリティグループを作成
    bash ec2_add_group.sh test-sg test-sg
  • テスト用 elb作成(SSL Terminationを使わない普通のELB)
    LB_NAME=test-lb
    elb-create-lb $LB_NAME \
      --availability-zones ap-northeast-1a,ap-northeast-1b \
      --listener "protocol=HTTP, lb-port=80, instance-port=80" \
      --listener "protocol=TCP, lb-port=443, instance-port=443"
    
    DNS_NAME  test-lb-274673121.ap-northeast-1.elb.amazonaws.com
  • テスト用 ec2作成
    AZ=ap-northeast-1a
    HOST=test-ec2
    SG=test-sg
    
    ec2-run-instances \
      ami-786fdd79 \
      -g $SG \
      -z $AZ \
      -k test-key \
      -t t1.micro \
      -b "/dev/sdb=ephemeral0" \
      -b "/dev/sdc=ephemeral1"
    
    
    ec2-create-tags i-9bf6e99b --tag "Name=$HOST"
  • ec2にapache, mod_rpafをインストール
    ssh -i test-key.pem root@ec2-54-248-59-203.ap-northeast-1.compute.amazonaws.com
    
    yum install httpd -y
    
    yum -y install gcc httpd-devel
    cd /tmp/
    git clone https://github.com/ttkzw/mod_rpaf-0.6.git
    cd mod_rpaf-0.6/
    make
    make install
    cp mod_rpaf.conf /etc/httpd/conf.d/rpaf.conf
    vi /etc/httpd/conf.d/rpaf.conf
    ----
    RPAFenable On
    RPAFsethostname Off
    RPAFproxy_ips 127.0.0.1 10.
    ----
    service httpd restart
    
    service iptables stop
    chkconfig iptables off
  • ELBにEC2を追加
    elb-register-instances-with-lb $LB_NAME \
      --instances i-9bf6e99b
    
    INSTANCE_ID  i-9bf6e99b
  • phpでHTTP ヘッダー出力
    yum -y install php php-mbstring
    
    vi /etc/php.ini
    ----
    date.timezone = "Asia/Tokyo"
    ----
    service httpd restart
    
    cd /var/www/html
    
    cat >> index.php << 'EOS'
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
    <pre>
    <?php var_export(getallheaders()); ?>
    </pre>
    </body>
    </html>
    EOS
  • テスト。80をフル解放して、ブラウザからアクセスできるか?
    ec2-authorize test-sg -P tcp -p 80
    
    # アクセスを確認したら削除
    ec2-revoke test-sg -P tcp -p 80
  • この状態ではELBからEC2へアクセスできない。セキュリティグループ test-sg にELBからのアクセスを許可
    # httpのみ許可
    ec2-authorize test-sg -P tcp -p 80 -o amazon-elb-sg -u amazon-elb
    
    # 全許可
    ec2-authorize test-sg -o amazon-elb-sg -u amazon-elb
  • テスト終了後の後始末
    # ELBから外す
    elb-deregister-instances-from-lb test-lb --instances i-9bf6e99b
    
    # EC2インスタンス削除
    ec2-terminate-instances i-9bf6e99b
    
    # ELB削除
    elb-delete-lb test-lb
    
    # セキュリティグループ削除
    ec2-delete-group test-sg

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-09-15 (土) 07:31:37 (9d)