Allow the AWS LB Controller to use WAFs

By introducing a few new fields within the Cluster spec's
"awsLoadBalancerController" field, allow users to enable the AWS Load
Balancer Controller to associate WAFs with EC2 Application Load
Balancers (ALBs). It's possible to enable separately use of two kinds
of WAF: WAF Classic and the never version 2-era WAF, the latter of
which bears no distinguishing name.

Retain our default configuration of the AWS Load Balancer Controller
in which this capability remains disabled via command-line flags,
overriding the controller program's enabling of this capability by
default.

Signed-off-by: Steven E. Harris <seh@panix.com>
This commit is contained in:
Steven E. Harris 2022-05-10 13:15:24 -04:00
parent 9f092e944c
commit a1495ac4c8
No known key found for this signature in database
GPG Key ID: BB5463D8C93E1666
17 changed files with 111 additions and 12 deletions

View File

@ -22,6 +22,33 @@ spec:
enabled: true
```
Though the AWS Load Balancer Controller can integrate the AWS WAF and
Shield services with your Application Load Balancers (ALBs), kOps
disables those capabilities by default.
{{ kops_feature_table(kops_added_default='1.24') }}
You can enable use of either or both of the WAF and WAF Classic
services by including the following fields in the cluster spec:
```yaml
spec:
awsLoadBalancerController:
enabled: true
enableWAF: true
enableWAFv2: true
```
Note that the controller will only succeed in associating one WAF with
a given ALB at a time, despite it accepting both the
"alb.ingress.kubernetes.io/waf-acl-id" and
"alb.ingress.kubernetes.io/wafv2-acl-arn" annotations on the same
_Ingress_ object.
Support for this WAF service in kOps is currently **beta**, meaning
that the accepted configuration and the AWS resources involved may
change.
Read more in the [official documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/).
#### Cluster autoscaler

View File

@ -262,6 +262,14 @@ spec:
description: AWSLoadbalancerControllerConfig determines the AWS LB
controller configuration.
properties:
enableWAF:
description: 'EnableWAF specifies whether the controller can use
WAFs (Classic Regional). Default: false'
type: boolean
enableWAFv2:
description: 'EnableWAFv2 specifies whether the controller can
use WAFs (V2). Default: false'
type: boolean
enabled:
description: 'Enabled enables the loadbalancer controller. Default:
false'

View File

@ -1059,6 +1059,12 @@ type AWSLoadBalancerControllerConfig struct {
Enabled *bool `json:"enabled,omitempty"`
// Version is the container image tag used.
Version *string `json:"version,omitempty"`
// EnableWAF specifies whether the controller can use WAFs (Classic Regional).
// Default: false
EnableWAF bool `json:"enableWAF,omitempty"`
// EnableWAFv2 specifies whether the controller can use WAFs (V2).
// Default: false
EnableWAFv2 bool `json:"enableWAFv2,omitempty"`
}
// HasAdmissionController checks if a specific admission controller is enabled

View File

@ -1085,6 +1085,12 @@ type AWSLoadBalancerControllerConfig struct {
Enabled *bool `json:"enabled,omitempty"`
// Version is the container image tag used.
Version *string `json:"version,omitempty"`
// EnableWAF specifies whether the controller can use WAFs (Classic Regional).
// Default: false
EnableWAF bool `json:"enableWAF,omitempty"`
// EnableWAFv2 specifies whether the controller can use WAFs (V2).
// Default: false
EnableWAFv2 bool `json:"enableWAFv2,omitempty"`
}
// HasAdmissionController checks if a specific admission controller is enabled

View File

@ -1324,6 +1324,8 @@ func Convert_kops_AWSEBSCSIDriver_To_v1alpha2_AWSEBSCSIDriver(in *kops.AWSEBSCSI
func autoConvert_v1alpha2_AWSLoadBalancerControllerConfig_To_kops_AWSLoadBalancerControllerConfig(in *AWSLoadBalancerControllerConfig, out *kops.AWSLoadBalancerControllerConfig, s conversion.Scope) error {
out.Enabled = in.Enabled
out.Version = in.Version
out.EnableWAF = in.EnableWAF
out.EnableWAFv2 = in.EnableWAFv2
return nil
}
@ -1335,6 +1337,8 @@ func Convert_v1alpha2_AWSLoadBalancerControllerConfig_To_kops_AWSLoadBalancerCon
func autoConvert_kops_AWSLoadBalancerControllerConfig_To_v1alpha2_AWSLoadBalancerControllerConfig(in *kops.AWSLoadBalancerControllerConfig, out *AWSLoadBalancerControllerConfig, s conversion.Scope) error {
out.Enabled = in.Enabled
out.Version = in.Version
out.EnableWAF = in.EnableWAF
out.EnableWAFv2 = in.EnableWAFv2
return nil
}

View File

@ -1056,4 +1056,10 @@ type AWSLoadBalancerControllerConfig struct {
Enabled *bool `json:"enabled,omitempty"`
// Version is the container image tag used.
Version *string `json:"version,omitempty"`
// EnableWAF specifies whether the controller can use WAFs (Classic Regional).
// Default: false
EnableWAF bool `json:"enableWAF,omitempty"`
// EnableWAFv2 specifies whether the controller can use WAFs (V2).
// Default: false
EnableWAFv2 bool `json:"enableWAFv2,omitempty"`
}

View File

@ -1324,6 +1324,8 @@ func Convert_kops_AWSEBSCSIDriver_To_v1alpha3_AWSEBSCSIDriver(in *kops.AWSEBSCSI
func autoConvert_v1alpha3_AWSLoadBalancerControllerConfig_To_kops_AWSLoadBalancerControllerConfig(in *AWSLoadBalancerControllerConfig, out *kops.AWSLoadBalancerControllerConfig, s conversion.Scope) error {
out.Enabled = in.Enabled
out.Version = in.Version
out.EnableWAF = in.EnableWAF
out.EnableWAFv2 = in.EnableWAFv2
return nil
}
@ -1335,6 +1337,8 @@ func Convert_v1alpha3_AWSLoadBalancerControllerConfig_To_kops_AWSLoadBalancerCon
func autoConvert_kops_AWSLoadBalancerControllerConfig_To_v1alpha3_AWSLoadBalancerControllerConfig(in *kops.AWSLoadBalancerControllerConfig, out *AWSLoadBalancerControllerConfig, s conversion.Scope) error {
out.Enabled = in.Enabled
out.Version = in.Version
out.EnableWAF = in.EnableWAF
out.EnableWAFv2 = in.EnableWAFv2
return nil
}

View File

@ -21,7 +21,7 @@ import (
"k8s.io/kops/pkg/model/iam"
)
// ServiceAccount represents the service-account used by the dns-controller.
// ServiceAccount represents the service-account used by the AWS Load Balancer Controller.
// It implements iam.Subject to get AWS IAM permissions.
type ServiceAccount struct{}
@ -32,7 +32,13 @@ func (r *ServiceAccount) BuildAWSPolicy(b *iam.PolicyBuilder) (*iam.Policy, erro
clusterName := b.Cluster.ObjectMeta.Name
p := iam.NewPolicy(clusterName, b.Partition)
iam.AddAWSLoadbalancerControllerPermissions(p)
var enableWAF bool
var enableWAFv2 bool
if c := b.Cluster.Spec.AWSLoadBalancerController; c != nil {
enableWAF = c.EnableWAF
enableWAFv2 = c.EnableWAFv2
}
iam.AddAWSLoadbalancerControllerPermissions(p, enableWAF, enableWAFv2)
return p, nil
}

View File

@ -424,8 +424,8 @@ func (r *NodeRoleMaster) BuildAWSPolicy(b *PolicyBuilder) (*Policy, error) {
}
}
if b.Cluster.Spec.AWSLoadBalancerController != nil && fi.BoolValue(b.Cluster.Spec.AWSLoadBalancerController.Enabled) {
AddAWSLoadbalancerControllerPermissions(p)
if c := b.Cluster.Spec.AWSLoadBalancerController; c != nil && fi.BoolValue(b.Cluster.Spec.AWSLoadBalancerController.Enabled) {
AddAWSLoadbalancerControllerPermissions(p, c.EnableWAF, c.EnableWAFv2)
}
var useStaticInstanceList bool
@ -955,8 +955,8 @@ func AddCCMPermissions(p *Policy, cloudRoutes bool) {
}
}
// AddAWSLoadbalancerControllerPermissions adds the permissions needed for the aws load balancer controller to the givnen policy
func AddAWSLoadbalancerControllerPermissions(p *Policy) {
// AddAWSLoadbalancerControllerPermissions adds the permissions needed for the AWS Load Balancer Controller to the givnen policy
func AddAWSLoadbalancerControllerPermissions(p *Policy, enableWAF bool, enableWAFv2 bool) {
p.unconditionalAction.Insert(
"acm:DescribeCertificate",
"acm:ListCertificates",
@ -980,23 +980,43 @@ func AddAWSLoadbalancerControllerPermissions(p *Policy) {
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
)
if enableWAF {
p.unconditionalAction.Insert(
"elasticloadbalancing:SetWebACL",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL",
"waf-regional:GetWebACL",
"waf-regional:GetWebACLForResource",
)
}
if enableWAFv2 {
p.unconditionalAction.Insert(
"elasticloadbalancing:SetWebACL",
"wafv2:AssociateWebACL",
"wafv2:DisassociateWebACL",
"wafv2:GetWebACL",
"wafv2:GetWebACLForResource",
)
}
p.clusterTaggedAction.Insert(
"ec2:AuthorizeSecurityGroupIngress", // aws.go
"ec2:DeleteSecurityGroup", // aws.go
"ec2:RevokeSecurityGroupIngress", // aws.go
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeleteRule",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:ModifyRule",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",

View File

@ -63,6 +63,7 @@
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSecurityGroup",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
@ -75,6 +76,7 @@
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",

View File

@ -63,6 +63,7 @@
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSecurityGroup",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
@ -75,6 +76,7 @@
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",

View File

@ -63,6 +63,7 @@
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSecurityGroup",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
@ -75,6 +76,7 @@
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",

View File

@ -63,6 +63,7 @@
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSecurityGroup",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
@ -75,6 +76,7 @@
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",

View File

@ -282,6 +282,7 @@
"ec2:ModifyInstanceAttribute",
"ec2:ModifyVolume",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:AttachLoadBalancerToSubnets",
@ -303,6 +304,7 @@
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",

View File

@ -282,6 +282,7 @@
"ec2:ModifyInstanceAttribute",
"ec2:ModifyVolume",
"ec2:RevokeSecurityGroupIngress",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:AttachLoadBalancerToSubnets",
@ -303,6 +304,7 @@
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",

View File

@ -749,8 +749,8 @@ spec:
containers:
- args:
- --cluster-name={{ ClusterName }}
- --enable-waf=false
- --enable-wafv2=false
- --enable-waf={{ .AWSLoadBalancerController.EnableWAF }}
- --enable-wafv2={{ .AWSLoadBalancerController.EnableWAFv2 }}
- --enable-shield=false
- --ingress-class=alb
- "--default-tags={{ CloudLabels }}"

View File

@ -749,8 +749,8 @@ spec:
containers:
- args:
- --cluster-name={{ ClusterName }}
- --enable-waf=false
- --enable-wafv2=false
- --enable-waf={{ .AWSLoadBalancerController.EnableWAF }}
- --enable-wafv2={{ .AWSLoadBalancerController.EnableWAFv2 }}
- --enable-shield=false
- --ingress-class=alb
- "--default-tags={{ CloudLabels }}"