📖

複数AWSアカウントのNAT Gatewayを「VPC Peering+Proxy」で中央集約させる

2024/09/03に公開

はじめに

阿河です。

各AWSアカウントにNat Gatewayを配置し、外部通信を行えるようにするケースは多いと思います。
ただし複数AWSアカウントを管理していて、それぞれにNat Gatewayが必要な場合、トータルコストが大きくかかります。

そこで中央VPCを用意して、各アカウントからの通信を集約させる構成を組んでみました。
Proxyが冗長化されていない問題は別途解決は必要ですが、まずは基本構成として。

誰かの参考になれば幸いです。

前提

  • AWSアカウント * 3
  • Terraformの利用

目次

  1. 中央ネットワークを構築
  2. 子ネットワークを駆逐
  3. VPC Peering設定
  4. Proxy設定
  5. 疎通テスト

1. 中央ネットワークを構築

中央アカウントのディレクトリ構造は以下です。

% tree
.
├── compute.tf
├── network.tf
└── variables.tf

network.tf

resource "aws_vpc" "central_vpc" {
    cidr_block                       = "${var.vpc_range}"
    enable_dns_support               = true
    tags                             = {
        "Name"    = "${var.tenant}-central-vpc"
    }
}

resource "aws_subnet" "sub_pub1" {
    availability_zone                              ="ap-northeast-1a"
    cidr_block                                     ="${var.pub_sub1_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pub1"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
}

resource "aws_subnet" "sub_pub2" {
    availability_zone                              ="ap-northeast-1c"
    cidr_block                                     ="${var.pub_sub2_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pub2"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
}

resource "aws_subnet" "sub_pri1" {
    availability_zone                              ="ap-northeast-1a"
    cidr_block                                     ="${var.pri_sub1_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pri1"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
}

resource "aws_subnet" "sub_pri2" {
    availability_zone                              ="ap-northeast-1c"
    cidr_block                                     ="${var.pri_sub2_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pri2"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
}

resource "aws_internet_gateway" "igw" {
    tags                                           = {
        "Name" = "${var.tenant}-igw"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"

}

resource "aws_eip" "eip" {
    tags                                           = {
        "Name" = "${var.tenant}-eip"
    }
}

resource "aws_nat_gateway" "ngw" {
    tags                                           = {
        "Name" = "${var.tenant}-ngw"
    }
    subnet_id                                      ="${aws_subnet.sub_pub1.id}"
    allocation_id                                  ="${aws_eip.eip.id}"
    connectivity_type                              ="public"
}

resource "aws_route_table" "rtb_pub" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pub"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
    route {
        cidr_block                                 ="0.0.0.0/0"
        gateway_id                                 ="${aws_internet_gateway.igw.id}"
    }
}

resource "aws_route_table" "rtb_pri1" {
    tags                                           = {
        "Name" = "rtb-pri1"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
    route {
        cidr_block                                 ="0.0.0.0/0"
        nat_gateway_id                             ="${aws_nat_gateway.ngw.id}"
    }
/*
    route {
        cidr_block                = "${var.peering_vpc_cidr1}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central1.id}"
    }
    route {
        cidr_block                = "${var.peering_vpc_cidr2}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central2.id}"
    }
*/
}

resource "aws_route_table" "rtb_pri2" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pri2"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
    route {
        cidr_block                                 ="0.0.0.0/0"
        nat_gateway_id                             ="${aws_nat_gateway.ngw.id}"
    }
/*
    route {
        cidr_block                = "${var.peering_vpc_cidr1}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central1.id}"
    }
    route {
        cidr_block                = "${var.peering_vpc_cidr2}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central2.id}"
    }
*/
}

resource "aws_route_table_association" "public_rt_1a" {
  subnet_id      = aws_subnet.sub_pub1.id
  route_table_id = aws_route_table.rtb_pub.id
}

resource "aws_route_table_association" "public_rt_1c" {
  subnet_id      = aws_subnet.sub_pub2.id
  route_table_id = aws_route_table.rtb_pub.id
}

resource "aws_route_table_association" "private_rt_1a" {
  subnet_id      = aws_subnet.sub_pri1.id
  route_table_id = aws_route_table.rtb_pri1.id
}

resource "aws_route_table_association" "private_rt_1c" {
  subnet_id      = aws_subnet.sub_pri2.id
  route_table_id = aws_route_table.rtb_pri2.id
}

