クライアントからの通信を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 のリスナーの設定」を参照してください。
検証構成
検証作業
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
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を作成しています。
・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)が記録されていますね。