1つのインスタンスで240個のSSLサイトをホストしてみた
Instance Types - Amazon Elastic Compute Cloudによれば、m2.4xlargeなどのインスタンスタイプでは 8ENI x 30IPs(/ENI) = 240のIPアドレスを使用する事ができる、とあるので実際に試してみた。
必要な物
- EIP上限解除申請
必要な数のEIPを確保するため、250個のEIP上限申請を行った → http://aws.amazon.com/jp/contact-us/vpc-request/ - 7つのENIを作成
- m2.4xlargeインスタンス(Amazon Linux 2012.09を使用)
- 240個のEIP取得(こちらのスクリプトで取得しました)
構成を決める
VPCを10.1.0.0/16で作成、PublicSubnetを10.1.0.0/24で作成した。インスタンスに振る事のできるPrivateIPアドレスは10.1.0.4-10.1.0.254なので、10.1.0.10-10.1.0.249を使用する事にした。
また、10.1.0.{10.,40,70,100,130,160,190,210}はeth[0-7]に直接振り、それ以外のIPアドレスは追加PrivateIPアドレスとして振る。
インスタンス起動〜ENIの追加
まずeth0に10.1.0.10のIPアドレスを指定してインスタンスを起動した。さらに7個のENIを作成し、インスタンスに紐づけて行く。
$ for x in 40 70 100 130 160 190 210 ; do ec2-create-network-interface --private-ip-address 10.1.0.$x -g sg-xxxxxxxx ; done $ ec2-attach-network-interface eni-11111111 -i i-xxxxxxxx -d 1 $ ec2-attach-network-interface eni-22222222 -i -xxxxxxxx -d 2 : $ ec2-attach-network-interface eni-77777777 -i i-xxxxxxxx -d 7
インスタンスにログインしてifconfig upしておく
$ for x in {1..7} ; do sudo ifconfig eth$x up ; done $ /sbin/ifconfig | grep ^eth eth0 Link encap:Ethernet HWaddr 0A:D7:75:83:32:95 eth1 Link encap:Ethernet HWaddr 0A:D7:75:BA:6B:CB : eth7 Link encap:Ethernet HWaddr 0A:D7:75:92:9A:37
8本のNICが認識された。
プライベートIPアドレスの付与
$ for x in {11..39} ; do echo ec2-assign-private-ip-addresses -n eni-00000000 --secondary-private-ip-address 10.1.0.$x ; done
これをENIのIDとIPレンジを変えながら実行します。結果、
$ ip addr | grep 10.1.0. | wc -l 240
240個のPrivateIPアドレスが付きました!他のインスタンスから疎通を確かめます。
$ for x in {10..249} ; do ping -c 1 10.1.0.$x ; done
EIPの関連付け
ENIのリストとEIPのAllocationIDのリストからec2-associate-addressコマンドを生成するスクリプトを作りました。pipeでshで受けて1つずつ実行します。
$ ./associate.pl ec2-associate-address -aeipalloc-0fa9a064 -n eni-83cec1e8 -p 10.1.0.10 ec2-associate-address -aeipalloc-4a949d21 -n eni-83cec1e8 -p 10.1.0.11 : ec2-associate-address -aeipalloc-aeaba2c5 -n eni-3ec3cc55 -p 10.1.0.249 $ ./associate.pl | sh
各EIPの疎通を確認します
$ ec2-describe-addresses | grep vpc | cut -f 2 | xargs -P 1 -L 1 ping
httpd設定
nginxを入れます。またそれぞれのSSLサイト用にdocument rootとindex.htmlを用意します。
# yum install nginx # cd /usr/share/nginx/ # for x in `seq -w 0 239` ; do mkdir html$x ; echo $x > html$x/index.html ; done
次にSSL証明書を240個用意します。
# openssl genrsa -des3 -out server.key 1024 # cp server.key server.key.org # openssl rsa -in server.key.org -out server.key # for x in `seq -w 0 239` ; do openssl req -new -key server.key -out server$x.csr -batch -subj "/CN=ssl$x.example.com/" ; openssl x509 -in server$x.csr -days 365 -req -signkey server.key > server$x.crt ; done # cp server.key *.crt /etc/nginx
HTTPSサイト用コンフィグをgenerateするスクリプトをサイト数分実行します。
# cd /etc/nginx/conf.d # for x in `seq 0 239` ; do ./genconf.sh $x ; done # service nginx reload
これで準備が出来たと思われます。
アクセス確認
本来ならDNSへも登録して動作確認したい所ですが、面倒臭いのでhostsファイルで済ませる事にします。
{EIP000} ssl000.example.com {EIP001} ssl001.example.com : {EIP003} ssl239.example.com
みたいなhostsエントリーを作成し、全てのサイトにアクセスをしてみます。
$ for x in `seq -w 0 239` ; do curl -k https://ssl$x.example.com ; done 000 001 : 239 $ for x in `seq -w 0 239` ; do curl -ksvo /dev/null https://ssl$x.example.com 2>&1 | grep common ; done * common name: ssl000.example.com * common name: ssl001.example.com : * common name: ssl239.example.com
ちゃんと別のcommon nameが表示されているので、別の証明書を使用しているのが分かります。