Consulが使うポートとセキュリティグループの設定


まだ検証した段階だけど、こんな感じで運用してみようと思う。

`consul agent -server` を Server 。
`consul agent` を Client 。
２つ合わせて Agent と呼ぶことにする。

# Consulが使うポート

| 機能 | TCP/UDP | ポート | 説明 |
|---|:-:|:-:|---|
| Server RPC | TCP | 8300 | Server が他の Agent からRPCのリクエストを受け付ける |
| Serf LAN | TCP & UDP | 8301 | LAN用のゴシッププロトコル<br>全 Agent 同士が使う |
| Serf WAN | TCP & UDP | 8302 | WAN用のゴシッププロトコル<br>Server 同士が使う |
| CLI RPC | TCP | 8400 | consulコマンド実行時にローカルの Agent との通信に使われる |
| HTTP API | TCP | 8500 | Client が HTTP リクエストを受け付ける |
| DNS | TCP & UDP | 8600 | Agent が DNSクエリを受け付ける |

https://www.consul.io/docs/install/ports.html

# セキュリティグループの設定

Server と Client でセキュリティグループを２つ用意した。
セキュリティグループは５つまでしか装備できないので Client 用に１つ使ってしまうのはもったいないが、セキュリティグループ単位で対象を絞れるのでこれはこれで欠かせないと思う。
22 や 80 は省略。

## Server 用セキュリティグループ

Server 同士は全通信を可能にした。
HTTP/DNS API はローカルと通信するのでポートは開けないでよさそう。
Serf WAN の設定をする場合 8302 番ポートの設定が必要で、この場合 IP アドレスで指定するしかないかも。

| Type | Protocol | Port Range | Source |
|---|:-:|:-:|---|
| All Traffic | All | All | sg-xxxxxx(consul-server) |
| Custom TCP Rule | TCP | 8300 | sg-xxxxxx(consul-client) |
| Custom TCP Rule | TCP | 8301 | sg-xxxxxx(consul-client)|
| Custom UDP Rule | UDP | 8301 | sg-xxxxxx(consul-client)|

## Client 用セキュリティグループ

Agent 同士が Serf LAN を使えればよさそう。

| Type | Protocol | Port Range | Source |
|---|:-:|:-:|---|
| Custom TCP Rule | TCP | 8301 | sg-xxxxxx(consul-server)|
| Custom UDP Rule | UDP | 8301 | sg-xxxxxx(consul-server)|
| Custom TCP Rule | TCP | 8301 | sg-xxxxxx(consul-client)|
| Custom UDP Rule | UDP | 8301 | sg-xxxxxx(consul-client)|

# CloudFormation テンプレート

CloudFormationのテンプレートからセキュリティグループの部分を抜粋したもの。
`AWS::EC2::SecurityGroup` の中で自分自身を参照(`Ref`, `Fn::GetAtt`)するとエラーになるので `AWS::EC2::SecurityGroupIngress` を別リソースとして定義した。

```json
"Resources": {
  "ClientSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "for consul-client",
      "VpcId" : {"Ref" : "VpcId"},
      "Tags" : [
        {"Key" : "Name", "Value" : "consul-client"}
      ]
    }
  },
  "ClientSecurityGroupIngressSerfLanTcpFromServer": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "tcp",
      "FromPort" : "8301",
      "ToPort" : "8301",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      }
    }
  },
  "ClientSecurityGroupIngressSerfLanUdpFromServer": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "udp",
      "FromPort" : "8301",
      "ToPort" : "8301",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroupIngressSerfLanTcpFromClient": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "tcp",
      "FromPort" : "8301",
      "ToPort" : "8301",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroupIngressSerfLanUdpFromClient": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "udp",
      "FromPort" : "8301",
      "ToPort" : "8301",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "for consul-server",
      "VpcId" : {"Ref" : "VpcId"},
      "Tags" : [
        {"Key" : "Name", "Value" : "consul-server"}
      ]
    }
  },
  "ServerSecurityGroupIngressHttp": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "tcp",
      "FromPort" : "80",
      "ToPort" : "80",
      "CidrIp" : "192.168.0.0/16",
      "GroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroupIngressServerRpc": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "tcp",
      "FromPort" : "8300",
      "ToPort" : "8300",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroupIngressSerfLanTcp": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "tcp",
      "FromPort" : "8301",
      "ToPort" : "8301",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroupIngressSerfLanUdp": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "udp",
      "FromPort" : "8301",
      "ToPort" : "8301",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ClientSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      }
    }
  },
  "ServerSecurityGroupIngressEachOther": {
    "Type": "AWS::EC2::SecurityGroupIngress",
    "Properties": {
      "IpProtocol" : "-1",
      "FromPort" : "0",
      "ToPort" : "65535",
      "SourceSecurityGroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      },
      "GroupId": {
        "Fn::GetAtt": ["ServerSecurityGroup", "GroupId"]
      }
    }
  }
}
```