resource "aws_vpc_endpoint" "vpc_ep_s3" {
    tags                                           = {
        "Name" = "${var.tenant}-vpc-ep-s3"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
    vpc_endpoint_type                              ="Gateway"
    service_name                                   ="com.amazonaws.ap-northeast-1.s3"
    route_table_ids = [
        "${aws_route_table.rtb_pri1.id}",
        "${aws_route_table.rtb_pri2.id}"
    ]
}

/*
resource "aws_vpc_peering_connection" "vpc_connection_from_central1" {
  peer_owner_id = "${var.accepter_account1}"
  peer_vpc_id = "${var.peering_vpc_id1}"
  vpc_id      = "${aws_vpc.central_vpc.id}"
}

resource "aws_vpc_peering_connection" "vpc_connection_from_central2" {
  peer_owner_id = "${var.accepter_account2}"
  peer_vpc_id = "${var.peering_vpc_id2}"
  vpc_id      = "${aws_vpc.central_vpc.id}"
}
*/

compute.tf

data aws_ssm_parameter amzn2_ami {
  name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}

data "aws_iam_policy_document" "proxy_assume_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "proxy_role" {
  name               = "${var.tenant}-ec2-role"
  assume_role_policy = data.aws_iam_policy_document.proxy_assume_role.json
}

data "aws_iam_policy" "ssm_instance_core" {
  arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "default" {
  role       = aws_iam_role.proxy_role.name
  policy_arn = data.aws_iam_policy.ssm_instance_core.arn
}

resource "aws_iam_instance_profile" "proxy_profile" {
  name = "InstanceProfile"
  role = aws_iam_role.proxy_role.name
}

resource "aws_security_group" "proxy_sg" {
  name        = "${var.tenant}-ec2-sg"
  vpc_id      = aws_vpc.central_vpc.id
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.tenant}-ec2-sg"
  }
}

resource "aws_instance" "proxy" {
  ami                  = data.aws_ssm_parameter.amzn2_ami.value
  instance_type        = "t3.micro"
  iam_instance_profile = aws_iam_instance_profile.proxy_profile.name
  subnet_id            = aws_subnet.sub_pri1.id
  vpc_security_group_ids      = [aws_security_group.proxy_sg.id]
  lifecycle {
    ignore_changes = [
      ami,
    ]
  }
}

variables.tf

//環境の固有名
variable "tenant" {
  default = "test"
}

//リージョン
variable "region" {
  default = "ap-northeast-1"
}

//中央VPCのCIDR
variable "vpc_range" {
  default = "10.1.0.0/16"
}

//中央パブリックサブネットのCIDR
variable "pub_sub1_range" {
  default = "10.1.0.0/24"
}

//中央パブリックサブネットのCIDR
variable "pub_sub2_range" {
  default = "10.1.1.0/24"
}

//中央プライベートサブネットのCIDR
variable "pri_sub1_range" {
  default = "10.1.2.0/24"
}

//中央プライベートサブネットのCIDR
variable "pri_sub2_range" {
  default = "10.1.3.0/24"
}

/*
//アカウントAのアカウントID
variable "accepter_account1" {
  default = "xxxxxxxxxxxx"
}

//アカウントBのアカウントID
variable "accepter_account2" {
  default = "xxxxxxxxxxxx"
}

//アカウントAのVPC ID
variable "peering_vpc_id1" {
  default = "xxxxxxxxxxxx"
}

//アカウントAのVPC CIDR
variable "peering_vpc_cidr1" {
  default = "10.2.0.0/16"
}

//アカウントBのVPC ID
variable "peering_vpc_id2" {
  default = "xxxxxxxxxxxx"
}

//アカウントBのVPC CIDR
variable "peering_vpc_cidr2" {
  default = "10.3.0.0/16"
}
*/

上記のデプロイにより、下記がデプロイされます。
variables.tfではVPCのCIDRなどを指定しているので、環境に合わせてデフォルト値を入れてください。
※ピアリングまわりは、一旦コメントアウトしています。

  • 中央アカウントのVPCおよびネットワークリソース
  • NAT Gateway
  • EC2(Proxy)

2. 子ネットワークを構築

中央アカウントに繋げる子アカウント側にデプロイを行います。

ディレクトリ構造は以下です。
variables.tfの値は、それぞれ環境に合わせて変更下さい。

.
├── connection-test.tf
├── network.tf
└── variables.tf

network.tf

resource "aws_vpc" "account_vpc" {
    cidr_block                       = "${var.vpc_range}"
    enable_dns_support               = true
    enable_dns_hostnames             = true
    tags                             = {
        "Name"    = "${var.tenant}-vpc"
    }
}

resource "aws_subnet" "sub_pub1" {
    availability_zone                              ="ap-northeast-1a"
    cidr_block                                     ="${var.pub_sub1_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pub1"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
}

