Memo/AmazonWebServices/ELB

http://dexlab.net/pukiwiki/index.php?Memo%2FAmazonWebServices%2FELB
 

ELB


WebSocket?

  • ALBはws://, wss:// をサポートしている

Proxy Protocolを有効にして、発信元IPを取得する

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

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

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

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

  • aws cliを使う場合
    • ポリシー名一覧取得
      1. aws elb describe-load-balancer-policies --query "PolicyDescriptions[].{PolicyName:PolicyName}"
      2. [
      3.     {
      4.         "PolicyName": "ELBSecurityPolicy-2014-10"
      5.     },
      6.     {
      7.         "PolicyName": "ELBSecurityPolicy-2014-01"
      8.     },
      9.     {
      10.         "PolicyName": "ELBSecurityPolicy-2011-08"
      11.     },
      12.     {
      13.         "PolicyName": "ELBSample-ELBDefaultNegotiationPolicy"
      14.     },
      15.     {
      16.         "PolicyName": "ELBSample-OpenSSLDefaultNegotiationPolicy"
      17.     }
      18. ]
    • ELBの一覧とセキュリティポリシーの取得
      1. aws elb describe-load-balancers --query "LoadBalancerDescriptions[].{LoadBalancerName:LoadBalancerName,Policies:Policies.OtherPolicies}"
      2.  
      3. [
      4.     {
      5.         "Policies": [
      6.             "ELBSecurityPolicy-2014-01"
      7.         ],
      8.         "LoadBalancerName": "example-lb"
      9.     },
      10. ...
      11. ]
    • 全リージョンのELB一覧とポリシーをファイルに出力
      1. AWS_PROFILE=default; for region in $(aws --profile $AWS_PROFILE ec2 describe-regions --query "Regions[].[RegionName]" --output text); do \
      2. echo "---- $region"; aws --profile $AWS_PROFILE --region $region elb describe-load-balancers --query "LoadBalancerDescriptions[].{LoadBalancerName:LoadBalancerName,Policies:Policies.OtherPolicies}"; \
      3. done > $AWS_PROFILE.elb.$(date +%Y%m%d-%H%M%S).log
    • セキュリティポリシーの更新。set-load-balancer-policies-of-listenerに直接ELBSecurityPolicy?-2014-10を指定してもエラーになった。"ELBSecurityPolicy?-*"は予約語で使えなかった。
      1. 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
      2. 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?-*"という名前のポリシーが増える
      1. aws elb delete-load-balancer-policy --load-balancer-name example-lb --policy-name AWSConsole-SSLNegotiationPolicy-example-lb-123456789
    • 指定したELBを、リージョン毎に一括更新する
      1. ELB_NAMES=(my-elb-01 my-elb-02)
      2. ELB_POLICY=ELBSecurityPolicy-2014-10
      3. AWS_PROFILE=default
      4. AWS_REGION=ap-northeast-1
      5.  
      6. for elb_name in "${ELB_NAMES[@]}"; do \
      7. 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 ; \
      8. sleep 10; \
      9. 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}
      10. 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」ヘッダが付く
      'X-Forwarded-For' => 'x.x.x.x(アクセス元IP)',
      'X-Forwarded-Port' => '80',
      'X-Forwarded-Proto' => 'http',
  • httpsでELBのSSL Termination機能を使った場合:「X-Forwarded-For」ヘッダが付く
    1. elb-create-lb test-lb \
    2.   --availability-zones ap-northeast-1a,ap-northeast-1b \
    3.   --listener "protocol=HTTP, lb-port=80, instance-port=80" \
    4.   --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」ヘッダは付かないため、以下の方法が使えない
    1. elb-create-lb test-lb \
    2.   --availability-zones ap-northeast-1a,ap-northeast-1b \
    3.   --listener "protocol=HTTP, lb-port=80, instance-port=80" \
    4.   --listener "protocol=TCP, lb-port=443, instance-port=443"

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

  • api-toolから
    1. # httpのみ許可
    2. ec2-authorize test-sg -P tcp -p 80 -o amazon-elb-sg -u amazon-elb
    3.  
    4. # 全許可
    5. 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のテスト

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

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-04-16 (月) 10:59:00 (10d)