You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS安全组引用配置异常:EC2间Flask服务访问超时排查

问题:EC2实例间通过安全组引用访问Flask应用超时的原因分析

我搭建了以下最小可复现的Terraform环境:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.21.0"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

data "aws_ami" "amazon_linux" {
  most_recent = true

  owners = ["amazon"]

  filter {
    name   = "image-id"
    values = ["ami-0a23a9827c6dab833"]
  }
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public" {
  cidr_block        = "10.0.1.0/24"
  vpc_id            = aws_vpc.main.id
  availability_zone = "eu-central-1a"
}

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

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

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

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

resource "aws_security_group" "inbound" {
  name        = "ingress-ec2"
  description = "For the EC2 that has the inbound traffic"
  vpc_id      = aws_vpc.main.id
}

resource "aws_security_group" "outbound" {
  name        = "egress-ec2"
  description = "For the EC2 that has the outbound traffic"
  vpc_id      = aws_vpc.main.id
}

resource "aws_vpc_security_group_ingress_rule" "main" {
  security_group_id            = aws_security_group.inbound.id
  from_port                    = 5000
  to_port                      = 5000
  ip_protocol                  = "tcp"
  referenced_security_group_id = aws_security_group.outbound.id
}

resource "aws_vpc_security_group_egress_rule" "main" {
  security_group_id            = aws_security_group.outbound.id
  from_port                    = 5000
  to_port                      = 5000
  ip_protocol                  = "tcp"
  referenced_security_group_id = aws_security_group.inbound.id
}

resource "aws_vpc_security_group_ingress_rule" "ssh_inbound" {
  security_group_id = aws_security_group.inbound.id
  from_port         = 22
  to_port           = 22
  ip_protocol       = "tcp"
  cidr_ipv4         = "0.0.0.0/0"
}

resource "aws_vpc_security_group_ingress_rule" "ssh_outbound" {
  security_group_id = aws_security_group.outbound.id
  from_port         = 22
  to_port           = 22
  ip_protocol       = "tcp"
  cidr_ipv4         = "0.0.0.0/0"
}

resource "aws_vpc_security_group_egress_rule" "internet_inbound" {
  security_group_id = aws_security_group.inbound.id
  ip_protocol       = -1
  cidr_ipv4         = "0.0.0.0/0"
}

resource "aws_vpc_security_group_egress_rule" "internet_outbound" {
  security_group_id = aws_security_group.outbound.id
  ip_protocol       = -1
  cidr_ipv4         = "0.0.0.0/0"
}

resource "aws_key_pair" "inbound" {
  key_name   = "ingress-ec2"
  public_key = file(var.public_ssh_key)
}

resource "aws_instance" "inbound" {
  ami                         = data.aws_ami.amazon_linux.id
  instance_type               = "t2.micro"
  key_name                    = aws_key_pair.inbound.id
  subnet_id                   = aws_subnet.public.id
  security_groups             = [aws_security_group.inbound.id]
  associate_public_ip_address = true
}

resource "aws_key_pair" "outbound" {
  key_name   = "egress-ec2"
  public_key = file(var.public_ssh_key)
}

resource "aws_instance" "outbound" {
  ami                         = data.aws_ami.amazon_linux.id
  instance_type               = "t2.micro"
  key_name                    = aws_key_pair.outbound.id
  subnet_id                   = aws_subnet.public.id
  security_groups             = [aws_security_group.outbound.id]
  associate_public_ip_address = true
}

variable "public_ssh_key" {
  type    = string
  default = "~/.ssh/test_key.pub"
}

output "ingress-ec2" {
  value = aws_instance.inbound.public_ip
}

output "egress-ec2" {
  value = aws_instance.outbound.public_ip
}

在inbound EC2实例上启动简单Flask应用后,从outbound EC2实例访问该应用出现超时错误。将inbound安全组的5000端口入站规则从引用outbound安全组改为允许0.0.0.0/0后,访问恢复正常,确认是安全组配置导致的拦截。


原因分析

核心问题在于安全组引用规则匹配的是实例的私有IP,而非公网IP:

  • 当你从outbound实例访问inbound实例的公网IP时,数据包会通过互联网传输,此时数据包的源IP是outbound实例的公网IP,而非它的私有IP。
  • 你配置的aws_vpc_security_group_ingress_rule.main规则,是允许关联到outbound安全组的实例的私有IP发起的5000端口流量,公网IP不在这个规则的匹配范围内,所以被inbound安全组拦截。
  • 当改为cidr_ipv4 = "0.0.0.0/0"时,规则允许所有公网IP的流量,自然就能正常访问。

解决方案

如果想保留安全组引用的安全特性,不需要开放全公网访问,可以:

  • 在outbound实例上使用inbound实例的私有IP访问Flask应用,此时数据包在VPC内部传输,源IP是outbound的私有IP,符合安全组引用规则,能正常通过。
  • 若必须使用公网IP访问,可在inbound安全组的入站规则中添加outbound实例的公网IP作为允许的CIDR,或者保持0.0.0.0/0(不推荐生产环境使用)。

内容的提问来源于stack exchange,提问作者Kilian Calefice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 13:44:52