[AWS CloudFormation] VPCフローログ -> CloudWatch

CloudWatchとはAWSで提供されているモニタリングサービス
カスタムメトリクスという機能を利用することで、モニタリングを統合できる

– セットアップ不要で使用できる
– 異常な状態を検知して、自動復旧
– メトリクスに応じてアラート通知やアクションを設定できる
– 監視対象はEC2, EBSなど

### CloudWatchのサービス
「CloudWatch」: CPU, メモリなどを監視。メール、再起動、AutoScaleなどできる
「CloudWatch Logs」: 各種ログ
「CloudWatch Events」: APIイベントをトリガーにアクションを実行

AWSTemplateFormatVersion: "2010-09-09"
Description:
  VPCFlowLogs Settings

Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "Project Name Prefix"
        Parameters:
          - PJPrefix
      - Label:
          default: "VPCFlowLogs Configuration (Destination Type is CloudWatchLogs)"
        Parameters:
          - Filter
          - RetentionInDays

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Type: String

  Filter:
    Type: String
    Default: ALL
    AllowedValues: [ ALL, ACCEPT, REJECT ]

  RetentionInDays:
    AllowedValues: [ 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653 ]
    Type: Number
    Default: 30

Resources:
# ------------------------------------------------------------#
#  IAM Role for VPCFlowLogs
# ------------------------------------------------------------# 
# VPCFlowLogsIAMRole:
  VPCFlowLogsIAMRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Sub "${PJPrefix}-vpcflowlogs-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - "vpc-flow-logs.amazonaws.com"
            Action:
              - "sts:AssumeRole"

      Policies:
      - PolicyName: !Sub "${PJPrefix}-vpcflowlogs-policy"
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
              - "logs:CreateLogGroup"
              - "logs:CreateLogStream"
              - "logs:PutLogEvents"
              - "logs:DescribeLogGroups"
              - "logs:DescribeLogStreams"
              Resource: "*"

# ------------------------------------------------------------#
#  LogGroup
# ------------------------------------------------------------#
  LogGroup:
    Type: "AWS::Logs::LogGroup"
    Properties:
      LogGroupName: !Sub "${PJPrefix}-vpcflowlogs-group"
      RetentionInDays: !Ref RetentionInDays

# ------------------------------------------------------------#
#  VPCFlowLogs
# ------------------------------------------------------------# 
  VPCFlowLogs:
    Type: "AWS::EC2::FlowLog"
    Properties:
      DeliverLogsPermissionArn: !GetAtt VPCFlowLogsIAMRole.Arn
      LogGroupName: !Ref LogGroup
      ResourceId: { "Fn::ImportValue": !Sub "${PJPrefix}-vpc" }
      ResourceType: "VPC"
      TrafficType: !Ref Filter

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
#LogGroup
  LogGroupName:
    Value: !Sub "${PJPrefix}-vpcflowlogs-group"
    Export:
      Name: !Sub "${PJPrefix}-vpcflowlogs-group-name"
  LogGroupARN:
    Value: !GetAtt LogGroup.Arn
    Export:
      Name: !Sub "${PJPrefix}-vpcflowlogs-group-arn"

なるほど、監視はmakerelではなく、cloudwatchを使うのね。

[AWS CloudFormation] VPCフローログ → S3

VPCフローログとは、VPCのネットワークインターフェイスとの間で行き来するIPトラフィックに関する情報をキャプチャできるようにする機能

AWSTemplateFormatVersion: "2010-09-09"
Description:
  VPCFlowLogs Settings (Destination Type is S3)

Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "Project Name Prefix"
        Parameters:
          - PJPrefix

      - Label:
          default: "VPCFlowLogs Configuration (Destination Type is S3)"
        Parameters:
          - Filter

# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------# 
Parameters:
  PJPrefix:
    Type: String

  Filter:
    Type: String
    Default: ALL
    AllowedValues: [ ALL, ACCEPT, REJECT ]

Resources:
# ------------------------------------------------------------#
#  S3 Bucket for VPCFlowLogs
# ------------------------------------------------------------#  
# FlowLogsBucket
  FlowLogsBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "${PJPrefix}-vpcflowlogs" 

# ------------------------------------------------------------#
#  VPCFlowLogs
# ------------------------------------------------------------# 
  VPCFlowLogs:
    Type: "AWS::EC2::FlowLog"
    DependsOn: FlowLogsBucket
    Properties:
      LogDestination: !Sub "arn:aws:s3:::${FlowLogsBucket}"
      LogDestinationType: s3
      ResourceId: {"Fn::ImportValue": !Sub "${PJPrefix}-vpc" }
      ResourceType: "VPC"
      TrafficType: !Ref Filter

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
# FlowLogsBucket
  FlowLogsBucket:
    Value: !Ref FlowLogsBucket
    Export:
      Name: !Sub "${PJPrefix}-vpcflowlogs"

Object can be publicになるのが気になるが、割と簡単に出来る。

AWS CIDR

