[CDP] High Availability Forward Proxyパターンの構築

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

High Availability Forward Proxyパターンの構築方法ををご紹介します。[CDP] インターネットアクセス(アウトバウンド)パターンでご紹介したこれらのパターンを実際に構築して、より深い理解に役立つことを期待しています。

目的

Proxyサーバを経由したインターネットアクセス(アウトバンド)によって、以下の要件を満たす環境構築します。
・AWSのPublicサービスとの連携
・OSパッケージのアップデート(yum)

構築環境:
・Amazon Linux AMI 2014.03.2 (HVM) - ami-29dc9228
・squid-3.1.10-20.15.amzn1.x86_64

構成図

Private Subnetに配置したWeb serverは、Public SubnetのProxy server(Squid等)を経由して、インターネットアクセス(アウトバウンド)するパターンです。Private SubnetのデフォルトゲートウェイがVPNゲートウェイに設定している場合もプライベートアドレス空間で外部接続が可能です。

Forward Proxyパターンの例を以下の図に示します。インバウンドリクエストはELBを経由してWeb serverに対して水平分散します。アウトバウンドリクエストは単一のProxyインスタンス(Squid)を経由してインターネットにアクセスします。

 haproxy-build

同じ冗長化構成であるHigh Availability NATパターンと比較して、冗長化方式がロードバランス型、障害検知・復旧がAWSが提供するマネジメントサービスを活かして実現されている点が優れています。OSやサービス毎にProxy設定が可能であり、冗長構成が組める予算があればこの構成を選択したいです。

Proxy Serverの構築

Squidのインストール

 
$ sudo yum -y update 
$ sudo yum -y install squid 

Squidの設定(/etc/squid.conf)

「AWS のPublicサービスとの連携」と「パッケージの取得・更新(yum)」のリクエストはSquidを経由するので、プロトコルはhttpとhttpsのみ有効とします。Proxyサービスのリスンポートは8080を設定しています。

 
#
# Recommended minimum configuration:
#
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8	# RFC1918 possible internal network
#acl localnet src 172.16.0.0/12	# RFC1918 possible internal network
#acl localnet src 192.168.0.0/16	# RFC1918 possible internal network
#acl localnet src fc00::/7       # RFC 4193 local private network range
#acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

## source ip address
#acl localhost src xxx.xxx.xxx.xxx/32

acl SSL_ports port 443
acl Safe_ports port 80		# http
#acl Safe_ports port 21		# ftp
acl Safe_ports port 443		# https
#acl Safe_ports port 70		# gopher
#acl Safe_ports port 210		# wais
#acl Safe_ports port 1025-65535	# unregistered ports
#acl Safe_ports port 280		# http-mgmt
#acl Safe_ports port 488		# gss-http
#acl Safe_ports port 591		# filemaker
#acl Safe_ports port 777		# multiling http
acl CONNECT method CONNECT

#
# Recommended minimum Access Permission configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost
http_access deny manager

# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost

# And finally deny all other access to this proxy
http_access deny all

# Squid normally listens to port 3128
#http_port 3128
http_port 8080

# We recommend you to use at least the following line.
hierarchy_stoplist cgi-bin ?

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/spool/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid

## visible hostname
visible_hostname none

## forwarded for
forwarded_for off

## add header
request_header_access Referer deny all
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all

## cache
cache_mem 128 MB
cache_dir ufs /var/spool/squid 600 16 128

## replayheader
reply_header_max_size 50 KB

# Add any of your own refresh_pattern entries above these.
#refresh_pattern ^ftp:		1440	20%	10080
#refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
#refresh_pattern .		0	20%	4320

Web Serverの構築

yumのProxy設定(/etc/yum.conf)

Proxyサーバを経由してパッケージを更新できるようにWeb serverのyumの設定にProxyサーバーの設定を追加してください。

 
proxy=http://internal-proxy-ielb-123456789.ap-northeast-1.elb.amazonaws.com:8080 

awscliのProxy設定

