在实例安全组的入站部分使用 VPC 的 CIDR 会阻止负载均衡器到达它

Posted

技术标签:

【中文标题】在实例安全组的入站部分使用 VPC 的 CIDR 会阻止负载均衡器到达它【英文标题】:Using the CIDR of the VPC in the inbound section of instance security group stops load balancer reaching it 【发布时间】:2021-12-15 17:59:03 【问题描述】:

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

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

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

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

描述我的整个设置的地形代码如下。

我指的是aws_security_group.instance_sg中端口3128的入口。将此 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
  

【问题讨论】:

【参考方案1】:

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

有关更多详细信息,您可以阅读this question 的答案。

【讨论】:

啊好吧,这是有道理的......有没有办法阻止互联网直接与我的实例连接(同时仍然允许负载均衡器)?我已经尝试使用 NAT 并将实例设为私有实例,但实际上我有几个实例并且需要它们都具有不同的公共 ip,并且使用 NAT,它们都将具有相同的公共 ip:NAT 的 ip。

以上是关于在实例安全组的入站部分使用 VPC 的 CIDR 会阻止负载均衡器到达它的主要内容,如果未能解决你的问题,请参考以下文章

IP 地址(在源列下)在 AWS 安全组的入站和出站规则中代表/或含义是啥?

运行 AWS opsworks 实例所需的基本安全组端口

您不能为现有 IPv4 CIDR 规则指定引用的组 ID。在 AWS 安全组中编辑入站规则时提示

AWS RDS Aurora - 如何使用 PgAdmin 进行连接?

VPC Peering 具有特定路由的配置

AWS CloudFormation VPC CIDR 分配给安全组