resource "aws_subnet" "sub_pub2" {
    availability_zone                              ="ap-northeast-1c"
    cidr_block                                     ="${var.pub_sub2_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pub2"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
}

resource "aws_subnet" "sub_pri1" {
    availability_zone                              ="ap-northeast-1a"
    cidr_block                                     ="${var.pri_sub1_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pri1"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
}

resource "aws_subnet" "sub_pri2" {
    availability_zone                              ="ap-northeast-1c"
    cidr_block                                     ="${var.pri_sub2_range}"
    tags                                           = {
        "Name" = "${var.tenant}-subnet-pri2"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
}

resource "aws_internet_gateway" "igw" {
    tags                                           = {
        "Name" = "${var.tenant}-igw"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
}

resource "aws_route_table" "rtb_pub" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pub"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
    route {
        cidr_block                                 ="0.0.0.0/0"
        gateway_id                                 ="${aws_internet_gateway.igw.id}"
    }
}

resource "aws_route_table" "rtb_pri1" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pri1"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
/*
    route {
        cidr_block                = "${var.peering_vpc_cidr}"
        vpc_peering_connection_id = "${var.vpc_connection_id}"
    }
*/
}

resource "aws_route_table" "rtb_pri2" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pri2"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
/*
    route {
        cidr_block                = "${var.peering_vpc_cidr}"
        vpc_peering_connection_id = "${var.vpc_connection_id}"
    }
*/
}

resource "aws_route_table_association" "public_rt_1a" {
  subnet_id      = aws_subnet.sub_pub1.id
  route_table_id = aws_route_table.rtb_pub.id
}

resource "aws_route_table_association" "public_rt_1c" {
  subnet_id      = aws_subnet.sub_pub2.id
  route_table_id = aws_route_table.rtb_pub.id
}

resource "aws_route_table_association" "private_rt_1a" {
  subnet_id      = aws_subnet.sub_pri1.id
  route_table_id = aws_route_table.rtb_pri1.id
}

resource "aws_route_table_association" "private_rt_1c" {
  subnet_id      = aws_subnet.sub_pri2.id
  route_table_id = aws_route_table.rtb_pri2.id
}

