こんにちは、技術4課の井関です。入社して半年ほど経過しましたが、初のブログ投稿となります。
ポートをTCPにしてロードバランシングした場合、バッググランドのEC2では送信元のIPアドレスを取得することができません。
クライアント証明書を利用したい時などは、要件によってTCPを利用するケースがあるかと思います。
バッググランドのEC2で送信元のIPアドレスを扱う方法をご紹介いたします。
検証環境
- Classic Load Balancer
- Amazon Linux AMI 2017.09.1 (HVM), SSD Volume Type
- Apache2.2
Apache側の準備
デフォルトでProxy Protocolに対応していないため、mod_myfixip モジュールをインストールします。
# Apacheのインストール yum install httpd # mod_myfixipインストールするための必須ライブラリ yum install -y httpd-devel yum install -y gcc # mod_myfixipのインストール curl -O https://raw.githubusercontent.com/ggrandes/apache22-modules/master/mod_myfixip.c apxs -c -i mod_myfixip.c
インストール後、httpd.confを修正し、再起動します。
# httpd.confの修正 ・・・ LoadModule version_module modules/mod_version.so LoadModule myfixip_module modules/mod_myfixip.so # この行を追加 ・・・ # ErrorLog logs/dummy-host.example.com-error_log # CustomLog logs/dummy-host.example.com-access_log common #RewriteIPResetHeader off RewriteIPAllow 10.20.0.0/16 # VPCのCIDRを指定 ・・・
以下コマンドにて、モジュールが有効になっているか確認しておきます。
httpd -M Loaded Modules: ・・・ myfixip_module (shared) ・・・
Proxy Protocolを有効にする前のApacheアクセスログ
ロードバランサのIPアドレスが出力されています。
10.20.8.75 - - [16/Apr/2018:09:59:26 +0000] "GET /test.html HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
CLB側の準備
1.ポリシーの作成
aws --region ap-northeast-1 elb create-load-balancer-policy --load-balancer-name ロードバランサ名 --policy-name ポリシー名 --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=True
2.対象ポート番号(今回は80)に対してポリシーを設定
aws --region ap-northeast-1 elb set-load-balancer-policies-for-backend-server --load-balancer-name ロードバランサ名 --policy-name ポリシー名 --instance-port 80
3.設定内容の確認
aws --region ap-northeast-1 elb describe-load-balancers --load-balancer-names ロードバランサ名
{ "LoadBalancerDescriptions": [ { "Subnets": [ "subnet-xxxxxxxx", "subnet-xxxxxxxx" ], "CanonicalHostedZoneNameID": "xxxxxxxxxxxxxx", "CanonicalHostedZoneName": "clb-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com", "ListenerDescriptions": [ { "Listener": { "InstancePort": 80, "LoadBalancerPort": 80, "Protocol": "TCP", "InstanceProtocol": "TCP" }, "PolicyNames": [] } ], "HealthCheck": { "HealthyThreshold": 10, "Interval": 30, "Target": "TCP:80", "Timeout": 5, "UnhealthyThreshold": 2 }, "VPCId": "vpc-xxxxxxxx", "BackendServerDescriptions": [ { "InstancePort": 80, "PolicyNames": [ "ポリシー名" ] } ], "Instances": [ { "InstanceId": "i-xxxxxxxxxxxxxxxxxx" } ], "DNSName": "clb-xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com", "SecurityGroups": [ "sg-xxxxxxxx" ], "Policies": { "LBCookieStickinessPolicies": [], "AppCookieStickinessPolicies": [], "OtherPolicies": [ "ポリシー名" ] }, "LoadBalancerName": "clb", "CreatedTime": "2018-04-16T09:57:19.500Z", "AvailabilityZones": [ "ap-northeast-1a", "ap-northeast-1c" ], "Scheme": "internet-facing", "SourceSecurityGroup": { "OwnerAlias": "xxxxxxxxxxxx", "GroupName": "clb" } } ] }
Proxy Protocolを有効にした後のApacheアクセスログ
クライアントのIPアドレスが出力されていることが確認できました。
xx.xx.xx.xx - - [16/Apr/2018:10:55:12 +0000] "GET /test.html HTTP/1.1" 200 11 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
まとめ
今回はCLBにて検証を行いましたが、NLB(Network Load Balancer)でも同様のことができるかと思いますので、次はNLBにて検証してみたいと思います。 NLBの場合、Proxy Protocolの有効化はマネジメントコンソール上で実施することができます。