クライアントからの通信をCLBを経由してサーバにTCPで分散する際に、クライアントのIPアドレスがCLBのIPアドレスに書き換えられます。
CLBの背後に、Proxyがあった場合、送信元がCLBのIPアドレスになってしまうため、クライアントのIPアドレスによるアクセス制御ができなくなります。
そんなとき、Classic Load Balancerで `Proxy Protocol` を有効にすることで、CLBを経由した後でも、クライアントの発信元IPアドレスを取得することができるようになります。
こちらの構成を今回検証していました。
ProxyProtocol無効時(送信元がCLBのIP)
ProxyProtocol有効時(送信元がProxyClientのIP)
検証環境
前提条件
Proxy Protocol を有効にするための前提条件として、AWS公式サイトには以下のような記述があります。
- ロードバランサーが、Proxy Protocol が有効になっているプロキシサーバーの背後にないことを確認します。Proxy Protocol がプロキシサーバーとロードバランサーの両方で有効になっていると、ロードバランサーが、プロキシサーバーからのヘッダーが既に追加されているリクエストにもう 1 つのヘッダーを追加します。インスタンスの設定によっては、このような重複によってエラーが発生する可能性があります。
インスタンスで Proxy Protocol 情報を処理できることを確認します。
リスナー設定で Proxy Protocol がサポートされることを確認します。詳細については、「Classic Load Balancer のリスナーの設定」を参照してください。
検証構成
名称 | IP | 備考 |
---|---|---|
Proxy(squid) | 10.0.0.24/32 | AmazonLinux |
Proxy-Client | 10.0.0.23/32 | AmazonLinux |
blog-CLB | 10.0.0.0/24・10.0.20.0/24 | Classic Load Balancer |
検証作業
1. Proxyの設定 作業場所
Proxy(squid) にログインし、squidのインストール及びProxyProtocolの設定を実施します。
3128ポートをProxyProtocolを有効にするProxyのリッスンポートとします。
・squidインストール
yum -y install squid
・squid設定ファイル編集(/etc/squid/squid.conf)
squidの設定ファイルを修正します。
以下の設定は、http_access deny all よりも上部に設定を入れています。
設定箇所 | 設定内容 |
---|---|
proxy server port | Proxyのリッスンポート及びProxyProtocolの有効化 |
ELB subnet | ACL。ELBが所蔵しているサブネットのネットワークアドレス。 |
white list | ACL。ProxyClientのIP。 |
permit proxy_protocol_access | proxy_protocolの利用許可 |
permit http protocol | httpでのアクセス許可 |
### proxy server port http_port 3128 require-proxy-header ### ELB subnet acl elbsubnet src 10.0.0.0/24 acl elbsubnet src 10.0.20.0/24 ### white list acl client-ip src 10.0.0.23/32 ### permit proxy_protocol_access proxy_protocol_access allow localhost proxy_protocol_access allow elbsubnet proxy_protocol_access allow client-ip proxy_protocol_access deny all ### permit http protocol http_access allow localhost http_access allow elbsubnet http_access allow client-ip
2. CLBの設定
・CLB作成
AWSコンソールより、以下のようなインターナルCLBを作成しています。
項目 | 設定内容 |
---|---|
名前 | blog-CLB |
DNS名 | internal-blog-CLB-950891528.ap-northeast-1.elb.amazonaws.com |
種類 | Classic |
スキーム | internal |
ポート構成 | 3128 (TCP) を 3128 (TCP) に転送します |
・ProxyProtocolの有効化
CLBの編集権限がある端末で、AWSCLIよりCLBのProxyProtocol有効化を実施します。
Proxy Protocol を有効にするポリシーを作成
#設定内容 aws elb create-load-balancer-policy --load-balancer-name <ロードバランサー名> --policy-name <elbポリシー名(自由)> --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=true #設定例 aws elb create-load-balancer-policy --load-balancer-name blog-CLB --policy-name my-ProxyProtocol-policy --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=true
作成したProxy Protocol を有効にするポリシーをCLBに適用
#設定内容 aws elb set-load-balancer-policies-for-backend-server --load-balancer-name my-loadbalancer --instance-port 80 --policy-names my-ProxyProtocol-policy #設定例 aws elb set-load-balancer-policies-for-backend-server --load-balancer-name blog-CLB --instance-port 3128 --policy-names my-ProxyProtocol-policy
ポリシーが適用されていることを確認
BackendServerDescriptionsにInstancePort及びPolicyNamesが記載されていることを確認します。
#確認内容 aws elb describe-load-balancers --load-balancer-name my-loadbalancer #確認例 aws elb describe-load-balancers --load-balancer-name blog-CLB ``` <略> "BackendServerDescriptions": [ { "InstancePort": 8080, "PolicyNames": [ "my-ProxyProtocol-policy" ] } ], <略> ```
3. 動作確認
最後に動作確認です。
ProxyClientからcurlを叩いて、ProxyのAccessログに記録されている送信元のIPを確認します。
curl -v --proxy internal-blog-CLB-950891528.ap-northeast-1.elb.amazonaws.com:3128 -L https://www.serverworks.co.jp/ Accessログの確認 #ProxyProtocol設定前 1523597386.042 125 10.0.0.101 TCP_TUNNEL/200 199840 CONNECT www.serverworks.co.jp:443 - HIER_DIRECT/52.193.3.37 - #ProxyProtocol設定後 1523597931.985 192 10.0.0.23 TCP_TUNNEL/200 199832 CONNECT www.serverworks.co.jp:443 - HIER_DIRECT/52.193.3.37 -
ProxyProtocol設定前は、ELBのIP(10.0.0.101)が送信元になっていますが、設定後は、ProxyClientのIP(10.0.0.23)が記録されていますね。