Proxyサーバを経由してAWSのPublicサービスを利用できるようにProxyサーバの設定を環境変数として設定してください。全てのユーザーに設定したい場合は/etc/bashrcに、特定のユーザーのみに利用させたい場合はそのユーザのユーザーディレクトリ配下の.bash_profileに以下の環境変数を追加してください。

 
export AWS_DEFAULT_REGION=ap-northeast-1 
export http_proxy=http://internal-proxy-ielb-123456789.ap-northeast-1.elb.amazonaws.com:8080 
export https_proxy=https://internal-proxy-ielb-123456789.ap-northeast-1.elb.amazonaws.com:8080 

尚、AWS SDKからPublicサービスを利用する場合はClientConfigurationにProxyサーバの設定をすることでProxyサーバ対応となります。

ルーティング設定

Proxyサーバ

Proxyサーバはインターネットアクセスが必要なためデフォルトゲートウェイ(0.0.0.0/0)にインターネットゲートウェイが設定されています。

proxy-routing

Webサーバー

プライベートアドレス空間に対するルーティングのみで外部接続が可能なProxyサーバにルーティングされます。

web-routing

Internal-ELBの設定

Internal-ELBの作成

Web ServerからProxy Serverへのリクエストを水平分散するInternal-Load Balancer(内部ロードバランサー)を構築します。一般的なロードバランサーとの違いは、Create Load BalancerのListener Configurationです。まず、Create an internal load balancerをチェックします。次にロードバランサーのリスナー設定として、Load Balancer ProtocolにTCP、Load Balancer Portに8080を指定します。同様にProxyサーバのリスナー設定としてInstance ProtocolにTCP、Instance Portに8080を設定してください。最後のAdd EC2 Instancesではロードバランス対象のProxyサーバ(Proxy 1とProxy 2)を選択してください。ここでの注意点は、ProxyサーバのSquidが利用可能な状態でこの操作をしないといつまでもInServiceなりません。ロードバランサーの設定が終わり、5分以上経過後ProxyサーバがInServiceとなっていれば設定完了です。

proxy-ielb

Internal-ELBのセキュリティグループ設定

Internal-ELBのセキュリティグループ設定では、Webサーバの8080ポートのみInboundを許可しています。Inbound RuleにはWeb serverのSecurity Group(ID)を指定しています。AWSはルーティングやSecurity Groupの設定にCIDRはもちろん、インスタンス(ID)やSecurity Group(ID)を設定することができるので、煩雑なネットワーク設定を論理的に扱いヒューマンエラーを防止する仕組みがあることが特長です。

ielb-sg

 

動作確認

OSパッケージの追加・更新〜yumの実行

Webサーバから以下のコマンドの実行が成功したらProxyサーバとyumの設定が正しく動作しています。

 
$ sudo yum update
読み込んだプラグイン:priorities, update-motd, upgrade-helper
amzn-main/latest		| 2.1 kB     00:00
amzn-updates/latest		| 2.3 kB     00:00
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ aws-amitools-ec2.noarch 0:1.5.2-0.0.amzn1 を 更新
---> パッケージ aws-amitools-ec2.noarch 0:1.5.3-0.0.amzn1 を アップデート
---> パッケージ aws-apitools-as.noarch 0:1.0.61.4-1.0.amzn1 を 更新
---> パッケージ aws-apitools-as.noarch 0:1.0.61.5-1.0.amzn1 を アップデート
		:
		:

AWSのPublicサービスとの連携〜awscliの実行

Webサーバから以下のコマンドの実行が成功したらProxyサーバを経由してAWSのPublicサービスに接続しています。

 
$ aws ec2 describe-regions
{
    "Regions": [
        {
            "Endpoint": "ec2.eu-west-1.amazonaws.com",
            "RegionName": "eu-west-1"
        },
        {
            "Endpoint": "ec2.sa-east-1.amazonaws.com",
            "RegionName": "sa-east-1"
        },
        {
		:
		:

最後に

今回構築したProxyサーバを用いて、Forward Proxyパターンが構築することも可能です。セキュアなシステムではデフォルトGWをインターネットゲートウェイに設定することに警戒感を持たれることは少なくありません。そんな時こそミッションクリティカルな場面でも活用できるHigh Availability Forward Proxyパターンをお役立ていただけたら幸いです。