A10のリバースプロキシで外部サーバへ転送する設定

A10の調べ物で色々ググるがあまり出てこないので,今回はA10でのリバースプロキシの設定をまとめておこうと思う.
A10のハードウェアアプライアンスA10 Thunder 4430である.

現状確認と要件

オンプレ環境にLBとしてA10を設置しており,A10ではインターネット(エンドユーザ)からのトラフィックを配下のLANに流している.仮にhoge.co.jpというサービスをオンプレ環境にホストしているとして,https://hoge.co.jp/fuga.txtというファイルにアクセスされたらそのトラフィックを外部のサーバに流し,それ以外のパスについては従来通り配下のLANに流すような要求が発生したとする.外部サーバにはhttpsで通信し,外部サーバのFQDNpiyo.co.jpのようにhoge.co.jpとは異なることを想定している.今回の外部サーバはAWSにあるものとし,443番ポートを受け付けているALB(Application Load Balancer)とそこに80番ポートを受け付けているEC2がぶら下がっている構成にする.イメージを下図に示す.

f:id:a-mochan:20201218234415p:plain
構成図

上記の要件を実現するためにA10で実施すべきことの詳細を説明する.

SNATの必要性

上記の通信を実現するには,A10で外部からのリクエストを受け取ったとき,ネットワーク層のソースIPをNAT(SNAT)させる必要がある.なぜなら,SNATをしないと外部サーバへたどり着くリクエストのソースIPはクライアントのものになり,外部サーバからのレスポンスがA10を経由せずクライアントに直接返されてしまうからである.クライアントからするとリクエストはA10に送信したのに,レスポンスは外部サーバから受け取ってしまう形となり通信ができない状態となる.したがってA10ではSNATも考慮する.

復号化と再暗号化

A10では受け取ったリクエストのパスで振り分け先を判断するので,一度復号しないとパスを確認することができない.また,A10・外部サーバ間はhttpsの通信を想定している.したがってA10では,受け取ったリクエストのアプリケーション層の情報(主にパス)を確認するために一度復号化し,再度暗号化して外部サーバへ通信する必要がある.

ホストの書き換え

A10配下のLANにホストしてあるFQDNhoge.co.jpで,外部サーバにホストしてあるFQDNpiyo.co.jpを想定しているので,A10では外部サーバへ転送する際にホストを書き換える必要がある.

実現方法

上記で説明してきた要件をA10では以下の手順で設定していく.

  1. ALBをサーバとして登録,サーバをサービスグループとして登録
  2. IP Source Pool作成
  3. Client SSL,Server SSLテンプレート作成
  4. aFlex作成
  5. バーチャルサーバ作成

1. ALBをサーバとして登録

外部サーバとしてA10にALBを登録する.外部サーバの登録方法としてIPかFQDNを選べるので今回はALBから払い出されるDNS名を指定する.ヘルスチェックは外部サーバによって決めればよいが,今回は443ポートチェックで行う.作成したサーバをサービスグループとして登録する.

slb server piyo-alb piyo-alb-1111111111.ap-northeast-1.elb.amazonaws.com
  port 443 tcp
    health-check tcp_443
slb service-group piyo-sg tcp
  member piyo-alb 443

2. IP Source Pool作成

SNATのためのIPプール作成.

ip nat pool global_ip_pool 33.44.55.1 33.44.55.10 netmask /24 ip-rr

3. Client SSL,Server SSLテンプレート作成

復号化・暗号化するためのClient SSL,Server SSLテンプレート作成.秘密鍵や証明書の登録は割愛する.

slb template client-ssl any.co.jp
  ca-cert CA
  cert any.co.jp
  key any.co.jp
slb template server-ssl reverse-proxy-re-encrypt

4. aFlex作成

A10のリバースプロキシを実現するキモとなるのがこのaFlexである.1~3で設定した内容をaFlexのスクリプトで定義する.また,ホストの書き換えもaFlexで行う.reverse-proxy-aflexという名前で作成する.

when HTTP_REQUEST {
  if { [HTTP::path] matches_regex "^/fuga.txt$"} {
    HTTP::header insert X-Forwarded-For [IP::client_addr]   # クライアントのIPを外部サーバのアプリケーションログに出したければこの設定を入れる
    HTTP::header Host "piyo.co.jp"
    pool piyo-sg
    snatpool global_ip_pool
    SSL::template serverside reverse-proxy-re-encrypt
  }
}

5. バーチャルサーバ作成

/fuga.txtの場合はaFlexで処理し,それ以外の場合はLANに流すサービスグループを指定したバーチャルサーバを作成.

slb virtual-server reverse-proxy-vs 111.222.11.22
  port 443 https
    aflex reverse-proxy-aflex
    service-group hoge-sg   # `/fuga.txt`ではないパスの場合はLANに流すようにサービスグループを設定
    template client-ssl any.co.jp   #復号化

以上の設定でhttps://hoge.co.jp/fuga.txtにアクセスするとALBに転送され,その他のパスについてはLANに流れるようになる.

まとめ

  • A10のリバースプロキシで外部サーバへ転送した
  • 今回はインターネットを経由するパターンで設定したが,専用線などが引いてありインターネットを経由しない場合は再暗号化しなくてもよいと思われ,今回の設定からいくつかステップを省略することが考えられる
  • A10を使用しているオンプレからAWSへ移行する際には使用する場合があるかもしれない