CIDR(Classless Inter-Domain Routing)
CIDRはIPアドレスの範囲で、172.10.0.0〜172.10.255.255と書くと面倒なので、172.10.0.0/16と書く
この”/16″というのは左の”16ビット固定” という意味
“172.10.0.4/32” は、32ビット(全部固定)という意味
RFC1918とは、プライベートIPアドレスについて記載したRFC文章

RFC1918の範囲
– クラスA(大規模ネットワーク): 10.0.0.0 ~ 10.255.255.255
– クラスB(大規模ネットワーク): 172.16.0.0 ~ 172.31.255.255
– クラスC(大規模ネットワーク): 192.168.0.0 ~ 192.168.255.255

予約されている5つのアドレス
10.0.0.0 ネットワークアドレス
10.0.0.1 VPCルータ
10.0.0.2 Amazonが提供するDNS
10.0.0.3 AWSで予約されているアドレス
10.0.0.255 ブロードキャストアドレス

そーゆーことか、めちゃくちゃ勉強になった

[AWS ALB] EC2で最初の接続だけ異常に重い時

EC2で最初の接続だけ異常に重く、一度接続すると、サクサク動く。
何故だ?curlで計測したところ、以下の様に最初の接続に130秒もかかっている。

$ curl ‘https://*.com/login’ -H ‘Accept-Encoding: gzip, deflate, sdch’ ept-Language: en-US,en;q=0.8,ja;q=0.6′ -H ‘Upgrade-Insecure-Requests: 1’ -H ‘User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36’ -H ‘Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8’ -H ‘Connection: keep-alive’ –compressed -o /dev/null -w “%{time_starttransfer}\n” -s
130.982826

最初、メモリが問題かと思って、増設し、さらにswapもつけたが、それでも変わらない。

$ df
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
devtmpfs 492676 0 492676 0% /dev
tmpfs 503444 0 503444 0% /dev/shm
tmpfs 503444 524 502920 1% /run
tmpfs 503444 0 503444 0% /sys/fs/cgroup
/dev/xvda1 18862060 13096136 5765924 70% /
tmpfs 100692 0 100692 0% /run/user/1000

$ free
total used free shared buff/cache available
Mem: 1006892 713376 72396 352 221120 154016
Swap: 1048572 768 1047804

明らかにおかしいと思ったら、2つのsubnetのうち1つがinternet gatewayにアタッチされていなかったのが原因。

AWS Elastic Load Balancing: Seeing extremely long initial connection time
https://stackoverflow.com/questions/35523421/aws-elastic-load-balancing-seeing-extremely-long-initial-connection-time

ALBだとAZで2つのsubnetの設定が必要だが、今回はインスタンスは1つしか使わないので、internet gatewayには1つしかアタッチしてなかった。もう一つのpublic subnetをigwにアタッチしたところ、0.63msに改善

$ curl ‘https://*.com/login’ -H ‘Accept-Encoding: gzip, deflate, sdch’ -H ‘Accept-Language: en-US,en;q=0.8,ja;q=0.6’ -H ‘Upgrade-Insecure-Requests: 1’ -H ‘User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36’ -H ‘Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8’ -H ‘Connection: keep-alive’ –compressed -o /dev/null -w “%{time_starttransfer}\n” -s
0.638270

メモリの問題じゃなかったああああああああああああああああああ 
なんてこったい

[AWS Network ACLs] ipアドレスベースでアクセス制御したい

AWS EC2で異常を検知した場合、ipアドレスベースでアクセス制御したい
セキュリティグループだと、プロトコルタイプ(http, https等)でしか制御できないが、ACLsだとipで制御できるらしい。

ACLsとは

ネットワークアクセスコントロールリスト (ACL) は、1 つ以上のサブネットのインバウンドトラフィックとアウトバウンドトラフィックを制御するファイアウォールとして動作する、VPC 用のセキュリティのオプションレイヤーです。

ほう。

rule numberの値が小さいほど、優先度が高い

Sourceでipアドレスを入力してdenyとするとアクセス拒否できる。
htaccessだとec2だけだが、ACLsだとVPS自体にアクセスできないようにできるので、良いですね。

EC2をprivate subnetに移し、SSH用のbastionサーバの構築

### 既存のWebサーバのAMIを取得
Instances -> Actions -> Image -> Create Image

### purivate subnetのインスタンスの作成
作成したAMIから、再度インスタンスを作る
${appName}-prd-01-private
vpc:dev-vpc
subnet:dev-subnet-private1
Public IP:enable
IAM role: s3readonly
Security group: prd

${appName}-prd-02-private
vpc:dev-vpc
subnet:dev-subnet-private2
Public IP:enable
IAM role: s3readonly
Security group: prd

### public subnetのインスタンス削除
instance -> instance state -> terminate

### ALBのターゲットグループに追加
TargetGroup -> Target -> 追加
->ALBのDNSを叩いて動作確認
->コンソールからinstanceのpublic ipを叩いてssh接続できない事を確認

