首页 > 解决方案 > 在实例安全组的入站部分使用 VPC 的 CIDR 会阻止负载均衡器到达它

问题描述

我在同一个子网中有一个网络负载均衡器和一个实例。我想将实例的入站流量限制为仅来自 VPC(因此互联网无法访问它)。所以我使用 VPC 的 CIDR 来执行此操作。但是,这不起作用。但是,如果我在安全组中更改此 CIDR 组以允许所有地址('0.0.0.0/0'),那么它确实有效。但它们位于同一个 VPC 和子网中,因此不应有所不同。

该实例是一个代理,我正在使用 python 请求对其进行测试,并将负载均衡器的地址添加为代理,如下所示:

requests.get('https://www.google.com' , proxies={'https':'<load_balancer_address>'})

它必须使用负载均衡器而不是直接使用实例,因为在上面一行中更改地址会使其阻塞,这意味着它肯定使用该地址作为请求的代理。

下面是描述我的整个设置的 terraform 代码。

我指的部分是 3128 端口的入口aws_security_group.instance_sg。更改此 CIDR 组以0.0.0.0/0使其工作。但我不明白为什么它已经不起作用了。

端口 54321(也来自负载均衡器)上的运行状况检查工作正常,并且具有相同的 CIDR 组。

provider "aws" {
    region = "eu-west-2"
}

resource "aws_vpc" "main" {
  cidr_block       = "172.31.0.0/16"
  instance_tenancy = "default"

  tags = {
    Name = "main"
  }
}

resource "aws_network_acl" "main" {
  vpc_id = aws_vpc.main.id

  ingress = [
    {
      from_port  = 22
      to_port    = 22
      protocol   = "tcp"
      rule_no    = 100
      action     = "allow"
      cidr_block = "${chomp(data.http.myip.body)}/32"
      ipv6_cidr_block = ""
      icmp_type = 0
      icmp_code = 0
    },
    {
      from_port  = 3128
      to_port    = 3128
      protocol   = "tcp"
      rule_no    = 200
      action     = "allow"
      cidr_block = "${chomp(data.http.myip.body)}/32"
      ipv6_cidr_block = ""
      icmp_type = 0
      icmp_code = 0
    }
  ]

  egress = [
    {
      from_port  = 443
      to_port    = 443
      protocol   = "tcp"
      rule_no    = 100
      action     = "allow"
      cidr_block = "0.0.0.0/0"
      ipv6_cidr_block = ""
      icmp_type = 0
      icmp_code = 0
    }
  ]

  tags = {
    Name = "main"
  }
}

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "main"
  }
}

resource "aws_route_table" "public_routes" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }

  tags = {
    Name = "public_routes"
  }
}

resource "aws_subnet" "public_zone" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "172.31.0.0/20"
  availability_zone = "eu-west-2a"
}

resource "aws_route_table_association" "public_zone_assoc" {
    subnet_id = aws_subnet.public_zone.id
    route_table_id = aws_route_table.public_routes.id
}

data "http" "myip" {
  url = "http://ipv4.icanhazip.com"
}

resource "aws_security_group" "bastion" {
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["${chomp(data.http.myip.body)}/32"]
  }

  egress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [ "172.31.0.0/16"]
  }
}

resource "aws_instance" "bastion" {
    ami = "ami-0194c3e07668a7e36"
    instance_type = "t2.micro"
    security_groups = [aws_security_group.bastion.id]
    tags = {
      "Name" = "Bastion"
    }
    subnet_id = aws_subnet.public_zone.id
    associate_public_ip_address = true
    key_name = "pumpbot"
}

resource "aws_security_group" "instance_sg" {
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    security_groups = [aws_security_group.bastion.id]
  }

  ingress {
    from_port   = 3128
    to_port     = 3128
    protocol    = "tcp"
    cidr_blocks = ["172.31.0.0/16"]
  }

  ingress {
    from_port   = 54321
    to_port     = 54321
    protocol    = "tcp"
    cidr_blocks = ["172.31.0.0/16"]
  }

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

resource "aws_instance" "proxies" {
    count = 1
    ami = "ami-0ef0d632eb136502d"
    instance_type = "t2.micro"
    security_groups = [aws_security_group.instance_sg.id]
    tags = {
      "Name" = "terraformproxy-${count.index + 1}"
    }
    subnet_id = aws_subnet.public_zone.id
    key_name = "pumpbot"
    associate_public_ip_address = true
}

resource "aws_lb_target_group" "tg" {
  name     = "lb-target-group"
  port     = 3128
  protocol = "TCP"
  vpc_id   = aws_vpc.main.id

  health_check {
    port = 54321
  }
}

resource "aws_lb_target_group_attachment" "tga" {
  count = length(aws_instance.proxies)
  target_group_arn = aws_lb_target_group.tg.arn
  target_id        = aws_instance.proxies[count.index].id
  port             = 3128
}

resource "aws_lb" "pump_bot_lb" {
  name               = "pump-bot-lb"
  load_balancer_type = "network"
  subnets = [aws_subnet.public_zone.id]

  enable_cross_zone_load_balancing   = true

  tags = {
    Name = "pump-bot-lb"
  }
}

resource "aws_lb_listener" "lb_listener" {
  load_balancer_arn = aws_lb.pump_bot_lb.arn
  port              = "3128"
  protocol          = "TCP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.tg.arn
  }
}

标签: amazon-web-servicesamazon-ec2amazon-vpcaws-security-groupaws-load-balancer

解决方案


网络负载均衡器按原样传递流量。实例将看到流量,就好像它直接来自客户端一样。流量不会有与之关联的网络负载均衡器的 IP 地址。这就是为什么您必须将安全组规则设置0.0.0.0/0为让您的 EC2 实例接受传入流量的原因。

有关更多详细信息,您可以阅读此问题的答案。


推荐阅读