From 67370a589d4000a489b42436eb3f7a751c5b70b9 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Fri, 7 Jan 2022 21:54:20 -0800 Subject: [PATCH 1/2] Add support for App Protect DoS --- api/v1alpha1/nginxingresscontroller_types.go | 22 +++++++++++++- api/v1alpha1/zz_generated.deepcopy.go | 20 +++++++++++++ ...k8s.nginx.org_nginxingresscontrollers.yaml | 29 ++++++++++++++++++- config/rbac/role.yaml | 1 + .../nginxingresscontroller_controller.go | 2 +- controllers/rbac.go | 5 ++++ controllers/rbac_test.go | 5 ++++ controllers/utils.go | 15 ++++++++++ controllers/utils_test.go | 12 ++++++++ docs/nginx-ingress-controller.md | 22 ++++++++++---- 10 files changed, 124 insertions(+), 9 deletions(-) diff --git a/api/v1alpha1/nginxingresscontroller_types.go b/api/v1alpha1/nginxingresscontroller_types.go index 7ef8eb08..f080ea05 100644 --- a/api/v1alpha1/nginxingresscontroller_types.go +++ b/api/v1alpha1/nginxingresscontroller_types.go @@ -154,6 +154,12 @@ type NginxIngressControllerSpec struct { // +nullable // +operator-sdk:csv:customresourcedefinitions:type=spec AppProtect *AppProtect `json:"appProtect"` + // App Protect Dos support configuration. + // Requires enableCRDs set to true. + // +kubebuilder:validation:Optional + // +nullable + // +operator-sdk:csv:customresourcedefinitions:type=spec + AppProtectDos *AppProtectDos `json:"appProtectDos"` // Timeout in milliseconds which the Ingress Controller will wait for a successful NGINX reload after a change or at the initial start. // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -268,8 +274,22 @@ type Prometheus struct { // AppProtect support configuration. type AppProtect struct { - // Enable App Protect. + // Enable App Protect WAF. + Enable bool `json:"enable"` +} + +// AppProtectDos support configuration. +type AppProtectDos struct { + // Enable App Protect Dos. Enable bool `json:"enable"` + // Enable debug mode. + Debug bool `json:"debug"` + // Max number of ADMD instances. + MaxDaemons int `json:"maxDaemons"` + // Max number of nginx processes to support. + MaxWorkers int `json:"maxWorkers"` + // RAM memory size in MB. + Memory int `json:"memory"` } // Service defines the Service for the Ingress Controller. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 58328ca6..b8d03225 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -40,6 +40,21 @@ func (in *AppProtect) DeepCopy() *AppProtect { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppProtectDos) DeepCopyInto(out *AppProtectDos) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppProtectDos. +func (in *AppProtectDos) DeepCopy() *AppProtectDos { + if in == nil { + return nil + } + out := new(AppProtectDos) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HealthStatus) DeepCopyInto(out *HealthStatus) { *out = *in @@ -185,6 +200,11 @@ func (in *NginxIngressControllerSpec) DeepCopyInto(out *NginxIngressControllerSp *out = new(AppProtect) **out = **in } + if in.AppProtectDos != nil { + in, out := &in.AppProtectDos, &out.AppProtectDos + *out = new(AppProtectDos) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NginxIngressControllerSpec. diff --git a/config/crd/bases/k8s.nginx.org_nginxingresscontrollers.yaml b/config/crd/bases/k8s.nginx.org_nginxingresscontrollers.yaml index 4f6b6c29..2321071d 100644 --- a/config/crd/bases/k8s.nginx.org_nginxingresscontrollers.yaml +++ b/config/crd/bases/k8s.nginx.org_nginxingresscontrollers.yaml @@ -43,11 +43,38 @@ spec: nullable: true properties: enable: - description: Enable App Protect. + description: Enable App Protect WAF. type: boolean required: - enable type: object + appProtectDos: + description: App Protect Dos support configuration. Requires enableCRDs + set to true. + nullable: true + properties: + debug: + description: Enable debug mode. + type: boolean + enable: + description: Enable App Protect Dos. + type: boolean + maxDaemons: + description: Max number of ADMD instances. + type: integer + maxWorkers: + description: Max number of nginx processes to support. + type: integer + memory: + description: RAM memory size in MB. + type: integer + required: + - debug + - enable + - maxDaemons + - maxWorkers + - memory + type: object configMapData: additionalProperties: type: string diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 0fea5ec1..c7047920 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -38,6 +38,7 @@ rules: - update - apiGroups: - appprotect.f5.com + - appprotectdos.f5.com - k8s.nginx.org resources: - '*' diff --git a/controllers/nginxingresscontroller_controller.go b/controllers/nginxingresscontroller_controller.go index fd0f9b34..fe85f9a9 100644 --- a/controllers/nginxingresscontroller_controller.go +++ b/controllers/nginxingresscontroller_controller.go @@ -55,7 +55,7 @@ type NginxIngressControllerReconciler struct { //+kubebuilder:rbac:groups=k8s.nginx.org,resources=nginxingresscontrollers,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=k8s.nginx.org,resources=nginxingresscontrollers/status,verbs=get;update;patch //+kubebuilder:rbac:groups=k8s.nginx.org,resources=nginxingresscontrollers/finalizers,verbs=update -//+kubebuilder:rbac:groups=k8s.nginx.org;appprotect.f5.com,resources=*,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=k8s.nginx.org;appprotect.f5.com;appprotectdos.f5.com,resources=*,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=apps,resources=deployments;daemonsets;replicasets;statefulsets,verbs=get;list;watch;create;update;patch;delete diff --git a/controllers/rbac.go b/controllers/rbac.go index 629cc033..ac492840 100644 --- a/controllers/rbac.go +++ b/controllers/rbac.go @@ -62,6 +62,11 @@ func clusterRoleForNginxIngressController(name string) *rbacv1.ClusterRole { APIGroups: []string{"appprotect.f5.com"}, Resources: []string{"aplogconfs", "appolicies", "apusersigs"}, }, + { + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"appprotectdos.f5.com"}, + Resources: []string{"apdoslogconfs", "apdospolicies", "dosprotectedresources"}, + }, } rbac := &rbacv1.ClusterRole{ ObjectMeta: v1.ObjectMeta{ diff --git a/controllers/rbac_test.go b/controllers/rbac_test.go index 2055448f..b1fca567 100644 --- a/controllers/rbac_test.go +++ b/controllers/rbac_test.go @@ -70,6 +70,11 @@ func TestClusterRoleForNginxIngressController(t *testing.T) { APIGroups: []string{"appprotect.f5.com"}, Resources: []string{"aplogconfs", "appolicies", "apusersigs"}, }, + { + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"appprotectdos.f5.com"}, + Resources: []string{"apdoslogconfs", "apdospolicies", "dosprotectedresources"}, + }, }, } diff --git a/controllers/utils.go b/controllers/utils.go index 1e17e89c..72e5a294 100644 --- a/controllers/utils.go +++ b/controllers/utils.go @@ -38,6 +38,21 @@ func generatePodArgs(instance *k8sv1alpha1.NginxIngressController) []string { if instance.Spec.AppProtect != nil && instance.Spec.AppProtect.Enable { args = append(args, "-enable-app-protect") } + if instance.Spec.AppProtectDos != nil && instance.Spec.AppProtectDos.Enable { + args = append(args, "-enable-app-protect-dos") + if instance.Spec.AppProtectDos.Debug { + args = append(args, "-app-protect-dos-debug") + } + if instance.Spec.AppProtectDos.MaxDaemons != 0 { + args = append(args, fmt.Sprintf("-app-protect-dos-max-daemons=%v", instance.Spec.AppProtectDos.MaxDaemons)) + } + if instance.Spec.AppProtectDos.MaxWorkers != 0 { + args = append(args, fmt.Sprintf("-app-protect-dos-max-workers=%v", instance.Spec.AppProtectDos.MaxWorkers)) + } + if instance.Spec.AppProtectDos.Memory != 0 { + args = append(args, fmt.Sprintf("-app-protect-dos-memory=%v", instance.Spec.AppProtectDos.Memory)) + } + } } if instance.Spec.IngressClass != "" { diff --git a/controllers/utils_test.go b/controllers/utils_test.go index 7670d7a7..ea6ac769 100644 --- a/controllers/utils_test.go +++ b/controllers/utils_test.go @@ -232,6 +232,13 @@ func TestGeneratePodArgs(t *testing.T) { AppProtect: &k8sv1alpha1.AppProtect{ Enable: true, }, + AppProtectDos: &k8sv1alpha1.AppProtectDos{ + Enable: true, + Debug: true, + MaxDaemons: 12, + MaxWorkers: 3, + Memory: 512, + }, NginxReloadTimeout: 5000, EnableCRDs: &disable, EnableSnippets: true, @@ -243,6 +250,11 @@ func TestGeneratePodArgs(t *testing.T) { "-default-server-tls-secret=my-nginx-ingress/my-secret", "-nginx-plus", "-enable-app-protect", + "-enable-app-protect-dos", + "-app-protect-dos-debug", + "-app-protect-dos-max-daemons=12", + "-app-protect-dos-max-workers=3", + "-app-protect-dos-memory=512", "-ingress-class=ingressClass", "-watch-namespace=default", "-health-status", diff --git a/docs/nginx-ingress-controller.md b/docs/nginx-ingress-controller.md index aa187f98..887260f7 100644 --- a/docs/nginx-ingress-controller.md +++ b/docs/nginx-ingress-controller.md @@ -1,7 +1,7 @@ # NginxIngressController Custom Resource -The `NginxIngressController` Custom Resource is the definition of a deployment of the Ingress Controller. -With this Custom Resource, the NGINX Ingress Operator will be able to deploy and configure instances of the Ingress Controller in your cluster. +The `NginxIngressController` Custom Resource is the definition of a deployment of the Ingress Controller. +With this Custom Resource, the NGINX Ingress Operator will be able to deploy and configure instances of the Ingress Controller in your cluster. ## Configuration @@ -25,7 +25,7 @@ spec: ``` The following example shows the usage of all fields (required and optional): - + ```yaml apiVersion: k8s.nginx.org/v1alpha1 kind: NginxIngressController @@ -73,8 +73,8 @@ spec: nginxReloadTimeout: 5000 appProtect: enable: false - ``` - + ``` + | Field | Type | Description | Required | | --- | --- | --- | --- | | `type` | `string` | The type of the Ingress Controller installation - `deployment` or `daemonset`. | Yes | @@ -153,4 +153,14 @@ spec: | Field | Type | Description | Required | | --- | --- | --- | --- | -| `enable` | `boolean` | Enable App Protect. | Yes | +| `enable` | `boolean` | Enable App Protect WAF. | Yes | + +## NginxIngressController.AppProtectDos + +| Field | Type | Description | Required | +| --- | --- | --- | --- | +| `enable` | `boolean` | Enable App Protect DoS. | Yes | +| `debug` | `boolean` | Enable debug mode. | No | +| `maxDaemons` | `int` | Maximum number of ADMD instances. | No | +| `maxWorkers` | `int` | Max number of nginx processes to support. | No | +| `memory` | `int` | RAM memory size to consume in MB. | No | From 23cf6581d341d42dfd75b82e30d9a4aa7c5a0dd2 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Mon, 10 Jan 2022 10:21:59 -0800 Subject: [PATCH 2/2] add dos link --- docs/nginx-ingress-controller.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/nginx-ingress-controller.md b/docs/nginx-ingress-controller.md index 887260f7..c378b050 100644 --- a/docs/nginx-ingress-controller.md +++ b/docs/nginx-ingress-controller.md @@ -100,7 +100,8 @@ spec: | `configMapData` | `map[string]string` | Initial values of the Ingress Controller ConfigMap. Check the [ConfigMap docs](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/) for more information about possible values. | No | | `globalConfiguration` | `string` | The GlobalConfiguration resource for global configuration of the Ingress Controller. Format is namespace/name. Requires `enableCRDs` set to `true`. | No | | `enableTLSPassthrough` | `boolean` | Enable TLS Passthrough on port 443. Requires `enableCRDs` set to `true`. | No | -| `appprotect` | [appprotect](#nginxingresscontrollerappprotect) | App Protect support configuration. Requires `nginxPlus` set to `true`. | No | +| `appProtect` | [appProtect](#nginxingresscontrollerappprotect) | App Protect WAF support configuration. Requires `nginxPlus` set to `true`. | No | +| `appProtectDos` | [appProtectDos](#nginxingresscontrollerappprotectdos) | App Protect DoS support configuration. Requires `nginxPlus` set to `true`. | No | | `nginxReloadTimeout` | `int`| Timeout in milliseconds which the Ingress Controller will wait for a successful NGINX reload after a change or at the initial start. (default is 4000. Default is 20000 instead if `enable-app-protect` is true) | No | ## NginxIngressController.Image