Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Security Policy for Listener in Application load balancer #4099

Merged
merged 9 commits into from Oct 22, 2022
2 changes: 2 additions & 0 deletions internal/pkg/deploy/cloudformation/stack/env.go
Expand Up @@ -405,13 +405,15 @@ func (e *EnvStackConfig) publicHTTPConfig() (template.HTTPConfig, error) {
CIDRPrefixListIDs: e.in.CIDRPrefixListIDs,
ImportedCertARNs: e.importPublicCertARNs(),
ELBAccessLogs: elbAccessLogsConfig,
SecurityPolicy: e.in.Mft.EnvironmentConfig.HTTPConfig.Public.SecurityPolicy,
}, nil
}

func (e *EnvStackConfig) privateHTTPConfig() template.HTTPConfig {
return template.HTTPConfig{
ImportedCertARNs: e.importPrivateCertARNs(),
CustomALBSubnets: e.internalALBSubnets(),
SecurityPolicy: e.in.Mft.EnvironmentConfig.HTTPConfig.Private.SecurityPolicy,
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
Expand Up @@ -725,6 +725,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
InternalLoadBalancer:
Metadata:
'aws:copilot:description': 'An internal Application Load Balancer to distribute private traffic from within the VPC to your services'
Expand Down Expand Up @@ -776,6 +777,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
Expand Up @@ -400,6 +400,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
HTTPSImportCertificate2:
Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
Condition: ExportHTTPSListener
Expand Down Expand Up @@ -456,6 +457,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
Expand Up @@ -425,6 +425,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
HTTPSImportCertificate2:
Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
Condition: ExportHTTPSListener
Expand Down Expand Up @@ -481,6 +482,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
Expand Up @@ -821,6 +821,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalLoadBalancer:
Metadata:
'aws:copilot:description': 'An internal Application Load Balancer to distribute private traffic from within the VPC to your services'
Expand Down Expand Up @@ -872,6 +873,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
Expand Up @@ -729,6 +729,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalLoadBalancer:
Metadata:
'aws:copilot:description': 'An internal Application Load Balancer to distribute private traffic from within the VPC to your services'
Expand Down Expand Up @@ -780,6 +781,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
Expand Up @@ -521,6 +521,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
HTTPSImportCertificate2:
Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
Condition: ExportHTTPSListener
Expand Down Expand Up @@ -577,6 +578,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
Expand Up @@ -559,6 +559,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalLoadBalancer:
Metadata:
'aws:copilot:description': 'An internal Application Load Balancer to distribute private traffic from within the VPC to your services'
Expand Down Expand Up @@ -610,6 +611,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: 'ELBSecurityPolicy-2016-08'
InternalWorkloadsHostedZone:
Metadata:
'aws:copilot:description': 'A hosted zone named test.demo.internal for backends behind a private load balancer'
Expand Down
6 changes: 4 additions & 2 deletions internal/pkg/manifest/env.go
Expand Up @@ -434,6 +434,7 @@ type PublicHTTPConfig struct {
SecurityGroupConfig ALBSecurityGroupsConfig `yaml:"security_groups,omitempty"`
Certificates []string `yaml:"certificates,omitempty"`
ELBAccessLogs ELBAccessLogsArgsOrBool `yaml:"access_logs,omitempty"`
SecurityPolicy *string `yaml:"security_policy,omitempty"`
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
}

// ELBAccessLogsArgsOrBool is a custom type which supports unmarshaling yaml which
Expand Down Expand Up @@ -534,18 +535,19 @@ func (i Ingress) IsEmpty() bool {

// IsEmpty returns true if there is no customization to the public ALB.
func (cfg PublicHTTPConfig) IsEmpty() bool {
return len(cfg.Certificates) == 0 && cfg.SecurityGroupConfig.IsEmpty() && cfg.ELBAccessLogs.isEmpty()
return len(cfg.Certificates) == 0 && cfg.SecurityGroupConfig.IsEmpty() && cfg.ELBAccessLogs.isEmpty() && cfg.SecurityPolicy == nil
}

type privateHTTPConfig struct {
InternalALBSubnets []string `yaml:"subnets,omitempty"`
Certificates []string `yaml:"certificates,omitempty"`
SecurityGroupsConfig securityGroupsConfig `yaml:"security_groups,omitempty"`
SecurityPolicy *string `yaml:"security_policy,omitempty"`
}

// IsEmpty returns true if there is no customization to the internal ALB.
func (cfg privateHTTPConfig) IsEmpty() bool {
return len(cfg.InternalALBSubnets) == 0 && len(cfg.Certificates) == 0 && cfg.SecurityGroupsConfig.isEmpty()
return len(cfg.InternalALBSubnets) == 0 && len(cfg.Certificates) == 0 && cfg.SecurityGroupsConfig.isEmpty() && cfg.SecurityPolicy == nil
}

type securityGroupsConfig struct {
Expand Down
14 changes: 12 additions & 2 deletions internal/pkg/manifest/env_test.go
Expand Up @@ -797,11 +797,16 @@ func TestPublicHTTPConfig_IsEmpty(t *testing.T) {
"empty": {
wanted: true,
},
"not empty": {
"not empty when Certificates are attached ": {
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
in: PublicHTTPConfig{
Certificates: []string{"mock-cert-1"},
},
},
"not empty when Security Policy is present": {
in: PublicHTTPConfig{
SecurityPolicy: aws.String("mock-ELB-ELBSecurityPolicy"),
},
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
Expand All @@ -819,11 +824,16 @@ func TestPrivateHTTPConfig_IsEmpty(t *testing.T) {
"empty": {
wanted: true,
},
"not empty": {
"not empty when Certificates are attached": {
in: privateHTTPConfig{
InternalALBSubnets: []string{"mock-subnet-1"},
},
},
"not empty when Security Policy is present": {
in: privateHTTPConfig{
SecurityPolicy: aws.String("mock-ELB-ELBSecurityPolicy"),
},
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/template/env.go
Expand Up @@ -135,6 +135,7 @@ type HTTPConfig struct {
ImportedCertARNs []string
CustomALBSubnets []string
ELBAccessLogs *ELBAccessLogs
SecurityPolicy *string
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
}

// ELBAccessLogs represents configuration for ELB access logs S3 bucket.
Expand Down
2 changes: 2 additions & 0 deletions internal/pkg/template/templates/environment/cf.yml
Expand Up @@ -356,6 +356,7 @@ Resources:
LoadBalancerArn: !Ref PublicLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: {{ if .PublicHTTPConfig.SecurityPolicy }}{{ .PublicHTTPConfig.SecurityPolicy }}{{ else }} ELBSecurityPolicy-2016-08 {{ end }}
{{- range $ind, $arn := .PublicHTTPConfig.ImportedCertARNs}}
{{- if gt $ind 0}}
HTTPSImportCertificate{{inc $ind}}:
Expand Down Expand Up @@ -432,6 +433,7 @@ Resources:
LoadBalancerArn: !Ref InternalLoadBalancer
Port: 443
Protocol: HTTPS
SslPolicy: {{ if .PrivateHTTPConfig.SecurityPolicy }}{{ .PrivateHTTPConfig.SecurityPolicy }}{{ else }} ELBSecurityPolicy-2016-08 {{ end }}
KollaAdithya marked this conversation as resolved.
Show resolved Hide resolved
{{- range $ind, $arn := .PrivateHTTPConfig.ImportedCertARNs}}
{{- if gt $ind 0}}
InternalHTTPSImportCertificate{{inc $ind}}:
Expand Down