AWSで最低限セキュアな構成を組む


# 最低限セキュアな構成とは

「最低限セキュアな構成」を次のように定義する。

1. Webサーバーやデータベースサーバーが直接、インターネットに公開されていない。
1. 公開・非公開に関わらず、特定のポートのみインバウンドを受け付けている。
1. 非公開のサブネットは特定のサブネットからのみインバウンドを受け付けている。
1. 踏み台サーバーは必要な時のみ存在している。

この定義を満たす構成は次のようになる。

![スクリーンショット 2014-10-11 20.18.24.png](https://qiita-image-store.s3.amazonaws.com/0/41502/4c26dade-1211-d66f-c3e9-ff305452f44c.png "aws-structure.png")

# 構築手順

ざっくりと以下の手順を踏む。

1. VPCの構築
1. パブリックSubnetの構築
  1. Subnetの構築
  1. Internet Gatewayの構築
  1. Route tableの構築
1. プライベートSubnetの構築
  1. Subnetの構築
  1. パブリックSubnetにNATインスタンスを構築
  1. Elastic IPのアロケートとNATインスタンスへの結び付け
  1. Route tableの構築
1. Auto Scaling Groupのための前準備
  1. プライベートSubnetにEC2インスタンス（Webサーバーとして）
  1. パブリックSubnetにEC2インスタンス（踏み台サーバーとして）
  1. 踏み台サーバーからWebサーバーにログインしてApacheをインストール
  1. WebサーバーのAMIを作成する
1. Elastic Load Balancerの構築
1. Auto Scaling Groupの構築
1. アクセスして確認

## VPCの構築

1. ServicesからVPCを選択（＝ VPC Dashboard）
1. 「n VPCs」となっているリンクを選択（画面が変わる）
1. 「Create VPC」ボタンを押下
  1. Name tagは適当に（vpc-servicename-stgとかvpc-servicename-prodとか）
  1. CIDR blockは例示されている10.0.0.0/16で問題無い
  1. TenancyはDefaultで
  1. 「Yes, Create」ボタンを押下

※以降、VPCのCIDR blockを10.0.0.0/16とした前提で記述する。

## パブリックSubnetの構築

1. VPC Dashboard左メニューから「Subnets」を選択
1. 「Create Subnet」ボタンを押下
  1. Name tagは適当に（subnet-servicename-stg-publicとか）
  1. VPCは前述「VPCの構築」で作成したVPCを選択
  1. Availability Zoneはap-northeast-1aを選択（BCPの観点からAZを分けたり、RDSでMulti-AZを組んだりするまでは、単一のAZを選択して良いと思う）
  1. CIDR blockは10.0.0.0/24とする
  1. 「Yes, Create」ボタンを押下
1. VPC Dashboard左メニューから「Internet Gateways」を選択
1. 「Create Internet Gateway」ボタンを押下
  1. Name tagは適当に（igw-servicename-stgとか）
  1. 「Yes, Create」ボタンを押下
1. 今作成したInternet Gatewayの左端の四角が選択されている事を確認して（されていなければ選択して）、「Attach to VPC」ボタンを押下
  1. VPCは前述「VPCの構築」で作成したVPCを選択
  1. 「Yes, Attach」ボタンを押下
1. VPC Dashboard左メニューから「Route Tables」を選択
1. 「Create Route Table」ボタンを押下
  1. Name tagは適当に（rtb-servicename-stg-publicとか）
  1. VPCは前述「VPCの構築」で作成したVPCを選択
  1. 「Yes, Create」ボタンを押下
1. 今作成したRoute Tableの左端の四角が選択されている事を確認して（されていなければ選択して）、ページ下部の「Routes」タブを選択
1. 「Edit」ボタンを押下
  1. Destinationに「0.0.0.0/0」を入力
  1. Targetに作成したInternet Gatewayを選択（候補で出るはず）
  1. 「Save」ボタンを押下
1. VPC Dashboard左メニューから「Subnets」を選択
1. 既に作成したパブリック用Subnetの左端の四角が選択されている事を確認して（されていなければ選択して）、ページ下部の「Route Table」タブを選択
1. 「Edit」ボタンを押下
  1. Change toで今作成したRoute Table（rtb-servicename-stg-publicとか）を選択
  1. 「Save」ボタンを押下

## プライベートSubnetの構築

1. VPC Dashboard左メニューから「Subnets」を選択
1. 「Create Subnet」ボタンを押下
  1. Name tagは適当に（subnet-servicename-stg-privateとか）
  1. VPCは前述「VPCの構築」で作成したVPCを選択
  1. Availability Zoneはap-northeast-1aを選択
  1. CIDR blockは10.0.1.0/24とする
  1. 「Yes, Create」ボタンを押下
1. ServicesからEC2を選択（＝ EC2 Dashboard）
1. 「Launch Instance」ボタンを押下（ここはかなり読み辛いのでご容赦を）
  1. 左メニューから「Community AMIs」を選択
  1. 「Search community AMIs」エディットボックスに「NAT」と入力して検索。
  1. 「amzn-ami-vpc-nat-pv-2014.03.2.x86_64-ebs」の「Select」ボタンを押下（構築時の一番新しいものを選択すれば良いと思う）
  1. 「Family」列がMicro instancesの行の左端の四角が選択されている事を確認して（実際はサービスの用途に合わせて選ぶべき）、「Next: Configure Instance Details」ボタンを押下
  1. Networkには作成したVPCが選択されている事
  1. Subnetには作成したパブリックsubnetが選択されている事（ここが重要）
  1. 「Next: Add Storage」ボタンを押下
  1. 「Next: Tag Instance」ボタンを押下
  1. Keyに「Name」が指定されているはずなので、Valueに「servicename-stg-nat」等と入力
  1. 「Next: Configure Security Group」ボタンを押下
  1. Assign a security groupは「Create a new security group」を選択
  1. Security group nameは適当に（securitygroup-servicename-stg-natとか）
  1. Descriptionは適当に
  1. SSHのSource列は「Custom IP」を選択し、値は「10.0.0.0/16」を指定。yum等でインストールする時のために、HTTPも追加。Custom IPで値は10.0.0.0/16で。
  1. 「Review and Launch」ボタンを押下
  1. 「Launch」ボタンを押下
  1. 「Select an existing key pair or create a new key pair」と聞かれるので、「Create a new key pair」を選択し、Key pair nameに「servicename-stg-nat」等と入力し、「Download Key Pair」ボタンを押下してダウンロード
  1. 「Launch Instances」ボタンを押下
  1. 「View Instances」ボタンを押下
1. 作成中（のはず）のインスタンスを右クリックして「Change Source/Dest. Check」メニューを選択
  1. 「Yes, Disable」ボタンを押下
1. EC2 Dashboard左メニューから「Elastic IPs」を選択
1. 「Allocate New Address」を押下
  1. 「Yes, Allocate」ボタンを押下
1. 今アロケートされたElastic IPの左端の四角が選択されている事を確認して（されていなければ選択して）、「Associate Address」ボタンを押下
  1. Instanceを選択するとインスタンスが検索され、先程作成したNATインスタンスが一覧されるはずなので、これを選択
  1. 「Associate」ボタンを押下
1. VPC Dashboard左メニューから「Route Tables」を選択
1. 「Create Route Table」ボタンを押下
  1. Name tagは適当に（rtb-servicename-stg-privateとか）
  1. VPCは前述「VPCの構築」で作成したVPCを選択
  1. 「Yes, Create」ボタンを押下
1. 今作成したRoute Tableの左端の四角が選択されている事を確認して（されていなければ選択して）、ページ下部の「Routes」タブを選択
1. 「Edit」ボタンを押下
  1. Destinationに「0.0.0.0/0」を入力
  1. Targetに作成したNATインスタンスを選択（候補で出るはず）
  1. 「Save」ボタンを押下
1. VPC Dashboard左メニューから「Subnets」を選択
1. 既に作成したプライベート用Subnetの左端の四角が選択されている事を確認して（されていなければ選択して）、ページ下部の「Route Table」タブを選択
1. 「Edit」ボタンを押下
  1. Change toで今作成したRoute Table（rtb-servicename-stg-privateとか）を選択
  1. 「Save」ボタンを押下

## Auto Scaling Groupのための前準備

※慣れて来ているのでEC2インスタンス上げるところはかなり端折ります

1. プライベートSubnetにEC2インスタンス（Webサーバーとして）
  1. NATインスタンスを作成した要領で、プラベートSubnetにEC2インスタンスを作成する。Security groupは新規に作成して、10.0.0.0/16からのHTTPとSSHのみを許可するように設定すればとりあえず良い。
1. パブリックSubnetにEC2インスタンス（踏み台サーバーとして）
  1. NATインスタンスを作成した要領で、パブリックSubnetにEC2インスタンスを作成する。Security groupは新規に作成してSSHをAnywhereに。Key pairは厳重に管理。尚、踏み台サーバーは、使用する時以外はStoppedにしておく事で、さらにセキュアな状態とする。このデザインパターンを[On Demand Bastionパターン](http://aws.clouddesignpattern.org/index.php/CDP:OnDemand_Bastion%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)と呼ぶらしい。
  1. NATインスタンスにした要領でElastic IPを踏み台サーバーにAssociateする。
1. 踏み台サーバーからWebサーバーにはいってApacheをインストール
1. Webサーバーのインスタンスを選択して右クリックして「Stop」選択して「Yes, Stop」ボタン押下
1. Webサーバーのインスタンスを選択して右クリックして「Create Image」選択。画面見ればAMIの作り方は感じられるはず

```bash:Apacheのインストール
sudo yum -y install httpd
sudo chkconfig httpd on
sudo service httpd start
```

## Elastic Load Balancerの構築

1. EC2 Dashboard左メニューから「Load Balancers」を選択
1. 「Create Load Balancer」ボタンを押下
1. Load Balancer nameは適当に（elb-servicename-stgとか）
1. Create LB Insideは作成したVPCを指定
1. Create an internal load balancerはチェックoff
1. 今の所ポート80をポート80に転送するので設定は触らず
1. 「Continue」ボタンを押下
1. Configure Health Checkは触らず（WebサーバーにApacheインストールした際にindex.htmlを用意しておく事）
1. Healthy Thresholdは、実運用時は適切に設定するものの、構築を試行している時は最小の2がお勧め
1. 「Continue」ボタンを押下
1. Available Subnetsの中からパブリックSubnetのプラスマークを押下（ELBが属するSubnetを指定する事）
1. 「Continue」ボタンを押下
1. Security groupはポート80だけを許可した新しいものをここでは作成した
1. 「Continue」ボタンを押下
1. Add Instances to Load Balancerの画面では何も指定しない。後ほどAuto Scaling Groupを設定する際、現在作成しているELBを指定する事になる。
1. 「Continue」ボタンを押下
1. Key, Valueはとりあえず指定せず「Continue」ボタンを押下
1. 「Create」ボタンを押下

## Auto Scaling Groupの構築

1. EC2 Dashboard左メニューから「Auto Scaling Groups」を選択
1. 「Create Auto Scaling Group」ボタンを押下
1. 「Create launch configuration」ボタンを押下
1. My AMIsを選択
1. 先程作成したAMIを選択
1. インスタンスタイプ変更するなら変更して「Next: Configure details」ボタンを押下
1. Create Launch ConfigurationのNameは適当に（clc-servicename-stgなど）
1. Advanced Detailsを開きIP Address Typeは「Do not assign a public IP address to any instances.」を選択
1. 「Next: Add Storage」ボタンを押下
1. ストレージは適当に「Next: Configure Security Group」ボタンを押下
1. セキュリティグループはWebサーバーと同じものを選択し「Review」ボタンを押下
1. 「Create launch configuration」ボタンを押下
1. Key pair聞かれるのでWebサーバーのkey pairを選択して「Create launch configuration」ボタンを押下
1. Create Auto Scaling Groupの画面に来るので、
  1. Group nameは適当に（asg-servicename-stg等）
  1. Group sizeは1を指定
  1. Networkは作成したVPCを指定
  1. SubnetはプライベートSubnetを指定
  1. Advanced Detailsを開き、
      1. Load Balancingの「Receive traffic from Elastic Load Balancer(s)」をチェック
      1. チェックするとその下にボックスが現れるので、先程作成したELBを指定
      1. Health Check TypeはELBを選択
  1. 「Next: Configure scaling policies」ボタンを押下
1. 今の所は「Keep this group at its initial size」を選択
1. 「Next: Connfigure Notifications」ボタンを押下
1. 「Next: Configure Tags」ボタンを押下
1. 「Review」ボタンを押下
1. 「Create Auto Scaling Group」ボタンを押下

## アクセスして確認

1. EC2 Dashboard左メニューから「Load Balancers」を選択
1. 作成したLoad Balancerを選択
1. ページ下部の「Description」タブを選択
1. DNS Nameがでるので、ブラウザーから当該URLにアクセスして、表示を確認する

上記確認を行う前に、Auto Scaling Groupの構築を行うと、AMIからEC2インスタンスが起動する。しばらく待つとELBに組み込まれる。DescriptionタブのStatusが「1 of 1 instances in service」となってからアクセスする事。

また、Auto Scaling Groupによって作成されたEC2インスタンスをterminateしてみると、ELBがこれを検知し切り離され、Auto Scaling Groupのポリシーによって新しいEC2インスタンスが起動されELBに組み込まれ・・・、という動作も確認出来る。

## そして...
最後の方はグダグダな記述でごめんなさい。
セキュリティグループってどの程度分けるんだろうとかもっと試行錯誤した後、ChefやServerspecへ旅立つ予定です。