SNI がまだそこまでポピュラーではないのでサーバ証明書を扱うには 1 枚に 1 つの IP address が要るのでお困りのそこのあなた!!

古い話になりますが、AWS では VPC 内の EC2 インスタンスのインターフェースに複数の IP address を割り当てることができるようになりました

http://aws.typepad.com/aws_japan/2012/07/multiple-ip-addresses-for-ec2-instances-in-a-virtual-private-cloud.html

まじでー。試そう、試しましょう。

http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/instance-types.html#AvailableIpPerENI

ドキュメントが追い付いてないみたいですが、VPC 内でも t1.micro が使えるようになり secondary IP address が 1 つ割り当てられるようです。

IP address を複数割り当てるぜ

インスタンスタイプによって ENI に付与できる Private IP address の数は異なりますが、割り当て自体は AWS Management Console から簡単にできます。Amazon Linux でいってみました。東京リージョンの ami-4e6cd34f を使ってみます。eth0 に auto-assign で 2 つ IP address を割り当ててみました。そして login。

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2012.09-release-notes/
[ec2-user@ip-10-0-2-67 ~]$

こんにちは、Amazon Linux! eth0 の 1 つ目の IP address は 10.0.2.67 になったようです。ifconfig とかしてみましょう。

[ec2-user@ip-10-0-2-67 ~]$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr 02:4B:68:4E:C2:77
          inet addr:10.0.2.67  Bcast:10.0.2.255  Mask:255.255.255.0
(snip)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
(snip)

eth0 があって 1 つしか IP address が割り当てられていません。でもね、

[ec2-user@ip-10-0-2-67 ~]$ ip addr list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 02:4b:68:4e:c2:77 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.67/24 brd 10.0.2.255 scope global eth0
    inet 10.0.2.52/24 brd 10.0.2.255 scope global secondary eth0
    inet6 fe80::4b:68ff:fe4e:c277/64 scope link
       valid_lft forever preferred_lft forever

/sbin/ip で見ると割り当てられているんです。実際には /etc/sysconfig/network-scripts/ec2net-functions の中で /sbin/ip が呼ばれているみたいですが、良く分からない。どっから値を取ってきてるかっつーと、そらもちろん meta-data から取っています。

[ec2-user@ip-10-0-2-67 iproute]$ curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:4b:68:4e:c2:77/local-ipv4s
10.0.2.67
10.0.2.52

/sbin/ip は AF_NETLINK な domain の socket を経由して device をごにょごにょするらしい。合ってるかな。もぉ ifconfig は古いらしいぜ! とにかく、ping を打つと

[ec2-user@ip-10-0-2-67 iproute]$ ping -c 3 10.0.2.52
PING 10.0.2.52 (10.0.2.52) 56(84) bytes of data.
64 bytes from 10.0.2.52: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 10.0.2.52: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 10.0.2.52: icmp_seq=3 ttl=64 time=0.022 ms

--- 10.0.2.52 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.022/0.025/0.028/0.006 ms

通ります。Amazon Linux でない AMI 使う場合でも、/sbin/ip 使ってもいいですし、良くある eth0:1 みたいなエイリアス使っても動かないことはないっつー感じです。

更に、この 2 つの Private IP address にそれぞれ EIP を紐づけておきましょう。

ApacheSSL するぜ

mod_ssl package をインストールします。

[ec2-user@ip-10-0-2-67 iproute]$ sudo yum install mod_ssl

証明書が欲しいのですがオレオレで十分なので適当に 2 枚作ります。

[ec2-user@ip-10-0-2-67 iproute]$ openssl req -new -x509 -newkey rsa:2048 -keyout 1.key -out 1.pem -nodes
[ec2-user@ip-10-0-2-67 iproute]$ openssl req -new -x509 -newkey rsa:2048 -keyout 2.key -out 2.pem -nodes

/etc/httpd/conf.d/ssl.conf ができてて

<VirtualHost _default_:443>

# General setup for the virtual host, inherited from global configuration
#DocumentRoot "/var/www/html"
#ServerName www.example.com:443

と VirtualHost が用意されているので、これをコピーして

  • の _default_ を Private IP address に
  • ServerName を適当に
  • SSLCertificateFile に上で作った証明書を
  • SSLCertificateKeyFile に上で作った秘密鍵

設定した VirtualHost を 2 つ作ります。そして

[ec2-user@ip-10-0-2-67 iproute]$ /etc/init.d/httpd start

ブラウザで接続して確認しよう

省略。それぞれの IP address に HTTPS で繋ぐともちろん警告が出ますが、証明書を確認すると異なる証明書が提示されてるはずです。

結論

Apache より nginx が好きです。ありがとう id:moriyoshi!