Aws-cdk: Disable security group rule creation in load balancers when passing your own security group

Created on 2 Jul 2019  路  6Comments  路  Source: aws/aws-cdk

  • I'm submitting a ...

    • [X] :beetle: bug report
  • What is the current behavior?
    If the current behavior is a :beetle:bug:beetle:: Please provide the steps to reproduce

When you pass your own security group to a load balancer, it forces creation of an ingress rule to port 80 and/or 443 from 0.0.0.0.

It's not only counterintuitive, it prevents us from using the load balancer constructs at all. We need to be able to lock down this LB to specific IP ranges.

I'd also argue there are unexpected security implications. I expect my security group to be respected, not edited.

  • What is the expected behavior (or behavior of feature suggested)?

Removal of this behavior when passing your own security group, or at the very least the ability to disable it.

  • What is the motivation / use case for changing the behavior or adding this feature?

We can't use the constructs without it, and implicitly changing a security group is not great behavior to begin with.

  • Please tell us about your environment:

    • CDK CLI Version: 0.36.1
    • Module Version: 0.36.1
    • OS: macOS
    • Language: TypeScript
needs-triage

Most helpful comment

@juho9000 thanks for sharing your solution for now. Here is the Typescript code snippet for the problem:

const sg = new SecurityGroup(this, "LoadBalancerSecurityGroup", {
      vpc: vpc,
      securityGroupName: "LoadBalancerSecurityGroup"
    });
// addrules

// Need to get immutable version because otherwise the ApplicationLoadBalancedFargateService 
// would create 0.0.0.0/0 rule for inbound traffic
const sgImmutable = SecurityGroup.fromSecurityGroupId(
  this,
  "LoadBalancerSecurityGroupImmutable",
  sg.securityGroupId,
  { mutable: false }
);

const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
  vpc: vpc,
  internetFacing: true,
  securityGroup: sgImmutable
});

// pass lb to ApplicationLoadBalancedFargateService

All 6 comments

I agree. Makes sense that it will be possible to disable automatic rule creation. It will be a while before we can attend to this. If this is blocking you, we'll gladly accept a PR.

I started doing just that, and while digging in realized that ApplicationListener is what opens the port in the LB's security group by default, not the LB itself. Passing open: false to it disables the behavior.

There might be value in allowing LoadBalancedFargateService and LoadBalancedEc2Service to specify security groups and disabling this behavior, but for now I'm going to close this. Sorry for the false alarm!

LoadBalancedEc2Service
I'm new to CDK but we are facing the same issue. I'm trying to deploy an AWS ecs sample image but restricted to say 2 originating sources (rather than everyone)

sg = ec2.SecurityGroup(self
                               , id="sg-ingress"
                               , vpc=vpc
                               , security_group_name=f"{props['namespace']}-ecs-lb-ingress")

        # Example IP Only
        sg.add_ingress_rule(peer=ec2.Peer.ipv4("188.10.10.10/32")
                            , connection=ec2.Port.tcp(80)
                            , description='Allow inbound 80 from Location 1')

        # Example IP Only 
        sg.add_ingress_rule(peer=ec2.Peer.ipv4("182.10.10.10/32")
                            , connection=ec2.Port.tcp(80)
                            , description='Allow inbound 80 from Location 2')

        lb = ApplicationLoadBalancer(self
                                    , id=f"{props['namespace']}-ecs-lb"
                                    , security_group=sg
                                     ,vpc=vpc
                                     ,load_balancer_name=f"{props['namespace']}-ecs-lb"
                                     ,internet_facing=True
                                     )

        fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService(
            self, f"{props['namespace']}-fargate-amazon-ecs-sample",
            cluster=cluster,
            service_name="amazon-ecs-sample",
            task_image_options={
                'image': ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")
            }
            ,load_balancer=lb
            ,assign_public_ip=False
            ,public_load_balancer=False
        )

This will create an inbound rule for everyone (0.0.0.0) on TCP / 80

How does one either:

  1. Remove the rule entry for "In, TCP 80, Everyone" as a post processed step (if possible)
  2. Specify a listener with the open=false on a LoadBlancedFargateService as per above ?

I was fighting with this issue for some time, so I thought I'd share my solution here. First I create my security group, then when passing a security group to the ALB I'm using SecurityGroup.fromSecurityGroupId, referencing the security group I created and passing mutable: false in props to it. ApplicationLoadBalancedFargateService also respects this, and the listener is not open to the world.

@juho9000 thanks for sharing your solution for now. Here is the Typescript code snippet for the problem:

const sg = new SecurityGroup(this, "LoadBalancerSecurityGroup", {
      vpc: vpc,
      securityGroupName: "LoadBalancerSecurityGroup"
    });
// addrules

// Need to get immutable version because otherwise the ApplicationLoadBalancedFargateService 
// would create 0.0.0.0/0 rule for inbound traffic
const sgImmutable = SecurityGroup.fromSecurityGroupId(
  this,
  "LoadBalancerSecurityGroupImmutable",
  sg.securityGroupId,
  { mutable: false }
);

const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
  vpc: vpc,
  internetFacing: true,
  securityGroup: sgImmutable
});

// pass lb to ApplicationLoadBalancedFargateService

Any word on this being fixed? Just encountered it myself and while the above solutions work, something native would be good.

Was this page helpful?
0 / 5 - 0 ratings