### bastionのサーバ構築
Instance Type: t2.nano
VPC: dev-vpc
subnet: dev-public-subnet
Auto-assign Public IP: enable
storage size: 8Gib
tag: ${appName}-prd-bastion
security group: create ${appName}-sg-bastion, Custom TCP
key pair: 新規推奨

### bastionのkey pair
bastionサーバにログインし、home/ec2-user/.sshに 秘密鍵(***.pem)を配置する
bastionにSSHログイン

$ ssh ec2-user@*** -i  ~/.ssh/***.pem
$ sudo chmod 600 /home/ec2-user/.ssh/***.pem
$ cd .ssh
$ ls -l

### Webサーバのセキュリティグループ
ssh接続のソースをmyIPに変更

### bastionからprivate subnetのweb serverにログイン
$ ssh ec2-user@${private_ip} -i .ssh/aws-dev.pem

$ curl https://www.google.co.jp/
-> timeout
-> private subnetは、インターネットゲートウェイのルーティングが存在しないことが原因

### NATゲートウェイ作成
VPC -> NATGateways -> create
subnet: dev-subnet-public1
Elastic IP: 割り当て

Private route table
NAT Gateway 割り当て

curl https://www.google.co.jp/
-> レスポンスが返るようになる。

VPCセキュリティグループの作成

セキュリティグループとは?
-> セキュリティグループとはインスタンスに関連付ける仮想ファイアウォール
-> インバウンドトラフィックとアウトバウンドトラフィックを許可する形でルール追加
-> 拒否するルールは設定できない
-> セキュリティグループはsubnetの中

### Security groupの作成
Security group name: dev-security-group
Description: Allow SSH Access
VPC: dev-vpc

Edit inbound rules
Type: SSH
Protocol: TCP
PortRange: 22
Source: MyIP(全てのipを許可する場合は0.0.0.0/0)

VPC、public subnet、InternetGateway、RouteTableの作成

EC2の構成を見ると、VPCの中にsubnetがあり、その中にEC2が入る。
従って、EC2の前にVPC、subnetを作成していく。

1. VPCの作成
CIDR block

2. Subnetの作成
どこと通信できるか設定

3. Route Tableの作成
Subnet間や外部通信用の設定
SubnetとInternet Gatewayの設定

4. Internet Gatewayの作成
インターネットと通信することをRoute Tableに許可
VPCにアタッチして、Route Tableに紐づけ

5. Network ACLの設定
SubnetのInBound(内部への通信)とOutBound(外部への通信)制御の設定

6. Security Groupの設定
インスタンスのInBound(内部への通信)とOutBound(外部への通信)制御の設定

### 1. VPCの作成
name-tag: dev-vcp
IPv4 CIDR block: 192.168.0.0/16 (10.0.0.0/16などでも可)
※「/16」は16個のアドレスができるという意味。ネットマスク
※CIDRとはIPアドレスの記述形式

CIDR block: A.B.C.D/E
AはVPC作成時に設定(内部のルーティング)
BはVPC作成時に設定(内部のルーティング)
EはVPC作成時に設定
CはSubnet作成時に設定(subnetごとに分ける)
DはSubnet作成後に自動設定(Cから自動生成)

VPC作成時に、VPCのトラフィックをルーティングするためのルールを登録する「ルートテーブル」というリソースも作成される

### 2. subnetの作成
name-tag: dev-subnet-public
vpc: dev-vpc
VPC CIDRs: 192.168.0.0/16
IPv4 CIDR block: 192.168.1.0/28

### 3. Internet Gateway
name-tag: dev-igw
作成後、actionでdev-vcpにattach

### 4. RouteTable作成
どのIPアドレス宛の通信をInternet Gatewayにむけるか決める
name-tag: dev-routetable
vpc: dev-vpc

– ルートテーブルにインターネットゲートウェイへのルートを登録する
->ルートの編集
Destination: 0.0.0.0/0
Target: Internet-gateway igw-********
※VPC内宛以外の通信に関してはインターネットゲートウェイに向く

ルートテーブルからサブネットに紐付け
Subnet Associationsタブをクリック

以上で、VPC(dev-vcp)の中にpublic subnet(dev-subnet-public)ができて、RouteTable(dev-routetable)で、Internet Gatewayに紐付けられている状態ができました。

defaultVPCではなく、実際に作ることで、VPC、public subnet、InternetGateway、RouteTableについて、大幅に理解が深まります。

AWS subnet

A subnet is an address space that further divides the VPC. A subnet is always created in one AZ, and it is not possible to create a subnet that spans multiple AZs.

AWS 0.0.0.0/0

VPC default security group
The VPC automatically uses the default security group. If you do not specify another security group when launching an instance, each EC2 instance launced in VPC is automatically associated with the security group named “launch-wizard-xx”. For example, the security group name of the first EC2 instance to launch is “launch-wizard-1”.

outpoud
Destination: 0.0.0.0/0
Protocol: all
Port: all
Range: Allow all outgoing IPv4 traffic