resource "aws_vpc_endpoint" "vpc_ep_s3" {
    tags                                           = {
        "Name" = "${var.tenant}-vpc-ep-s3"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
    vpc_endpoint_type                              ="Gateway"
    service_name                                   ="com.amazonaws.ap-northeast-1.s3"
    route_table_ids = [
        "${aws_route_table.rtb_pri1.id}",
        "${aws_route_table.rtb_pri2.id}"
    ]
}

connection-test.tf

resource "aws_vpc_endpoint" "ssm" {
  vpc_id              = aws_vpc.account_vpc.id
  service_name        = "com.amazonaws.${var.region}.ssm"
  vpc_endpoint_type   = "Interface"
  security_group_ids  = [aws_security_group.vpc_endpoint_sg.id]
  subnet_ids          = [aws_subnet.sub_pri1.id]
  private_dns_enabled = true
}
 
resource "aws_vpc_endpoint" "ec2messages" {
  vpc_id              = aws_vpc.account_vpc.id
  service_name        = "com.amazonaws.${var.region}.ec2messages"
  vpc_endpoint_type   = "Interface"
  security_group_ids  = [aws_security_group.vpc_endpoint_sg.id]
  subnet_ids          = [aws_subnet.sub_pri1.id]
  private_dns_enabled = true
}
 
resource "aws_vpc_endpoint" "ssmmessages" {
  vpc_id              = aws_vpc.account_vpc.id
  service_name        = "com.amazonaws.${var.region}.ssmmessages"
  vpc_endpoint_type   = "Interface"
  security_group_ids  = [aws_security_group.vpc_endpoint_sg.id]
  subnet_ids          = [aws_subnet.sub_pri1.id]
  private_dns_enabled = true
}

resource "aws_security_group" "vpc_endpoint_sg" {
  name   = "${var.tenant}-vpc-endpoint-sg"
  vpc_id = aws_vpc.account_vpc.id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "main" {
  name   = "${var.tenant}-sg"
  vpc_id = aws_vpc.account_vpc.id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

data "aws_ami" "latest_amazon_linux2" {
  most_recent = true
  owners      = ["amazon"]
 
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

resource "aws_instance" "main" {
  instance_type          = "t3.micro"
  ami                    = data.aws_ami.latest_amazon_linux2.id
  subnet_id              = aws_subnet.sub_pri1.id
  vpc_security_group_ids = [aws_security_group.main.id]
  iam_instance_profile   = aws_iam_instance_profile.test_profile.name
  root_block_device {
    volume_size           = 8
    volume_type           = "gp3"
    iops                  = 3000
    throughput            = 125
  }
  lifecycle {
    ignore_changes = [
      ami,
    ]
  }
}

resource "aws_iam_instance_profile" "test_profile" {
  name = "${var.tenant}-ssm"
  role = aws_iam_role.ssm_role.name
}
 
resource "aws_iam_role" "ssm_role" {
  name               = "${var.tenant}-ssm"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
 
data "aws_iam_policy_document" "assume_role" {
  statement {
    actions = ["sts:AssumeRole"]
 
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}
 
resource "aws_iam_role_policy_attachment" "ssm_managed_instance_core" {
  role       = aws_iam_role.ssm_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

variables.tf

variable "tenant" {
  default = "accounta"
}

variable "region" {
  default = "ap-northeast-1"
}

variable "vpc_range" {
  default = "10.5.0.0/16"
}

variable "pub_sub1_range" {
  default = "10.5.0.0/24"
}

variable "pub_sub2_range" {
  default = "10.5.1.0/24"
}

variable "pri_sub1_range" {
  default = "10.5.2.0/24"
}

variable "pri_sub2_range" {
  default = "10.5.3.0/24"
}

/*
variable "peering_vpc_cidr" {
  default = "10.1.0.0/16"
}

variable "vpc_connection_id" {
  default = "xxxxxxxxxxxxxxxx"
}
*/

上記のデプロイにより、下記がデプロイされます。
variables.tfではVPCのCIDRなどを指定しているので、環境に合わせてデフォルト値を入れてください。
※ピアリングまわりは、一旦コメントアウトしています。

  • 各アカウントのVPCおよびネットワークリソース
  • EC2(疎通確認要)
    ※中央アカウント側のNAT Gatewayを経由してインターネットへ出るため、子アカウント側にはNAT Gatewayは配置しません。

今回の検証では2AWSアカウントにデプロイを行っています。
CIDRは中央アカウント/各アカウント間に被らないようにしてください。

3. VPC Peering設定

次にVPC Peeringの設定を行います。

//中央アカウント

中央アカウントの各TFファイルについて、下記箇所のコメントアウトを外し、必要な設定を行います。

variables.tf

//アカウントAのアカウントID
variable "accepter_account1" {
  default = "xxxxxxxxxxxx" //子アカウント1のAWS アカウントIDを入力
}

//アカウントBのアカウントID
variable "accepter_account2" {
  default = "xxxxxxxxxxxx" //子アカウント2のAWS アカウントIDを入力
}

//アカウントAのVPC ID
variable "peering_vpc_id1" {
  default = "xxxxxxxxxxxx" //子アカウント1のVPC IDを入力
}

//アカウントAのVPC CIDR
variable "peering_vpc_cidr1" {
  default = "10.2.0.0/16" //子アカウント1のVPC CIDRを入力
}

//アカウントBのVPC ID
variable "peering_vpc_id2" {
  default = "xxxxxxxxxxxx" //子アカウント2のVPC IDを入力
}

//アカウントBのVPC CIDR
variable "peering_vpc_cidr2" {
  default = "10.3.0.0/16" //子アカウント2のVPC CIDRを入力
}

network.tf

resource "aws_route_table" "rtb_pri1" {
    tags                                           = {
        "Name" = "rtb-pri1"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
    route {
        cidr_block                                 ="0.0.0.0/0"
        nat_gateway_id                             ="${aws_nat_gateway.ngw.id}"
    }
    route {
        cidr_block                = "${var.peering_vpc_cidr1}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central1.id}"
    }
    route {
        cidr_block                = "${var.peering_vpc_cidr2}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central2.id}"
    }
}

resource "aws_route_table" "rtb_pri2" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pri2"
    }
    vpc_id                                         ="${aws_vpc.central_vpc.id}"
    route {
        cidr_block                                 ="0.0.0.0/0"
        nat_gateway_id                             ="${aws_nat_gateway.ngw.id}"
    }
    route {
        cidr_block                = "${var.peering_vpc_cidr1}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central1.id}"
    }
    route {
        cidr_block                = "${var.peering_vpc_cidr2}"
        vpc_peering_connection_id = "${aws_vpc_peering_connection.vpc_connection_from_central2.id}"
    }
}
resource "aws_vpc_peering_connection" "vpc_connection_from_central1" {
  peer_vpc_id = "${var.peering_vpc_id1}"
  vpc_id      = "${aws_vpc.central_vpc.id}"
  auto_accept = true
}

resource "aws_vpc_peering_connection" "vpc_connection_from_central2" {
  peer_vpc_id = "${var.peering_vpc_id2}"
  vpc_id      = "${aws_vpc.central_vpc.id}"
  auto_accept = true
}

上記デプロイ(変更)の結果、VPCページの「Peering connections」に設定が現れます。

次に子アカウント側の「Peering connections」ページに移り、「Accept request」を行います。


中央アカウント-2アカウント間のピアリングが、Activeになることを確認します。

//子アカウント側

variables.tf

variable "peering_vpc_cidr" {
  default = "10.1.0.0/16" //中央アカウントのVPC CIDR
}

variable "vpc_connection_id" {
  default = "xxxxxxxxxxxxxxxx" //Peering Connection ID
}

network.tf

resource "aws_route_table" "rtb_pri1" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pri1"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
    route {
        cidr_block                = "${var.peering_vpc_cidr}"
        vpc_peering_connection_id = "${var.vpc_connection_id}"
    }
}

resource "aws_route_table" "rtb_pri2" {
    tags                                           = {
        "Name" = "${var.tenant}-rtb-pri2"
    }
    vpc_id                                         ="${aws_vpc.account_vpc.id}"
    route {
        cidr_block                = "${var.peering_vpc_cidr}"
        vpc_peering_connection_id = "${var.vpc_connection_id}"
    }
}

  • VPCピアリング設定と、ルート設定が完了しました。

4. Proxy設定

今のままでは子アカウント~中央アカウントのNat Gatewayを経由した外部通信ができないので、中央アカウントのEC2にSquidの設定を入れます。


中央アカウントのAWSマネジメントコンソールにログイン。
Proxyサーバに、Session Managerで入ります。

//Squidのインストール & confファイル作成

$ sudo yum update -y
$ sudo yum install squid -y
$ sudo touch /etc/squid/squid.conf

// etc/squid/squid.confを編集

acl localnet src 10.2.0.0/16 //子アカウント側に合わせる
acl localnet src 10.3.0.0/16 //子アカウント側に合わせる   

acl Safe_ports port 80          # http
acl Safe_ports port 443         # https
http_access deny !Safe_ports

acl SSL_ports port 443          # https
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports

# ホワイトリストを指定
acl whitelist dstdomain "/etc/squid/whitelist"

http_access deny !localnet

http_access allow whitelist

http_access deny all

http_port 3128

no_cache deny all

coredump_dir /var/spool/squid

logformat squid %tl %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt

visible_hostname unknown

forwarded_for off
request_header_access User-Agent deny all
request_header_access Referer deny all
request_header_access X-Forwarded-For deny all
request_header_access Via deny all
request_header_access Cache-Control deny all

設定ファイルを更新します。

$ sudo systemctl start squid
$ sudo systemctl enable squid

Squidの起動停止を行います。

$ sudo touch /etc/squid/whitelist

次にホワイトリストの設定を行います。

//etc/squid/whitelist

.google.com

テストとしてgoogle.comを指定しました。

$ sudo chmod 644 /etc/squid/whitelist
$ sudo chown squid:squid /etc/squid/whitelist

$ sudo systemctl reload squid

リロードします。

最後にEC2(Proxy)のセキュリティグループを、環境に合わせて設定してください。

5. 疎通テスト

子アカウント1のEC2に対して、Session Managerにログインします。

ping ※プロキシサーバのIPアドレス

まず中央アカウントのProxyサーバに疎通確認をします。
EC2(Proxy)のプライベートIPアドレスを指定してください。

疎通ができることを確認します。
疎通ができない場合は、Proxyのセキュリティグループ設定等を御確認ください。

$ export http_proxy=http://10.1.2.49:3128 //プロキシサーバのipアドレスを入力
$ export https_proxy=http://10.1.2.49:3128 //プロキシサーバのipアドレスを入力

$ curl -I https://www.google.com //ホワイトリストで許可
HTTP/1.1 200 Connection established

$ curl -I https://www.amazon.com //ホワイトリストに記載なし
HTTP/1.1 403 Forbidden
  • google.comへのアクセスができること
  • それ以外は拒否されること

上記を確認します。
想定どおりの挙動となりました。

子アカウント2についても同様に疎通テストを行い、疎通できることを確認してください。

おわりに

別途Proxyサーバの冗長化については、追って記事を書こうと思います。
誰かの参考になれば幸いです。

御覧いただきありがとうございました。

MEGAZONE株式会社 Tech Blog

Discussion