mirror of
https://github.com/openappsec/openappsec.git
synced 2025-11-16 09:21:54 +03:00
Compare commits
27 Commits
Sep_24_202
...
Nov_12_202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3061342b45 | ||
|
|
0869b8f24d | ||
|
|
1a4ab5f0d7 | ||
|
|
4a2d25ab65 | ||
|
|
f2ca7301b9 | ||
|
|
3d11ead170 | ||
|
|
39b8c5a5ff | ||
|
|
de6f1033bd | ||
|
|
58958b2436 | ||
|
|
59e7f00b3e | ||
|
|
e102b25b7d | ||
|
|
0386431eee | ||
|
|
fd1a77628e | ||
|
|
da911582a5 | ||
|
|
798dd2a7d1 | ||
|
|
6bda60ae84 | ||
|
|
5b9769e94e | ||
|
|
6693176131 | ||
|
|
c2ced075eb | ||
|
|
0b4bdd3677 | ||
|
|
d6599cc7bc | ||
|
|
4db7a54c27 | ||
|
|
f3ede0c60e | ||
|
|
79bac9f501 | ||
|
|
89263f6f34 | ||
|
|
5feb12f7e4 | ||
|
|
a2ee6ca839 |
@@ -3,6 +3,11 @@ project (ngen)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -Wno-terminate -Dalpine")
|
||||
|
||||
execute_process(COMMAND grep -c "Alpine Linux" /etc/os-release OUTPUT_VARIABLE IS_ALPINE)
|
||||
if(IS_ALPINE EQUAL "1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dalpine")
|
||||
endif()
|
||||
|
||||
find_package(Boost REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(GTest REQUIRED)
|
||||
|
||||
@@ -63,11 +63,11 @@ $ ./open-appsec-k8s-install
|
||||
|
||||
For Kubernetes (NGINX or Kong) using Helm: follow [documentation](https://docs.openappsec.io/getting-started/start-with-kubernetes/install-using-helm-ingress-nginx-and-kong) – use this method if you’ve built your own containers.
|
||||
|
||||
For Linux (NGINX or Kong) using the installer (list of supported/pre-compiled NGINX attachments is available [here](https://downloads.openappsec.io/supported-nginx.txt)):
|
||||
For Linux (NGINX or Kong) using the installer (list of supported/pre-compiled NGINX attachments is available [here](https://downloads.openappsec.io/packages/supported-nginx.txt)):
|
||||
|
||||
```bash
|
||||
$ wget https://downloads.openappsec.io/open-appsec-install && chmod +x open-appsec-install
|
||||
$ ./open-appsec-install –auto
|
||||
$ ./open-appsec-install --auto
|
||||
```
|
||||
|
||||
For Linux, if you’ve built your own package use the following commands:
|
||||
@@ -104,13 +104,14 @@ Before compiling the services, you'll need to ensure the latest development vers
|
||||
* GTest
|
||||
* GMock
|
||||
* cURL
|
||||
* Redis
|
||||
* Hiredis
|
||||
|
||||
An example of installing the packages on Alpine:
|
||||
|
||||
```bash
|
||||
$ apk update
|
||||
$ apk add boost-dev openssl-dev pcre2-dev libxml2-dev gtest-dev curl-dev hiredis-dev
|
||||
$ apk add boost-dev openssl-dev pcre2-dev libxml2-dev gtest-dev curl-dev hiredis-dev redis
|
||||
```
|
||||
|
||||
## Compiling and packaging the agent code
|
||||
|
||||
@@ -32,5 +32,6 @@ DEFINE_KDEBUG_FLAG(statelessValidation)
|
||||
DEFINE_KDEBUG_FLAG(kernelMetric)
|
||||
DEFINE_KDEBUG_FLAG(tproxy)
|
||||
DEFINE_KDEBUG_FLAG(tenantStats)
|
||||
DEFINE_KDEBUG_FLAG(uuidTranslation)
|
||||
|
||||
#endif // DEFINE_KDEBUG_FLAG
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
annotations:
|
||||
artifacthub.io/changes: |
|
||||
- "Added a doc line to the missing helm value service.internal.loadBalancerIP (#9406)"
|
||||
- "feat(helm): Add loadBalancerClass (#9562)"
|
||||
- "added helmshowvalues example (#10019)"
|
||||
- "Update Ingress-Nginx version controller-v1.8.1"
|
||||
- "Update Ingress-Nginx version controller-v1.9.1"
|
||||
artifacthub.io/prerelease: "false"
|
||||
apiVersion: v2
|
||||
appVersion: 1.8.1
|
||||
appVersion: latest
|
||||
keywords:
|
||||
- ingress
|
||||
- nginx
|
||||
@@ -14,4 +11,4 @@ kubeVersion: '>=1.20.0-0'
|
||||
name: open-appsec-k8s-nginx-ingress
|
||||
sources:
|
||||
- https://github.com/kubernetes/ingress-nginx
|
||||
version: 4.7.1
|
||||
version: 4.8.1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer
|
||||
|
||||
 
|
||||
 
|
||||
|
||||
To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources.
|
||||
|
||||
@@ -249,7 +249,6 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.admissionWebhooks.key | string | `"/usr/local/certificates/key"` | |
|
||||
| controller.admissionWebhooks.labels | object | `{}` | Labels to be added to admission webhooks |
|
||||
| controller.admissionWebhooks.namespaceSelector | object | `{}` | |
|
||||
| controller.admissionWebhooks.networkPolicyEnabled | bool | `false` | |
|
||||
| controller.admissionWebhooks.objectSelector | object | `{}` | |
|
||||
| controller.admissionWebhooks.patch.enabled | bool | `true` | |
|
||||
| controller.admissionWebhooks.patch.image.digest | string | `"sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b"` | |
|
||||
@@ -274,7 +273,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.admissionWebhooks.service.servicePort | int | `443` | |
|
||||
| controller.admissionWebhooks.service.type | string | `"ClusterIP"` | |
|
||||
| controller.affinity | object | `{}` | Affinity and anti-affinity rules for server scheduling to nodes # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity # |
|
||||
| controller.allowSnippetAnnotations | bool | `true` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected |
|
||||
| controller.allowSnippetAnnotations | bool | `false` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected |
|
||||
| controller.annotations | object | `{}` | Annotations to be added to the controller Deployment or DaemonSet # |
|
||||
| controller.autoscaling.annotations | object | `{}` | |
|
||||
| controller.autoscaling.behavior | object | `{}` | |
|
||||
@@ -294,8 +293,9 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.dnsConfig | object | `{}` | Optionally customize the pod dnsConfig. |
|
||||
| controller.dnsPolicy | string | `"ClusterFirst"` | Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. |
|
||||
| controller.electionID | string | `""` | Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' |
|
||||
| controller.enableAnnotationValidations | bool | `false` | |
|
||||
| controller.enableMimalloc | bool | `true` | Enable mimalloc as a drop-in replacement for malloc. # ref: https://github.com/microsoft/mimalloc # |
|
||||
| controller.enableTopologyAwareRouting | bool | `false` | This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-aware-hints="auto" Defaults to false |
|
||||
| controller.enableTopologyAwareRouting | bool | `false` | This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-mode="auto" Defaults to false |
|
||||
| controller.existingPsp | string | `""` | Use an existing PSP instead of creating one |
|
||||
| controller.extraArgs | object | `{}` | Additional command line arguments to pass to Ingress-Nginx Controller E.g. to specify the default SSL certificate you can use |
|
||||
| controller.extraContainers | list | `[]` | Additional containers to be added to the controller pod. See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. |
|
||||
@@ -306,6 +306,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.extraVolumes | list | `[]` | Additional volumes to the controller pod. |
|
||||
| controller.healthCheckHost | string | `""` | Address to bind the health check endpoint. It is better to set this option to the internal node address if the Ingress-Nginx Controller is running in the `hostNetwork: true` mode. |
|
||||
| controller.healthCheckPath | string | `"/healthz"` | Path of the health check endpoint. All requests received on the port defined by the healthz-port parameter are forwarded internally to this path. |
|
||||
| controller.hostAliases | list | `[]` | Optionally customize the pod hostAliases. |
|
||||
| controller.hostNetwork | bool | `false` | Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 is merged |
|
||||
| controller.hostPort.enabled | bool | `false` | Enable 'hostPort' or not |
|
||||
| controller.hostPort.ports.http | int | `80` | 'hostPort' http port |
|
||||
@@ -313,13 +314,13 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.hostname | object | `{}` | Optionally customize the pod hostname. |
|
||||
| controller.image.allowPrivilegeEscalation | bool | `true` | |
|
||||
| controller.image.chroot | bool | `false` | |
|
||||
| controller.image.digest | string | `"sha256:e5c4824e7375fcf2a393e1c03c293b69759af37a9ca6abdb91b13d78a93da8bd"` | |
|
||||
| controller.image.digestChroot | string | `"sha256:e0d4121e3c5e39de9122e55e331a32d5ebf8d4d257227cb93ab54a1b912a7627"` | |
|
||||
| controller.image.digest | string | `"sha256:605a737877de78969493a4b1213b21de4ee425d2926906857b98050f57a95b25"` | |
|
||||
| controller.image.digestChroot | string | `"sha256:2ac744ef08850ee86ad7162451a6879f47c1a41c6a757f6b6f913c52103b8836"` | |
|
||||
| controller.image.image | string | `"ingress-nginx/controller"` | |
|
||||
| controller.image.pullPolicy | string | `"IfNotPresent"` | |
|
||||
| controller.image.registry | string | `"registry.k8s.io"` | |
|
||||
| controller.image.runAsUser | int | `101` | |
|
||||
| controller.image.tag | string | `"v1.8.1"` | |
|
||||
| controller.image.tag | string | `"v1.9.1"` | |
|
||||
| controller.ingressClass | string | `"nginx"` | For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation |
|
||||
| controller.ingressClassByName | bool | `false` | Process IngressClass per name (additionally as per spec.controller). |
|
||||
| controller.ingressClassResource.controllerValue | string | `"k8s.io/ingress-nginx"` | Controller-value of the controller that is processing this ingressClass |
|
||||
@@ -372,10 +373,12 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.minAvailable | int | `1` | Minimum available pods set in PodDisruptionBudget. Define either 'minAvailable' or 'maxUnavailable', never both. |
|
||||
| controller.minReadySeconds | int | `0` | `minReadySeconds` to avoid killing pods before we are ready # |
|
||||
| controller.name | string | `"controller"` | |
|
||||
| controller.networkPolicy.enabled | bool | `false` | Enable 'networkPolicy' or not |
|
||||
| controller.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for controller pod assignment # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ # |
|
||||
| controller.opentelemetry.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | |
|
||||
| controller.opentelemetry.enabled | bool | `false` | |
|
||||
| controller.opentelemetry.image | string | `"registry.k8s.io/ingress-nginx/opentelemetry:v20230527@sha256:fd7ec835f31b7b37187238eb4fdad4438806e69f413a203796263131f4f02ed0"` | |
|
||||
| controller.opentelemetry.image | string | `"registry.k8s.io/ingress-nginx/opentelemetry:v20230721-3e2062ee5@sha256:13bee3f5223883d3ca62fee7309ad02d22ec00ff0d7033e3e9aca7a9f60fd472"` | |
|
||||
| controller.opentelemetry.resources | object | `{}` | |
|
||||
| controller.podAnnotations | object | `{}` | Annotations to be added to controller pods # |
|
||||
| controller.podLabels | object | `{}` | Labels to add to the pod container metadata |
|
||||
| controller.podSecurityContext | object | `{}` | Security Context policies for controller pods |
|
||||
@@ -399,14 +402,14 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| controller.scope.enabled | bool | `false` | Enable 'scope' or not |
|
||||
| controller.scope.namespace | string | `""` | Namespace to limit the controller to; defaults to $(POD_NAMESPACE) |
|
||||
| controller.scope.namespaceSelector | string | `""` | When scope.enabled == false, instead of watching all namespaces, we watching namespaces whose labels only match with namespaceSelector. Format like foo=bar. Defaults to empty, means watching all namespaces. |
|
||||
| controller.service.annotations | object | `{}` | |
|
||||
| controller.service.annotations | object | `{}` | Annotations are mandatory for the load balancer to come up. Varies with the cloud service. Values passed through helm tpl engine. |
|
||||
| controller.service.appProtocol | bool | `true` | If enabled is adding an appProtocol option for Kubernetes service. An appProtocol field replacing annotations that were using for setting a backend protocol. Here is an example for AWS: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http It allows choosing the protocol for each backend specified in the Kubernetes service. See the following GitHub issue for more details about the purpose: https://github.com/kubernetes/kubernetes/issues/40244 Will be ignored for Kubernetes versions older than 1.20 # |
|
||||
| controller.service.enableHttp | bool | `true` | |
|
||||
| controller.service.enableHttps | bool | `true` | |
|
||||
| controller.service.enabled | bool | `true` | |
|
||||
| controller.service.external.enabled | bool | `true` | |
|
||||
| controller.service.externalIPs | list | `[]` | List of IP addresses at which the controller services are available # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips # |
|
||||
| controller.service.internal.annotations | object | `{}` | Annotations are mandatory for the load balancer to come up. Varies with the cloud service. |
|
||||
| controller.service.internal.annotations | object | `{}` | Annotations are mandatory for the load balancer to come up. Varies with the cloud service. Values passed through helm tpl engine. |
|
||||
| controller.service.internal.enabled | bool | `false` | Enables an additional internal load balancer (besides the external one). |
|
||||
| controller.service.internal.loadBalancerIP | string | `""` | Used by cloud providers to connect the resulting internal LoadBalancer to a pre-existing static IP. Make sure to add to the service the needed annotation to specify the subnet which the static IP belongs to. For instance, `networking.gke.io/internal-load-balancer-subnet` for GCP and `service.beta.kubernetes.io/aws-load-balancer-subnets` for AWS. |
|
||||
| controller.service.internal.loadBalancerSourceRanges | list | `[]` | Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. |
|
||||
@@ -469,6 +472,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
||||
| defaultBackend.minAvailable | int | `1` | |
|
||||
| defaultBackend.minReadySeconds | int | `0` | `minReadySeconds` to avoid killing pods before we are ready # |
|
||||
| defaultBackend.name | string | `"defaultbackend"` | |
|
||||
| defaultBackend.networkPolicy.enabled | bool | `false` | Enable 'networkPolicy' or not |
|
||||
| defaultBackend.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for default backend pod assignment # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ # |
|
||||
| defaultBackend.podAnnotations | object | `{}` | Annotations to be added to default backend pods # |
|
||||
| defaultBackend.podLabels | object | `{}` | Labels to add to the pod container metadata |
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org).
|
||||
|
||||
### 4.7.2
|
||||
|
||||
* Update Ingress-Nginx version controller-v1.8.2
|
||||
|
||||
**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.7.1...helm-chart-4.7.2
|
||||
@@ -0,0 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org).
|
||||
|
||||
### 4.8.0-beta.0
|
||||
|
||||
* ci(helm): fix Helm Chart release action 422 error (#10237)
|
||||
* helm: Use .Release.Namespace as default for ServiceMonitor namespace (#10249)
|
||||
* [helm] configure allow to configure hostAliases (#10180)
|
||||
* [helm] pass service annotations through helm tpl engine (#10084)
|
||||
* Update Ingress-Nginx version controller-v1.9.0-beta.0
|
||||
|
||||
**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.7.2...helm-chart-4.8.0-beta.0
|
||||
@@ -0,0 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org).
|
||||
|
||||
### 4.8.0
|
||||
|
||||
* ci(helm): fix Helm Chart release action 422 error (#10237)
|
||||
* helm: Use .Release.Namespace as default for ServiceMonitor namespace (#10249)
|
||||
* [helm] configure allow to configure hostAliases (#10180)
|
||||
* [helm] pass service annotations through helm tpl engine (#10084)
|
||||
* Update Ingress-Nginx version controller-v1.9.0
|
||||
|
||||
**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.7.2...helm-chart-4.8.0
|
||||
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org).
|
||||
|
||||
### 4.8.1
|
||||
|
||||
* Update Ingress-Nginx version controller-v1.9.1
|
||||
|
||||
**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.8.0...helm-chart-4.8.1
|
||||
@@ -198,7 +198,6 @@ IngressClass parameters.
|
||||
Extra modules.
|
||||
*/}}
|
||||
{{- define "extraModules" -}}
|
||||
|
||||
- name: {{ .name }}
|
||||
image: {{ .image }}
|
||||
{{- if .distroless | default false }}
|
||||
@@ -209,8 +208,10 @@ Extra modules.
|
||||
{{- if .containerSecurityContext }}
|
||||
securityContext: {{ .containerSecurityContext | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .resources }}
|
||||
resources: {{ .resources | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: {{ toYaml "modules"}}
|
||||
mountPath: {{ toYaml "/modules_mount"}}
|
||||
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{{- define "ingress-nginx.params" -}}
|
||||
- /nginx-ingress-controller
|
||||
{{- if .Values.controller.enableAnnotationValidations }}
|
||||
- --enable-annotation-validation=true
|
||||
{{- end }}
|
||||
{{- if .Values.defaultBackend.enabled }}
|
||||
- --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.networkPolicyEnabled }}
|
||||
{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
@@ -16,11 +16,11 @@ metadata:
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "ingress-nginx.labels" . | nindent 6 }}
|
||||
{{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: admission-webhook
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
- {}
|
||||
- {}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
matchLabels:
|
||||
{{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: controller
|
||||
{{- if not .Values.controller.autoscaling.enabled }}
|
||||
{{- if not (or .Values.controller.autoscaling.enabled .Values.controller.keda.enabled) }}
|
||||
{{- if eq .Values.kind "AppSecStateful" }}
|
||||
serviceName: "open-appsec-stateful-set"
|
||||
{{- end }}
|
||||
@@ -38,11 +38,10 @@ spec:
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
{{- if .Values.controller.updateStrategy }}
|
||||
{{- if (and (not (eq .Values.kind "AppSecStateful")) (eq .Values.controller.kind "DaemonSet")) }}
|
||||
updateStrategy:
|
||||
updateStrategy: {{ toYaml .Values.controller.updateStrategy | nindent 4 }}:
|
||||
{{- else }}
|
||||
strategy:
|
||||
strategy: {{ toYaml .Values.controller.updateStrategy | nindent 4 }}
|
||||
{{- end }}
|
||||
{{ toYaml .Values.controller.updateStrategy | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if (eq .Values.kind "AppSec") }}
|
||||
minReadySeconds: {{ .Values.controller.minReadySeconds }}
|
||||
@@ -68,6 +67,9 @@ spec:
|
||||
{{- if .Values.controller.dnsConfig }}
|
||||
dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostAliases }}
|
||||
hostAliases: {{ tpl (toYaml .Values.controller.hostAliases) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostname }}
|
||||
hostname: {{ toYaml .Values.controller.hostname | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -268,17 +270,14 @@ spec:
|
||||
{{- end }}
|
||||
{{- if .Values.controller.extraModules }}
|
||||
{{- range .Values.controller.extraModules }}
|
||||
{{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }}
|
||||
{{- $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{- include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.opentelemetry.enabled}}
|
||||
{{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{- if (and (not (eq .Values.kind "AppSecStateful")) (eq .Values.controller.kind "DaemonSet")) }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext ) | nindent 8}}
|
||||
{{ else }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext "distroless" false) | nindent 8}}
|
||||
{{- end }}
|
||||
{{- $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{ $otelResources := $.Values.controller.opentelemetry.resources | default dict }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext "distroless" true "resources" $otelResources) | nindent 8}}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostNetwork }}
|
||||
@@ -294,7 +293,7 @@ spec:
|
||||
affinity: {{ toYaml .Values.controller.affinity | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.topologySpreadConstraints }}
|
||||
topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }}
|
||||
topologySpreadConstraints: {{ tpl (toYaml .Values.controller.topologySpreadConstraints) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
|
||||
terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
|
||||
|
||||
@@ -45,6 +45,9 @@ spec:
|
||||
{{- if .Values.controller.dnsConfig }}
|
||||
dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostAliases }}
|
||||
hostAliases: {{ tpl (toYaml .Values.controller.hostAliases) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostname }}
|
||||
hostname: {{ toYaml .Values.controller.hostname | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -180,13 +183,14 @@ spec:
|
||||
{{- end }}
|
||||
{{- if .Values.controller.extraModules }}
|
||||
{{- range .Values.controller.extraModules }}
|
||||
{{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }}
|
||||
{{- $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{- include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.opentelemetry.enabled}}
|
||||
{{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext) | nindent 8}}
|
||||
{{- $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{ $otelResources := $.Values.controller.opentelemetry.resources | default dict }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext "distroless" true "resources" $otelResources) | nindent 8}}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostNetwork }}
|
||||
@@ -202,7 +206,7 @@ spec:
|
||||
affinity: {{ toYaml .Values.controller.affinity | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.topologySpreadConstraints }}
|
||||
topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }}
|
||||
topologySpreadConstraints: {{ tpl (toYaml .Values.controller.topologySpreadConstraints) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
|
||||
terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
|
||||
|
||||
@@ -19,13 +19,12 @@ spec:
|
||||
matchLabels:
|
||||
{{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: controller
|
||||
{{- if not .Values.controller.autoscaling.enabled }}
|
||||
{{- if not (or .Values.controller.autoscaling.enabled .Values.controller.keda.enabled) }}
|
||||
replicas: {{ .Values.controller.replicaCount }}
|
||||
{{- end }}
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
{{- if .Values.controller.updateStrategy }}
|
||||
strategy:
|
||||
{{ toYaml .Values.controller.updateStrategy | nindent 4 }}
|
||||
strategy: {{ toYaml .Values.controller.updateStrategy | nindent 4 }}
|
||||
{{- end }}
|
||||
minReadySeconds: {{ .Values.controller.minReadySeconds }}
|
||||
template:
|
||||
@@ -49,6 +48,9 @@ spec:
|
||||
{{- if .Values.controller.dnsConfig }}
|
||||
dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostAliases }}
|
||||
hostAliases: {{ tpl (toYaml .Values.controller.hostAliases) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostname }}
|
||||
hostname: {{ toYaml .Values.controller.hostname | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -184,13 +186,14 @@ spec:
|
||||
{{- end }}
|
||||
{{- if .Values.controller.extraModules }}
|
||||
{{- range .Values.controller.extraModules }}
|
||||
{{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }}
|
||||
{{- $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{- include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.opentelemetry.enabled}}
|
||||
{{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext "distroless" false) | nindent 8}}
|
||||
{{- $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
|
||||
{{ $otelResources := $.Values.controller.opentelemetry.resources | default dict }}
|
||||
{{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext "distroless" true "resources" $otelResources) | nindent 8}}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.hostNetwork }}
|
||||
@@ -206,7 +209,7 @@ spec:
|
||||
affinity: {{ toYaml .Values.controller.affinity | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.topologySpreadConstraints }}
|
||||
topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }}
|
||||
topologySpreadConstraints: {{ tpl (toYaml .Values.controller.topologySpreadConstraints) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
|
||||
terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
{{- if .Values.controller.networkPolicy.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "ingress-nginx.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: controller
|
||||
{{- with .Values.controller.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
name: {{ include "ingress-nginx.controller.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: controller
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
- ports:
|
||||
{{- range $key, $value := .Values.controller.containerPort }}
|
||||
- protocol: TCP
|
||||
port: {{ $value }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.metrics.enabled }}
|
||||
- protocol: TCP
|
||||
port: {{ .Values.controller.metrics.port }}
|
||||
{{- end }}
|
||||
{{- if .Values.controller.admissionWebhooks.enabled }}
|
||||
- protocol: TCP
|
||||
port: {{ .Values.controller.admissionWebhooks.port }}
|
||||
{{- end }}
|
||||
{{- range $key, $value := .Values.tcp }}
|
||||
- protocol: TCP
|
||||
port: {{ $key }}
|
||||
{{- end }}
|
||||
{{- range $key, $value := .Values.udp }}
|
||||
- protocol: UDP
|
||||
port: {{ $key }}
|
||||
{{- end }}
|
||||
egress:
|
||||
- {}
|
||||
{{- end }}
|
||||
@@ -4,7 +4,7 @@ kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
{{- range $key, $value := .Values.controller.service.internal.annotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{ $key }}: {{ tpl ($value | toString) $ | quote }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "ingress-nginx.labels" . | nindent 4 }}
|
||||
|
||||
@@ -4,7 +4,7 @@ kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
{{- range $key, $value := .Values.controller.service.annotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{ $key }}: {{ tpl ($value | toString) $ | quote }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "ingress-nginx.labels" . | nindent 4 }}
|
||||
|
||||
@@ -11,8 +11,7 @@ metadata:
|
||||
name: {{ template "ingress-nginx.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- if .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.serviceAccount.annotations | nindent 4 }}
|
||||
annotations: {{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
||||
{{- end }}
|
||||
|
||||
@@ -5,6 +5,8 @@ metadata:
|
||||
name: {{ include "ingress-nginx.controller.fullname" . }}
|
||||
{{- if .Values.controller.metrics.serviceMonitor.namespace }}
|
||||
namespace: {{ .Values.controller.metrics.serviceMonitor.namespace | quote }}
|
||||
{{- else }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "ingress-nginx.labels" . | nindent 4 }}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{{- if .Values.controller.admissionWebhooks.enabled }}
|
||||
{{- if .Values.controller.admissionWebhooks.networkPolicyEnabled }}
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "ingress-nginx.fullname" . }}-webhooks-allow
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
ingress:
|
||||
- {}
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "ingress-nginx.name" . }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,25 @@
|
||||
{{- if and .Values.defaultBackend.enabled .Values.defaultBackend.networkPolicy.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "ingress-nginx.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: default-backend
|
||||
{{- with .Values.defaultBackend.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: default-backend
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
- ports:
|
||||
- protocol: TCP
|
||||
port: {{ .Values.defaultBackend.port }}
|
||||
{{- end }}
|
||||
@@ -15,6 +15,7 @@ commonLabels: {}
|
||||
|
||||
controller:
|
||||
name: controller
|
||||
enableAnnotationValidations: false
|
||||
image:
|
||||
## Keep false as default for now!
|
||||
chroot: false
|
||||
@@ -23,9 +24,9 @@ controller:
|
||||
## for backwards compatibility consider setting the full image url via the repository value below
|
||||
## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail
|
||||
## repository:
|
||||
tag: "v1.8.1"
|
||||
digest: sha256:e5c4824e7375fcf2a393e1c03c293b69759af37a9ca6abdb91b13d78a93da8bd
|
||||
digestChroot: sha256:e0d4121e3c5e39de9122e55e331a32d5ebf8d4d257227cb93ab54a1b912a7627
|
||||
tag: "v1.9.1"
|
||||
digest: sha256:605a737877de78969493a4b1213b21de4ee425d2926906857b98050f57a95b25
|
||||
digestChroot: sha256:2ac744ef08850ee86ad7162451a6879f47c1a41c6a757f6b6f913c52103b8836
|
||||
pullPolicy: IfNotPresent
|
||||
# www-data -> uid 101
|
||||
runAsUser: 101
|
||||
@@ -48,6 +49,16 @@ controller:
|
||||
addHeaders: {}
|
||||
# -- Optionally customize the pod dnsConfig.
|
||||
dnsConfig: {}
|
||||
# -- Optionally customize the pod hostAliases.
|
||||
hostAliases: []
|
||||
# - ip: 127.0.0.1
|
||||
# hostnames:
|
||||
# - foo.local
|
||||
# - bar.local
|
||||
# - ip: 10.1.2.3
|
||||
# hostnames:
|
||||
# - foo.remote
|
||||
# - bar.remote
|
||||
# -- Optionally customize the pod hostname.
|
||||
hostname: {}
|
||||
# -- Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'.
|
||||
@@ -63,14 +74,14 @@ controller:
|
||||
watchIngressWithoutClass: false
|
||||
# -- Process IngressClass per name (additionally as per spec.controller).
|
||||
ingressClassByName: false
|
||||
# -- This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-aware-hints="auto"
|
||||
# -- This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-mode="auto"
|
||||
# Defaults to false
|
||||
enableTopologyAwareRouting: false
|
||||
# -- This configuration defines if Ingress Controller should allow users to set
|
||||
# their own *-snippet annotations, otherwise this is forbidden / dropped
|
||||
# when users add those annotations.
|
||||
# Global snippets in ConfigMap are still respected
|
||||
allowSnippetAnnotations: true
|
||||
allowSnippetAnnotations: false
|
||||
# -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm),
|
||||
# since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920
|
||||
# is merged
|
||||
@@ -85,6 +96,10 @@ controller:
|
||||
http: 80
|
||||
# -- 'hostPort' https port
|
||||
https: 443
|
||||
# NetworkPolicy for controller component.
|
||||
networkPolicy:
|
||||
# -- Enable 'networkPolicy' or not
|
||||
enabled: false
|
||||
# -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader'
|
||||
electionID: ""
|
||||
## This section refers to the creation of the IngressClass resource
|
||||
@@ -245,12 +260,22 @@ controller:
|
||||
## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
|
||||
##
|
||||
topologySpreadConstraints: []
|
||||
# - maxSkew: 1
|
||||
# topologyKey: topology.kubernetes.io/zone
|
||||
# whenUnsatisfiable: DoNotSchedule
|
||||
# labelSelector:
|
||||
# - labelSelector:
|
||||
# matchLabels:
|
||||
# app.kubernetes.io/instance: ingress-nginx-internal
|
||||
# app.kubernetes.io/name: '{{ include "ingress-nginx.name" . }}'
|
||||
# app.kubernetes.io/instance: '{{ .Release.Name }}'
|
||||
# app.kubernetes.io/component: controller
|
||||
# topologyKey: topology.kubernetes.io/zone
|
||||
# maxSkew: 1
|
||||
# whenUnsatisfiable: ScheduleAnyway
|
||||
# - labelSelector:
|
||||
# matchLabels:
|
||||
# app.kubernetes.io/name: '{{ include "ingress-nginx.name" . }}'
|
||||
# app.kubernetes.io/instance: '{{ .Release.Name }}'
|
||||
# app.kubernetes.io/component: controller
|
||||
# topologyKey: kubernetes.io/hostname
|
||||
# maxSkew: 1
|
||||
# whenUnsatisfiable: ScheduleAnyway
|
||||
|
||||
# -- `terminationGracePeriodSeconds` to avoid killing pods before we are ready
|
||||
## wait up to five minutes for the drain of connections
|
||||
@@ -415,6 +440,7 @@ controller:
|
||||
# Will be ignored for Kubernetes versions older than 1.20
|
||||
##
|
||||
appProtocol: true
|
||||
# -- Annotations are mandatory for the load balancer to come up. Varies with the cloud service. Values passed through helm tpl engine.
|
||||
annotations: {}
|
||||
labels: {}
|
||||
# clusterIP: ""
|
||||
@@ -476,7 +502,7 @@ controller:
|
||||
internal:
|
||||
# -- Enables an additional internal load balancer (besides the external one).
|
||||
enabled: false
|
||||
# -- Annotations are mandatory for the load balancer to come up. Varies with the cloud service.
|
||||
# -- Annotations are mandatory for the load balancer to come up. Varies with the cloud service. Values passed through helm tpl engine.
|
||||
annotations: {}
|
||||
# -- Used by cloud providers to connect the resulting internal LoadBalancer to a pre-existing static IP. Make sure to add to the service the needed annotation to specify the subnet which the static IP belongs to. For instance, `networking.gke.io/internal-load-balancer-subnet` for GCP and `service.beta.kubernetes.io/aws-load-balancer-subnets` for AWS.
|
||||
loadBalancerIP: ""
|
||||
@@ -552,9 +578,10 @@ controller:
|
||||
|
||||
opentelemetry:
|
||||
enabled: false
|
||||
image: registry.k8s.io/ingress-nginx/opentelemetry:v20230527@sha256:fd7ec835f31b7b37187238eb4fdad4438806e69f413a203796263131f4f02ed0
|
||||
image: registry.k8s.io/ingress-nginx/opentelemetry:v20230721-3e2062ee5@sha256:13bee3f5223883d3ca62fee7309ad02d22ec00ff0d7033e3e9aca7a9f60fd472
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
resources: {}
|
||||
admissionWebhooks:
|
||||
annotations: {}
|
||||
# ignore-check.kube-linter.io/no-read-only-rootfs: "This deployment needs write access to root filesystem".
|
||||
@@ -583,7 +610,6 @@ controller:
|
||||
labels: {}
|
||||
# -- Use an existing PSP instead of creating one
|
||||
existingPsp: ""
|
||||
networkPolicyEnabled: false
|
||||
service:
|
||||
annotations: {}
|
||||
# clusterIP: ""
|
||||
@@ -849,6 +875,10 @@ defaultBackend:
|
||||
maxReplicas: 2
|
||||
targetCPUUtilizationPercentage: 50
|
||||
targetMemoryUtilizationPercentage: 50
|
||||
# NetworkPolicy for default backend component.
|
||||
networkPolicy:
|
||||
# -- Enable 'networkPolicy' or not
|
||||
enabled: false
|
||||
service:
|
||||
annotations: {}
|
||||
# clusterIP: ""
|
||||
@@ -909,8 +939,8 @@ appsec:
|
||||
image:
|
||||
#registry:
|
||||
repository: ghcr.io/openappsec
|
||||
image: agent
|
||||
tag: latest
|
||||
image: "agent"
|
||||
tag: "latest"
|
||||
pullPolicy: Always
|
||||
|
||||
securityContext: {}
|
||||
|
||||
@@ -1,5 +1,98 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
Nothing yet.
|
||||
|
||||
## 2.29.0
|
||||
|
||||
### Improvements
|
||||
* Make it possible to set the admission webhook's `timeoutSeconds`.
|
||||
|
||||
## 2.28.1
|
||||
|
||||
### Fixed
|
||||
|
||||
* The admission webhook now includes Gateway API resources and Ingress
|
||||
resources for controller versions 2.12+. This version introduces new
|
||||
validations for Kong's regex path implementation.
|
||||
|
||||
## 2.28.0
|
||||
|
||||
### Improvements
|
||||
|
||||
* Bump default `kong` image tag to 3.4.
|
||||
[#883](https://github.com/Kong/charts/pull/883)
|
||||
* Bump default ingress controller image tag to 2.12.
|
||||
* Added validation rule for `latency` upstream load balancing algorithm to
|
||||
CRDs. [Upgrade your CRDs](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#updates-to-crds)
|
||||
when installing this release.
|
||||
|
||||
## 2.27.0
|
||||
|
||||
### Improvements
|
||||
|
||||
* Listens now all support `.address` configuration. This was an existing
|
||||
setting that was not applied properly for some listens.
|
||||
[#881](https://github.com/Kong/charts/pull/881)
|
||||
|
||||
## 2.26.5
|
||||
|
||||
### Fixed
|
||||
|
||||
* Kuma ServiceAccount Token hints and volumes are also available in migrations
|
||||
Pods.
|
||||
[#877](https://github.com/Kong/charts/pull/877)
|
||||
|
||||
## 2.26.4
|
||||
|
||||
### Fixed
|
||||
|
||||
* updated `admin_api_uri` to `admin_gui_api_url` as per [kong documentation](https://docs.konghq.com/gateway/3.4.x/reference/configuration/#admin_api_uri).
|
||||
|
||||
## 2.26.3
|
||||
|
||||
### Fixed
|
||||
|
||||
* Enabled Service and Ingress in Kong Manager for non enterprise users.
|
||||
|
||||
## 2.26.2
|
||||
|
||||
### Fixed
|
||||
|
||||
* Add missing CRD KongConsumerGroup and extend status subresource for CRDs
|
||||
|
||||
## 2.26.1
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix parsing enterprise tags (like e.g. `3.4.0.0`)
|
||||
[#857](https://github.com/Kong/charts/pull/857)
|
||||
|
||||
## 2.26.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
2.26 changes the default proxy readiness endpoint for newer Kong versions. This
|
||||
causes an issue in a narrow edge case. If all of the following are true:
|
||||
|
||||
* You use Kong 3.3 or newer.
|
||||
* You use controller 2.10 or older.
|
||||
* You run the controller and proxy in separate Deployments.
|
||||
|
||||
you are affected and should review [the 2.26 upgrade instructions](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#2260).
|
||||
|
||||
### Improvements
|
||||
|
||||
* Use the Kong 3.3 `/status/ready` endpoint for readiness probes by default if
|
||||
available. If not available, use the old `/status` default.
|
||||
[#844](https://github.com/Kong/charts/pull/844)
|
||||
* Add ArgoCD `Sync` and `BeforeHookCreation` [hook policies](https://argo-cd.readthedocs.io/en/stable/user-guide/resource_hooks/)
|
||||
to the the init and pre-upgrade migrations Jobs.
|
||||
* Add controller's RBAC rules for `KongConsumerGroups` CRD.
|
||||
[#850](https://github.com/Kong/charts/pull/850)
|
||||
* Updated controller version to 2.11.
|
||||
|
||||
## 2.25.0
|
||||
|
||||
- Generate the `adminApiService.name` value from `.Release.Name` rather than
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v2
|
||||
appVersion: "3.3"
|
||||
appVersion: 1.1.0
|
||||
dependencies:
|
||||
- condition: postgresql.enabled
|
||||
name: postgresql
|
||||
@@ -16,4 +16,4 @@ maintainers:
|
||||
name: open-appsec-kong
|
||||
sources:
|
||||
- https://github.com/Kong/charts/tree/main/charts/kong
|
||||
version: 2.25.0
|
||||
version: 2.29.0
|
||||
|
||||
@@ -71,6 +71,7 @@ $ helm install kong/kong --generate-name
|
||||
- [Sessions](#sessions)
|
||||
- [Email/SMTP](#emailsmtp)
|
||||
- [Prometheus Operator integration](#prometheus-operator-integration)
|
||||
- [Argo CD considerations](#argo-cd-considerations)
|
||||
- [Changelog](https://github.com/Kong/charts/blob/main/charts/kong/CHANGELOG.md)
|
||||
- [Upgrading](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md)
|
||||
- [Seeking help](#seeking-help)
|
||||
@@ -599,7 +600,8 @@ directory.
|
||||
| Parameter | Description | Default |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------- | ------------------- |
|
||||
| image.repository | Kong image | `kong` |
|
||||
| image.tag | Kong image version | `2.5` |
|
||||
| image.tag | Kong image version | `3.4` |
|
||||
| image.effectiveSemver | Semantic version to use for version-dependent features (if `tag` is not a semver) | |
|
||||
| image.pullPolicy | Image pull policy | `IfNotPresent` |
|
||||
| image.pullSecrets | Image pull secrets | `null` |
|
||||
| replicaCount | Kong instance count. It has no effect when `autoscaling.enabled` is set to true | `1` |
|
||||
@@ -723,7 +725,7 @@ section of `values.yaml` file:
|
||||
|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
|
||||
| enabled | Deploy the ingress controller, rbac and crd | true |
|
||||
| image.repository | Docker image with the ingress controller | kong/kubernetes-ingress-controller |
|
||||
| image.tag | Version of the ingress controller | 2.0 |
|
||||
| image.tag | Version of the ingress controller | `2.12` |
|
||||
| image.effectiveSemver | Version of the ingress controller used for version-specific features when image.tag is not a valid semantic version | |
|
||||
| readinessProbe | Kong ingress controllers readiness probe | |
|
||||
| livenessProbe | Kong ingress controllers liveness probe | |
|
||||
@@ -737,11 +739,13 @@ section of `values.yaml` file:
|
||||
| admissionWebhook.enabled | Whether to enable the validating admission webhook | true |
|
||||
| admissionWebhook.failurePolicy | How unrecognized errors from the admission endpoint are handled (Ignore or Fail) | Ignore |
|
||||
| admissionWebhook.port | The port the ingress controller will listen on for admission webhooks | 8080 |
|
||||
| admissionWebhook.address | The address the ingress controller will listen on for admission webhooks, if not 0.0.0.0 | |
|
||||
| admissionWebhook.annotations | Annotations for the Validation Webhook Configuration | |
|
||||
| admissionWebhook.certificate.provided | Use a provided certificate. When set to false, the chart will automatically generate a certificate. | false |
|
||||
| admissionWebhook.certificate.secretName | Name of the TLS secret for the provided webhook certificate | |
|
||||
| admissionWebhook.certificate.caBundle | PEM encoded CA bundle which will be used to validate the provided webhook certificate | |
|
||||
| admissionWebhook.namespaceSelector | Add namespaceSelector to the webhook. Please go to [Kubernetes doc for the specs](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector) | |
|
||||
| admissionWebhook.timeoutSeconds | Kubernetes `apiserver`'s timeout when running this webhook. Default: 10 seconds. | |
|
||||
| userDefinedVolumes | Create volumes. Please go to Kubernetes doc for the spec of the volumes | |
|
||||
| userDefinedVolumeMounts | Create volumeMounts. Please go to Kubernetes doc for the spec of the volumeMounts | |
|
||||
| terminationGracePeriodSeconds | Sets the [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution) for Deployment pod | 30 |
|
||||
@@ -1045,7 +1049,7 @@ must know where other Kong services (namely the admin and files APIs) can be
|
||||
accessed in order to function properly. Kong's default behavior for attempting
|
||||
to locate these absent configuration is unlikely to work in common Kubernetes
|
||||
environments. Because of this, you should set each of `admin_gui_url`,
|
||||
`admin_api_uri`, `proxy_url`, `portal_api_url`, `portal_gui_host`, and
|
||||
`admin_gui_api_url`, `proxy_url`, `portal_api_url`, `portal_gui_host`, and
|
||||
`portal_gui_protocol` under the `.env` key in values.yaml to locations where
|
||||
each of their respective services can be accessed to ensure that Kong services
|
||||
can locate one another and properly set CORS headers. See the
|
||||
@@ -1161,6 +1165,28 @@ admin:
|
||||
enable-metrics: "true"
|
||||
```
|
||||
|
||||
## Argo CD Considerations
|
||||
|
||||
The built-in database subchart (`postgresql.enabled` in values) is not
|
||||
supported when installing the chart via Argo CD.
|
||||
|
||||
Argo CD does not support the full Helm lifecycle. There is no distinction
|
||||
between the initial install and upgrades. Both operations are a "sync" in Argo
|
||||
terms. This affects when migration Jobs execute in database-backed Kong
|
||||
installs.
|
||||
|
||||
The chart sets the `Sync` and `BeforeHookCreation` deletion
|
||||
[hook policies](https://argo-cd.readthedocs.io/en/stable/user-guide/resource_hooks/)
|
||||
on the `init-migrations` and `pre-upgrade-migrations` Jobs.
|
||||
|
||||
The `pre-upgrade-migrations` Job normally uses Helm's `pre-upgrade` policy. Argo
|
||||
translates this to its `PreSync` policy, which would create the Job before all
|
||||
sync phase resources. Doing this before various sync phase resources (such as
|
||||
the ServiceAccount) are in place would prevent the Job from running
|
||||
successfully. Overriding this with Argo's `Sync` policy starts the Job at the
|
||||
same time as the upgraded Deployment Pods. The new Pods may fail to start
|
||||
temporarily, but will eventually start normally once migrations complete.
|
||||
|
||||
## Seeking help
|
||||
|
||||
If you run into an issue, bug or have a question, please reach out to the Kong
|
||||
|
||||
@@ -17,7 +17,8 @@ upgrading from a previous version.
|
||||
## Table of contents
|
||||
|
||||
- [Upgrade considerations for all versions](#upgrade-considerations-for-all-versions)
|
||||
- [2.17.0](#2170)
|
||||
- [2.26.0](#2260)
|
||||
- [2.19.0](#2190)
|
||||
- [2.13.0](#2130)
|
||||
- [2.8.0](#280)
|
||||
- [2.7.0](#270)
|
||||
@@ -83,6 +84,35 @@ https://raw.githubusercontent.com/Kong/charts/kong-<version>/charts/kong/crds/cu
|
||||
For example, if your release is 2.6.4, you would apply
|
||||
`https://raw.githubusercontent.com/Kong/charts/kong-2.6.4/charts/kong/crds/custom-resource-definitions.yaml`.
|
||||
|
||||
## 2.26.0
|
||||
|
||||
If you are using controller version 2.10 or lower and proxy version 3.3 or
|
||||
higher in separate Deployments (such as when using the `ingress` chart), proxy
|
||||
Pods will not become ready unless you override the default readiness endpoint:
|
||||
|
||||
```
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /status
|
||||
```
|
||||
|
||||
This section goes under the `gateway` section when using the `ingress` chart.
|
||||
|
||||
2.26 changes the default proxy readiness endpoint to the `/status/ready`
|
||||
endpoint introduced in Kong 3.3. This endpoint reports true when Kong has
|
||||
configuration available, whereas the previous `/status` endpoint returned true
|
||||
immediately after start, and could result in proxy instances attempting to
|
||||
serve requests before they had configuration.
|
||||
|
||||
The chart has logic to fall back to the older endpoint if the proxy and
|
||||
controller versions do not work well with the new endpoint. However, the chart
|
||||
detection cannot determine the controller version when the controller is in a
|
||||
separate Deployment, and will always use the new endpoint if the Kong image
|
||||
version is 3.3 or higher.
|
||||
|
||||
Kong recommends Kong 3.3 and higher users update to controller 2.11 at their
|
||||
earliest convenience to take advantage of the improved readiness behavior.
|
||||
|
||||
## 2.19.0
|
||||
|
||||
2.19 sets a default [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
admin:
|
||||
enabled: true
|
||||
type: ClusterIP
|
||||
|
||||
# Stub config to make the instance become ready
|
||||
dblessConfig:
|
||||
config: |
|
||||
_format_version: "1.1"
|
||||
services:
|
||||
- name: example.com
|
||||
url: http://example.com
|
||||
routes:
|
||||
- name: example
|
||||
paths:
|
||||
- "/example"
|
||||
|
||||
ingressController:
|
||||
enabled: false
|
||||
@@ -1,6 +0,0 @@
|
||||
admin:
|
||||
enabled: true
|
||||
type: ClusterIP
|
||||
|
||||
ingressController:
|
||||
enabled: false
|
||||
@@ -1,6 +1,3 @@
|
||||
|
||||
# install chart with some extra labels
|
||||
|
||||
extraLabels:
|
||||
acme.com/some-key: some-value
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
# install chart with default values
|
||||
proxy:
|
||||
type: NodePort
|
||||
|
||||
env:
|
||||
anonymous_reports: "off"
|
||||
ingressController:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# CI test for empty hostname including tls secret using string
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
tls: "kong.proxy.example.secret"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# CI test for hostname including tls secret using string
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: "proxy.kong.example"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# CI test for using ingress hosts configuration
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hosts:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# CI test for testing combined ingress hostname and hosts configuration including tls configuraion using slice
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: "proxy.kong.example"
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
# use single image strings instead of repository/tag
|
||||
|
||||
image:
|
||||
unifiedRepoTag: kong:2.6
|
||||
proxy:
|
||||
type: NodePort
|
||||
unifiedRepoTag: kong:3.4
|
||||
|
||||
env:
|
||||
anonymous_reports: "off"
|
||||
@@ -12,4 +10,4 @@ ingressController:
|
||||
env:
|
||||
anonymous_reports: "false"
|
||||
image:
|
||||
unifiedRepoTag: kong/kubernetes-ingress-controller:2.0.2
|
||||
unifiedRepoTag: kong/kubernetes-ingress-controller:2.12
|
||||
@@ -0,0 +1,14 @@
|
||||
ingressController:
|
||||
enabled: false
|
||||
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.4.0.0"
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: "/status"
|
||||
port: status
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
@@ -30,14 +30,12 @@ podLabels:
|
||||
environment: test
|
||||
# - ingress resources are created with hosts
|
||||
admin:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: admin.kong.example
|
||||
annotations: {}
|
||||
path: /
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: proxy.kong.example
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
# - stream listens work
|
||||
# - a mixture of controller, Kong, and shared volumes successfully mount
|
||||
# - watchNamespaces is set
|
||||
# - the admission webhook is enabled; has the timeout explicitly set
|
||||
ingressController:
|
||||
enabled: true
|
||||
admissionWebhook:
|
||||
enabled: true
|
||||
timeoutSeconds: 5
|
||||
env:
|
||||
anonymous_reports: "false"
|
||||
customEnv:
|
||||
@@ -21,13 +25,11 @@ env:
|
||||
database: "postgres"
|
||||
# - ingress resources are created without hosts
|
||||
admin:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hosts: []
|
||||
path: /
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: proxy.kong.example
|
||||
|
||||
@@ -8,8 +8,6 @@ env:
|
||||
database: "off"
|
||||
postgresql:
|
||||
enabled: false
|
||||
proxy:
|
||||
type: NodePort
|
||||
deployment:
|
||||
initContainers:
|
||||
- name: "bash"
|
||||
|
||||
@@ -12,7 +12,6 @@ env:
|
||||
postgresql:
|
||||
enabled: false
|
||||
proxy:
|
||||
type: NodePort
|
||||
# - add stream listens
|
||||
stream:
|
||||
- containerPort: 9000
|
||||
|
||||
@@ -26,13 +26,11 @@ customEnv:
|
||||
client_id: "exampleId"
|
||||
# - ingress resources are created without hosts
|
||||
admin:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hosts: []
|
||||
path: /
|
||||
proxy:
|
||||
type: NodePort
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: proxy.kong.example
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# CI test for testing dbless deployment without ingress controllers
|
||||
# - disable ingress controller
|
||||
# - no static config
|
||||
ingressController:
|
||||
enabled: false
|
||||
# - disable DB for kong
|
||||
env:
|
||||
anonymous_reports: "off"
|
||||
database: "off"
|
||||
postgresql:
|
||||
enabled: false
|
||||
proxy:
|
||||
type: NodePort
|
||||
deployment:
|
||||
initContainers:
|
||||
- name: "bash"
|
||||
image: "bash:latest"
|
||||
command: ["/bin/sh", "-c", "true"]
|
||||
resources:
|
||||
limits:
|
||||
cpu: "100m"
|
||||
memory: "64Mi"
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "64Mi"
|
||||
volumeMounts:
|
||||
- name: "tmpdir"
|
||||
mountPath: "/opt/tmp"
|
||||
userDefinedVolumes:
|
||||
- name: "tmpdir"
|
||||
emptyDir: {}
|
||||
userDefinedVolumeMounts:
|
||||
- name: "tmpdir"
|
||||
mountPath: "/opt/tmp"
|
||||
@@ -1,10 +1,9 @@
|
||||
# generated using: kubectl kustomize github.com/kong/kubernetes-ingress-controller/config/crd?ref=v2.8.1
|
||||
# generated using: kubectl kustomize 'github.com/kong/kubernetes-ingress-controller/config/crd?ref=v2.12.0'
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: ingressclassparameterses.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
@@ -56,8 +55,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: kongclusterplugins.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
@@ -91,6 +89,9 @@ spec:
|
||||
name: Config
|
||||
priority: 1
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Programmed")].status
|
||||
name: Programmed
|
||||
type: string
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
@@ -142,6 +143,11 @@ spec:
|
||||
disabled:
|
||||
description: Disabled set if the plugin is disabled or not.
|
||||
type: boolean
|
||||
instance_name:
|
||||
description: InstanceName is an optional custom name to identify an instance
|
||||
of the plugin. This is useful when running the same plugin in multiple
|
||||
contexts, for example, on multiple services.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
@@ -183,6 +189,8 @@ spec:
|
||||
description: Protocols configures plugin to run on requests received on
|
||||
specific protocols.
|
||||
items:
|
||||
description: KongProtocol is a valid Kong protocol. This alias is necessary
|
||||
to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
@@ -201,6 +209,91 @@ spec:
|
||||
- second
|
||||
- all
|
||||
type: string
|
||||
status:
|
||||
description: Status represents the current status of the KongClusterPlugin
|
||||
resource.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Pending
|
||||
status: Unknown
|
||||
type: Programmed
|
||||
description: "Conditions describe the current conditions of the KongClusterPluginStatus.
|
||||
\n Known condition types are: \n * \"Programmed\""
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
required:
|
||||
- plugin
|
||||
type: object
|
||||
@@ -213,8 +306,142 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: kongconsumergroups.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
names:
|
||||
categories:
|
||||
- kong-ingress-controller
|
||||
kind: KongConsumerGroup
|
||||
listKind: KongConsumerGroupList
|
||||
plural: kongconsumergroups
|
||||
shortNames:
|
||||
- kcg
|
||||
singular: kongconsumergroup
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- additionalPrinterColumns:
|
||||
- description: Age
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
- jsonPath: .status.conditions[?(@.type=="Programmed")].status
|
||||
name: Programmed
|
||||
type: string
|
||||
name: v1beta1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: KongConsumerGroup is the Schema for the kongconsumergroups API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
status:
|
||||
description: Status represents the current status of the KongConsumer
|
||||
resource.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Pending
|
||||
status: Unknown
|
||||
type: Programmed
|
||||
description: "Conditions describe the current conditions of the KongConsumerGroup.
|
||||
\n Known condition types are: \n * \"Programmed\""
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: kongconsumers.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
@@ -238,6 +465,9 @@ spec:
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
- jsonPath: .status.conditions[?(@.type=="Programmed")].status
|
||||
name: Programmed
|
||||
type: string
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
@@ -248,6 +478,12 @@ spec:
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
consumerGroups:
|
||||
description: ConsumerGroups are references to consumer groups (that consumer
|
||||
wants to be part of) provisioned in Kong.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
credentials:
|
||||
description: Credentials are references to secrets containing a credential
|
||||
to be provisioned in Kong.
|
||||
@@ -265,6 +501,91 @@ spec:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
status:
|
||||
description: Status represents the current status of the KongConsumer
|
||||
resource.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Pending
|
||||
status: Unknown
|
||||
type: Programmed
|
||||
description: "Conditions describe the current conditions of the KongConsumer.
|
||||
\n Known condition types are: \n * \"Programmed\""
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
username:
|
||||
description: Username is a Kong cluster-unique username of the consumer.
|
||||
type: string
|
||||
@@ -278,8 +599,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: kongingresses.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
@@ -381,8 +701,7 @@ spec:
|
||||
type: integer
|
||||
methods:
|
||||
description: 'Methods is a list of HTTP methods that match this Route.
|
||||
Deprecated: use Ingress'' "konghq.com/override-protocols" annotation
|
||||
instead.'
|
||||
Deprecated: use Ingress'' "konghq.com/methods" annotation instead.'
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -407,6 +726,8 @@ spec:
|
||||
allow. Deprecated: use Ingress'' "konghq.com/protocols" annotation
|
||||
instead.'
|
||||
items:
|
||||
description: KongProtocol is a valid Kong protocol. This alias is
|
||||
necessary to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
@@ -448,8 +769,8 @@ spec:
|
||||
type: object
|
||||
upstream:
|
||||
description: Upstream represents a virtual hostname and can be used to
|
||||
load balance incoming requests over multiple targets (e.g. Kubernetes
|
||||
Services can be a target, or URLs can be targets).
|
||||
loadbalance incoming requests over multiple targets (e.g. Kubernetes
|
||||
`Services` can be a target, OR `Endpoints` can be targets).
|
||||
properties:
|
||||
algorithm:
|
||||
description: Algorithm is the load balancing algorithm to use.
|
||||
@@ -457,6 +778,7 @@ spec:
|
||||
- round-robin
|
||||
- consistent-hashing
|
||||
- least-connections
|
||||
- latency
|
||||
type: string
|
||||
hash_fallback:
|
||||
description: 'HashFallback defines What to use as hashing input if
|
||||
@@ -512,6 +834,12 @@ spec:
|
||||
concurrency:
|
||||
minimum: 1
|
||||
type: integer
|
||||
headers:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
healthy:
|
||||
description: Healthy configures thresholds and HTTP status
|
||||
codes to mark targets healthy for an upstream.
|
||||
@@ -626,8 +954,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: kongplugins.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
@@ -661,6 +988,9 @@ spec:
|
||||
name: Config
|
||||
priority: 1
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Programmed")].status
|
||||
name: Programmed
|
||||
type: string
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
@@ -708,6 +1038,11 @@ spec:
|
||||
disabled:
|
||||
description: Disabled set if the plugin is disabled or not.
|
||||
type: boolean
|
||||
instance_name:
|
||||
description: InstanceName is an optional custom name to identify an instance
|
||||
of the plugin. This is useful when running the same plugin in multiple
|
||||
contexts, for example, on multiple services.
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
@@ -749,6 +1084,8 @@ spec:
|
||||
description: Protocols configures plugin to run on requests received on
|
||||
specific protocols.
|
||||
items:
|
||||
description: KongProtocol is a valid Kong protocol. This alias is necessary
|
||||
to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342
|
||||
enum:
|
||||
- http
|
||||
- https
|
||||
@@ -767,6 +1104,90 @@ spec:
|
||||
- second
|
||||
- all
|
||||
type: string
|
||||
status:
|
||||
description: Status represents the current status of the KongPlugin resource.
|
||||
properties:
|
||||
conditions:
|
||||
default:
|
||||
- lastTransitionTime: "1970-01-01T00:00:00Z"
|
||||
message: Waiting for controller
|
||||
reason: Pending
|
||||
status: Unknown
|
||||
type: Programmed
|
||||
description: "Conditions describe the current conditions of the KongPluginStatus.
|
||||
\n Known condition types are: \n * \"Programmed\""
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource. --- This struct is intended for direct
|
||||
use as an array at the field path .status.conditions. For example,
|
||||
\n type FooStatus struct{ // Represents the observations of a
|
||||
foo's current state. // Known .status.conditions.type are: \"Available\",
|
||||
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
|
||||
// +listType=map // +listMapKey=type Conditions []metav1.Condition
|
||||
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
|
||||
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: lastTransitionTime is the last time the condition
|
||||
transitioned from one status to another. This should be when
|
||||
the underlying condition changed. If that is not known, then
|
||||
using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: message is a human readable message indicating
|
||||
details about the transition. This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration represents the .metadata.generation
|
||||
that the condition was set based upon. For instance, if .metadata.generation
|
||||
is currently 12, but the .status.conditions[x].observedGeneration
|
||||
is 9, the condition is out of date with respect to the current
|
||||
state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: reason contains a programmatic identifier indicating
|
||||
the reason for the condition's last transition. Producers
|
||||
of specific condition types may define expected values and
|
||||
meanings for this field, and whether the values are considered
|
||||
a guaranteed API. The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
--- Many .condition.type values are consistent across resources
|
||||
like Available, but because arbitrary conditions can be useful
|
||||
(see .node.status.conditions), the ability to deconflict is
|
||||
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
maxItems: 8
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- type
|
||||
x-kubernetes-list-type: map
|
||||
type: object
|
||||
required:
|
||||
- plugin
|
||||
type: object
|
||||
@@ -779,8 +1200,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: tcpingresses.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
@@ -966,8 +1386,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.11.1
|
||||
creationTimestamp: null
|
||||
controller-gen.kubebuilder.io/version: v0.13.0
|
||||
name: udpingresses.configuration.konghq.com
|
||||
spec:
|
||||
group: configuration.konghq.com
|
||||
|
||||
@@ -88,7 +88,7 @@ enterprise:
|
||||
enabled: true
|
||||
env:
|
||||
admin_access_log: /dev/stdout
|
||||
admin_api_uri: https://kong.127-0-0-1.nip.io/api
|
||||
admin_gui_api_url: https://kong.127-0-0-1.nip.io/api
|
||||
admin_error_log: /dev/stdout
|
||||
admin_gui_access_log: /dev/stdout
|
||||
admin_gui_error_log: /dev/stdout
|
||||
@@ -146,7 +146,7 @@ extraLabels:
|
||||
konghq.com/component: quickstart
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
ingressController:
|
||||
enabled: true
|
||||
env:
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
prefix: /kong_prefix/
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
admin:
|
||||
enabled: true
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
image:
|
||||
repository: kong
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
prefix: /kong_prefix/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
enterprise:
|
||||
enabled: true
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
database: postgres
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
image:
|
||||
repository: kong/kong-gateway
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
role: data_plane
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
image:
|
||||
repository: kong
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
prefix: /kong_prefix/
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
image:
|
||||
repository: kong
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
prefix: /kong_prefix/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
image:
|
||||
repository: kong
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
|
||||
env:
|
||||
prefix: /kong_prefix/
|
||||
|
||||
@@ -330,10 +330,11 @@ Create KONG_STREAM_LISTEN string
|
||||
*/}}
|
||||
{{- define "kong.streamListen" -}}
|
||||
{{- $unifiedListen := list -}}
|
||||
{{- $address := (default "0.0.0.0" .address) -}}
|
||||
{{- range .stream -}}
|
||||
{{- $listenConfig := dict -}}
|
||||
{{- $listenConfig := merge $listenConfig . -}}
|
||||
{{- $_ := set $listenConfig "address" "0.0.0.0" -}}
|
||||
{{- $_ := set $listenConfig "address" $address -}}
|
||||
{{/* You set NGINX stream listens to UDP using a parameter due to historical reasons.
|
||||
Our configuration is dual-purpose, for both the Service and listen string, so we
|
||||
forcibly inject this parameter if that's the Service protocol. The default handles
|
||||
@@ -458,7 +459,8 @@ The name of the service used for the ingress controller's validation webhook
|
||||
{{- $_ := set $autoEnv "CONTROLLER_ELECTION_ID" (printf "kong-ingress-controller-leader-%s" .Values.ingressController.ingressClass) -}}
|
||||
|
||||
{{- if .Values.ingressController.admissionWebhook.enabled }}
|
||||
{{- $_ := set $autoEnv "CONTROLLER_ADMISSION_WEBHOOK_LISTEN" (printf "0.0.0.0:%d" (int64 .Values.ingressController.admissionWebhook.port)) -}}
|
||||
{{- $address := (default "0.0.0.0" .Values.ingressController.admissionWebhook.address) -}}
|
||||
{{- $_ := set $autoEnv "CONTROLLER_ADMISSION_WEBHOOK_LISTEN" (printf "%s:%d" $address (int64 .Values.ingressController.admissionWebhook.port)) -}}
|
||||
{{- end }}
|
||||
{{- if (not (eq (len .Values.ingressController.watchNamespaces) 0)) }}
|
||||
{{- $_ := set $autoEnv "CONTROLLER_WATCH_NAMESPACE" (.Values.ingressController.watchNamespaces | join ",") -}}
|
||||
@@ -552,6 +554,41 @@ The name of the service used for the ingress controller's validation webhook
|
||||
- name: {{ template "kong.fullname" . }}-tmp
|
||||
emptyDir:
|
||||
sizeLimit: {{ .Values.deployment.tmpDir.sizeLimit }}
|
||||
{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }}
|
||||
- name: {{ template "kong.serviceAccountTokenName" . }}
|
||||
{{- /* Due to GKE versions (e.g. v1.23.15-gke.1900) we need to handle pre-release part of the version as well.
|
||||
See the related documentation of semver module that Helm depends on for semverCompare:
|
||||
https://github.com/Masterminds/semver#working-with-prerelease-versions
|
||||
Related Helm issue: https://github.com/helm/helm/issues/3810 */}}
|
||||
{{- if semverCompare ">=1.20.0-0" .Capabilities.KubeVersion.Version }}
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
expirationSeconds: 3607
|
||||
path: token
|
||||
- configMap:
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
name: kube-root-ca.crt
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
path: namespace
|
||||
{{- else }}
|
||||
secret:
|
||||
secretName: {{ template "kong.serviceAccountTokenName" . }}
|
||||
items:
|
||||
- key: token
|
||||
path: token
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
- key: namespace
|
||||
path: namespace
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and ( .Capabilities.APIVersions.Has "cert-manager.io/v1" ) .Values.certificates.enabled -}}
|
||||
{{- if .Values.certificates.cluster.enabled }}
|
||||
- name: {{ include "kong.fullname" . }}-cluster-cert
|
||||
@@ -786,10 +823,22 @@ The name of the service used for the ingress controller's validation webhook
|
||||
|
||||
{{/* effectiveVersion takes an image dict from values.yaml. if .effectiveSemver is set, it returns that, else it returns .tag */}}
|
||||
{{- define "kong.effectiveVersion" -}}
|
||||
{{- /* Because Kong Gateway enterprise uses versions with 4 segments and not 3 */ -}}
|
||||
{{- /* as semver does, we need to account for that here by extracting */ -}}
|
||||
{{- /* first 3 segments for comparison */ -}}
|
||||
{{- if .effectiveSemver -}}
|
||||
{{- .effectiveSemver -}}
|
||||
{{- if regexMatch "^[0-9]+.[0-9]+.[0-9]+" .effectiveSemver -}}
|
||||
{{- regexFind "^[0-9]+.[0-9]+.[0-9]+" .effectiveSemver -}}
|
||||
{{- else -}}
|
||||
{{- .effectiveSemver -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- (trimSuffix "-redhat" .tag) -}}
|
||||
{{- $tag := (trimSuffix "-redhat" .tag) -}}
|
||||
{{- if regexMatch "^[0-9]+.[0-9]+.[0-9]+" .tag -}}
|
||||
{{- regexFind "^[0-9]+.[0-9]+.[0-9]+" .tag -}}
|
||||
{{- else -}}
|
||||
{{- .tag -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -908,7 +957,7 @@ the template that it itself is using form the above sections.
|
||||
{{- end -}}
|
||||
{{- $listenConfig := dict -}}
|
||||
{{- $listenConfig := merge $listenConfig . -}}
|
||||
{{- $_ := set $listenConfig "address" $address -}}
|
||||
{{- $_ := set $listenConfig "address" (default $address .address) -}}
|
||||
{{- $_ := set $autoEnv "KONG_ADMIN_LISTEN" (include "kong.listen" $listenConfig) -}}
|
||||
|
||||
{{- if or .tls.client.secretName .tls.client.caBundle -}}
|
||||
@@ -952,6 +1001,7 @@ the template that it itself is using form the above sections.
|
||||
{{- end -}}
|
||||
|
||||
{{- if .Values.admin.ingress.enabled }}
|
||||
{{- $_ := set $autoEnv "KONG_ADMIN_GUI_API_URL" (include "kong.ingress.serviceUrl" .Values.admin.ingress) -}}
|
||||
{{- $_ := set $autoEnv "KONG_ADMIN_API_URI" (include "kong.ingress.serviceUrl" .Values.admin.ingress) -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -1203,6 +1253,24 @@ resource roles into their separate templates.
|
||||
- namespaces
|
||||
verbs:
|
||||
- list
|
||||
{{- if (semverCompare ">= 2.11.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }}
|
||||
- apiGroups:
|
||||
- configuration.konghq.com
|
||||
resources:
|
||||
- kongconsumergroups
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- configuration.konghq.com
|
||||
resources:
|
||||
- kongconsumergroups/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
{{- end }}
|
||||
{{- if (semverCompare "< 2.10.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }}
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -1614,6 +1682,16 @@ networking.k8s.io/v1beta1
|
||||
extensions/v1beta1
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "kong.proxy.compatibleReadiness" -}}
|
||||
{{- $proxyReadiness := .Values.readinessProbe -}}
|
||||
{{- if (or (semverCompare "< 3.3.0" (include "kong.effectiveVersion" .Values.image)) (and .Values.ingressController.enabled (semverCompare "< 2.11.0" (include "kong.effectiveVersion" .Values.ingressController.image)))) -}}
|
||||
{{- if (eq $proxyReadiness.httpGet.path "/status/ready") -}}
|
||||
{{- $_ := set $proxyReadiness.httpGet "path" "/status" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- (toYaml $proxyReadiness) -}}
|
||||
{{- end -}}
|
||||
{{/*
|
||||
appsec labels
|
||||
*/}}
|
||||
|
||||
@@ -46,6 +46,9 @@ webhooks:
|
||||
namespaceSelector:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ingressController.admissionWebhook.timeoutSeconds }}
|
||||
timeoutSeconds: {{ . }}
|
||||
{{- end }}
|
||||
objectSelector:
|
||||
matchExpressions:
|
||||
- key: owner
|
||||
@@ -80,6 +83,28 @@ webhooks:
|
||||
- UPDATE
|
||||
resources:
|
||||
- secrets
|
||||
{{- if (semverCompare ">= 2.12.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }}
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
apiVersions:
|
||||
- 'v1'
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- ingresses
|
||||
- apiGroups:
|
||||
- gateway.networking.k8s.io
|
||||
apiVersions:
|
||||
- 'v1alpha2'
|
||||
- 'v1beta1'
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- gateways
|
||||
- httproutes
|
||||
{{- end }}
|
||||
clientConfig:
|
||||
{{- if not .Values.ingressController.admissionWebhook.certificate.provided }}
|
||||
caBundle: {{ b64enc $caCert }}
|
||||
|
||||
@@ -359,7 +359,7 @@ spec:
|
||||
{{- include "kong.volumeMounts" . | nindent 10 }}
|
||||
{{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 10 }}
|
||||
readinessProbe:
|
||||
{{ toYaml .Values.readinessProbe | indent 10 }}
|
||||
{{ include "kong.proxy.compatibleReadiness" . | indent 10 }}
|
||||
livenessProbe:
|
||||
{{ toYaml .Values.livenessProbe | indent 10 }}
|
||||
{{- if .Values.startupProbe }}
|
||||
@@ -403,41 +403,6 @@ spec:
|
||||
{{- end }}
|
||||
{{- include "kong.volumes" . | nindent 8 -}}
|
||||
{{- include "kong.userDefinedVolumes" . | nindent 8 -}}
|
||||
{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }}
|
||||
- name: {{ template "kong.serviceAccountTokenName" . }}
|
||||
{{- /* Due to GKE versions (e.g. v1.23.15-gke.1900) we need to handle pre-release part of the version as well.
|
||||
See the related documentation of semver module that Helm depends on for semverCompare:
|
||||
https://github.com/Masterminds/semver#working-with-prerelease-versions
|
||||
Related Helm issue: https://github.com/helm/helm/issues/3810 */}}
|
||||
{{- if semverCompare ">=1.20.0-0" .Capabilities.KubeVersion.Version }}
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
expirationSeconds: 3607
|
||||
path: token
|
||||
- configMap:
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
name: kube-root-ca.crt
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
path: namespace
|
||||
{{- else }}
|
||||
secret:
|
||||
secretName: {{ template "kong.serviceAccountTokenName" . }}
|
||||
items:
|
||||
- key: token
|
||||
path: token
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
- key: namespace
|
||||
path: namespace
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if (and (eq .Values.kind "AppSecStateful") .Values.appsec.persistence.enabled) }}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
|
||||
@@ -270,7 +270,7 @@ spec:
|
||||
{{- include "kong.volumeMounts" . | nindent 10 }}
|
||||
{{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 10 }}
|
||||
readinessProbe:
|
||||
{{ toYaml .Values.readinessProbe | indent 10 }}
|
||||
{{ include "kong.proxy.compatibleReadiness" . | indent 10 }}
|
||||
livenessProbe:
|
||||
{{ toYaml .Values.livenessProbe | indent 10 }}
|
||||
{{- if .Values.startupProbe }}
|
||||
@@ -302,39 +302,4 @@ spec:
|
||||
volumes:
|
||||
{{- include "kong.volumes" . | nindent 8 -}}
|
||||
{{- include "kong.userDefinedVolumes" . | nindent 8 -}}
|
||||
{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }}
|
||||
- name: {{ template "kong.serviceAccountTokenName" . }}
|
||||
{{- /* Due to GKE versions (e.g. v1.23.15-gke.1900) we need to handle pre-release part of the version as well.
|
||||
See the related documentation of semver module that Helm depends on for semverCompare:
|
||||
https://github.com/Masterminds/semver#working-with-prerelease-versions
|
||||
Related Helm issue: https://github.com/helm/helm/issues/3810 */}}
|
||||
{{- if semverCompare ">=1.20.0-0" .Capabilities.KubeVersion.Version }}
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
expirationSeconds: 3607
|
||||
path: token
|
||||
- configMap:
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
name: kube-root-ca.crt
|
||||
- downwardAPI:
|
||||
items:
|
||||
- fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.namespace
|
||||
path: namespace
|
||||
{{- else }}
|
||||
secret:
|
||||
secretName: {{ template "kong.serviceAccountTokenName" . }}
|
||||
items:
|
||||
- key: token
|
||||
path: token
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
- key: namespace
|
||||
path: namespace
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -29,6 +29,9 @@ spec:
|
||||
{{- range $key, $value := .Values.migrations.annotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }}
|
||||
kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }}
|
||||
|
||||
@@ -13,6 +13,8 @@ metadata:
|
||||
annotations:
|
||||
helm.sh/hook: "pre-upgrade"
|
||||
helm.sh/hook-delete-policy: "before-hook-creation"
|
||||
argocd.argoproj.io/hook: Sync
|
||||
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
|
||||
{{- range $key, $value := .Values.migrations.jobAnnotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
@@ -29,6 +31,9 @@ spec:
|
||||
{{- range $key, $value := .Values.migrations.annotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }}
|
||||
kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }}
|
||||
|
||||
@@ -21,6 +21,8 @@ metadata:
|
||||
{{- include "kong.metaLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: init-migrations
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: Sync
|
||||
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
|
||||
{{- range $key, $value := .Values.migrations.jobAnnotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
@@ -37,6 +39,9 @@ spec:
|
||||
{{- range $key, $value := .Values.migrations.annotations }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }}
|
||||
kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{{- if .Values.deployment.kong.enabled }}
|
||||
{{- if .Values.enterprise.enabled }}
|
||||
{{- if and .Values.manager.enabled (or .Values.manager.http.enabled .Values.manager.tls.enabled) -}}
|
||||
{{- $serviceConfig := dict -}}
|
||||
{{- $serviceConfig := merge $serviceConfig .Values.manager -}}
|
||||
@@ -16,4 +15,3 @@
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -86,7 +86,7 @@ env:
|
||||
database: "off"
|
||||
# the chart uses the traditional router (for Kong 3.x+) because the ingress
|
||||
# controller generates traditional routes. if you do not use the controller,
|
||||
# you may set this to "traditional_compatible" or "expression" to use the new
|
||||
# you may set this to "traditional_compatible" or "expressions" to use the new
|
||||
# DSL-based router
|
||||
router_flavor: "traditional"
|
||||
nginx_worker_processes: "2"
|
||||
@@ -121,11 +121,13 @@ extraLabels: {}
|
||||
# Specify Kong's Docker image and repository details here
|
||||
image:
|
||||
repository: kong
|
||||
tag: "3.3"
|
||||
tag: "3.4"
|
||||
# Kong Enterprise
|
||||
# repository: kong/kong-gateway
|
||||
# tag: "3.3"
|
||||
# tag: "3.4"
|
||||
|
||||
# Specify a semver version if your image tag is not one (e.g. "nightly")
|
||||
effectiveSemver:
|
||||
pullPolicy: IfNotPresent
|
||||
## Optionally specify an array of imagePullSecrets.
|
||||
## Secrets must be manually created in the namespace.
|
||||
@@ -514,7 +516,7 @@ ingressController:
|
||||
enabled: true
|
||||
image:
|
||||
repository: kong/kubernetes-ingress-controller
|
||||
tag: "2.10"
|
||||
tag: "2.12"
|
||||
# Optionally set a semantic version for version-gated features. This can normally
|
||||
# be left unset. You only need to set this if your tag is not a semver string,
|
||||
# such as when you are using a "next" tag. Set this to the effective semantic
|
||||
@@ -574,6 +576,8 @@ ingressController:
|
||||
service:
|
||||
# Specify custom labels for the validation webhook service.
|
||||
labels: {}
|
||||
# Tune the default Kubernetes timeoutSeconds of 10 seconds
|
||||
# timeoutSeconds: 10
|
||||
|
||||
ingressClass: kong
|
||||
# annotations for IngressClass resource (Kubernetes 1.18+)
|
||||
@@ -800,7 +804,7 @@ resources: {}
|
||||
# readinessProbe for Kong pods
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: "/status"
|
||||
path: "/status/ready"
|
||||
port: status
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 5
|
||||
@@ -1229,8 +1233,8 @@ appsec:
|
||||
image:
|
||||
#registry:
|
||||
repository: ghcr.io/openappsec
|
||||
image: agent
|
||||
tag: latest
|
||||
image: "agent"
|
||||
tag: "1.1.0"
|
||||
pullPolicy: Always
|
||||
|
||||
securityContext:
|
||||
@@ -1243,8 +1247,8 @@ appsec:
|
||||
# runAsUser: 1000
|
||||
kong:
|
||||
image:
|
||||
repository: "ghcr.io/openappsec/kong-gateway-attachment"
|
||||
tag: "latest"
|
||||
repository: "ghcr.io/openappsec/kong-attachment"
|
||||
tag: "1.1.0"
|
||||
configMapName: appsec-settings-configmap
|
||||
configMapContent:
|
||||
crowdsec:
|
||||
|
||||
@@ -5,6 +5,7 @@ CROWDSEC_INSTALLATION_SCRIPT="install-cp-crowdsec-aux.sh"
|
||||
HTTP_TRANSACTION_HANDLER_SERVICE="install-cp-nano-service-http-transaction-handler.sh"
|
||||
ATTACHMENT_REGISTRATION_SERVICE="install-cp-nano-attachment-registration-manager.sh"
|
||||
ORCHESTRATION_INSTALLATION_SCRIPT="install-cp-nano-agent.sh"
|
||||
CACHE_INSTALLATION_SCRIPT="install-cp-nano-agent-cache.sh"
|
||||
|
||||
var_fog_address=
|
||||
var_proxy=
|
||||
@@ -63,6 +64,7 @@ if [ -f /var/run/secrets/kubernetes.io/serviceaccount/token ]; then
|
||||
fi
|
||||
|
||||
/nano-service-installers/$ATTACHMENT_REGISTRATION_SERVICE --install
|
||||
/nano-service-installers/$CACHE_INSTALLATION_SCRIPT --install
|
||||
/nano-service-installers/$HTTP_TRANSACTION_HANDLER_SERVICE --install
|
||||
|
||||
if [ ! -z $CROWDSEC_ENABLED ]; then
|
||||
|
||||
@@ -49,6 +49,8 @@ nginxIntakerEvent::resetAllCounters()
|
||||
req_proccessing_timeout = 0;
|
||||
res_proccessing_timeout = 0;
|
||||
req_failed_to_reach_upstream = 0;
|
||||
req_overall_size = 0;
|
||||
res_overall_size = 0;
|
||||
cpu_event.setCPU(0);
|
||||
}
|
||||
|
||||
@@ -249,10 +251,22 @@ nginxIntakerEvent::addPluginMetricCounter(const ngx_http_cp_metric_data_t *recie
|
||||
cpu_event.setCPU(amount);
|
||||
break;
|
||||
}
|
||||
case ngx_http_plugin_metric_type_e::REQUEST_OVERALL_SIZE_COUNT: {
|
||||
req_overall_size += amount;
|
||||
static const uint64_t max_expected_res_size = 100ULL * 1024 * 1024 * 1024;
|
||||
if (amount > max_expected_res_size) {
|
||||
dbgWarning(D_METRICS_NGINX_ATTACHMENT) << "Requests sizes higher than expected: " << amount;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ngx_http_plugin_metric_type_e::RESPONSE_OVERALL_SIZE_COUNT: {
|
||||
res_overall_size += amount;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dbgWarning(D_METRICS_NGINX_ATTACHMENT)
|
||||
<< "Unsupported metric type. Type: " << static_cast<int>(metric_type);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,6 +367,10 @@ nginxIntakerEvent::getPluginMetricCounter(ngx_http_plugin_metric_type_e metric_t
|
||||
return req_failed_to_reach_upstream;
|
||||
case ngx_http_plugin_metric_type_e::CPU_USAGE:
|
||||
return static_cast<uint64_t>(cpu_event.getCPU());
|
||||
case ngx_http_plugin_metric_type_e::REQUEST_OVERALL_SIZE_COUNT:
|
||||
return req_overall_size;
|
||||
case ngx_http_plugin_metric_type_e::RESPONSE_OVERALL_SIZE_COUNT:
|
||||
return res_overall_size;
|
||||
default:
|
||||
dbgWarning(D_METRICS_NGINX_ATTACHMENT)
|
||||
<< "Unsupported metric type. Type: " << static_cast<int>(metric_type);
|
||||
@@ -498,5 +516,11 @@ nginxIntakerMetric::upon(const nginxIntakerEvent &event)
|
||||
req_failed_to_reach_upstream.report(
|
||||
event.getPluginMetricCounter(ngx_http_plugin_metric_type_e::REQ_FAILED_TO_REACH_UPSTREAM)
|
||||
);
|
||||
req_overall_size.report(
|
||||
event.getPluginMetricCounter(ngx_http_plugin_metric_type_e::REQUEST_OVERALL_SIZE_COUNT)
|
||||
);
|
||||
res_overall_size.report(
|
||||
event.getPluginMetricCounter(ngx_http_plugin_metric_type_e::RESPONSE_OVERALL_SIZE_COUNT)
|
||||
);
|
||||
event.notifyCPU();
|
||||
}
|
||||
|
||||
@@ -224,5 +224,6 @@ private:
|
||||
};
|
||||
|
||||
static const ParameterBehavior action_ignore(BehaviorKey::ACTION, BehaviorValue::IGNORE);
|
||||
static const ParameterBehavior action_accept(BehaviorKey::ACTION, BehaviorValue::ACCEPT);
|
||||
|
||||
#endif //__PARAMETERS_CONFIG_H__
|
||||
|
||||
@@ -34,7 +34,6 @@ public:
|
||||
virtual const std::string & getUpdateTime() const = 0;
|
||||
virtual const std::string & getLastManifestUpdate() const = 0;
|
||||
virtual const std::string & getPolicyVersion() const = 0;
|
||||
virtual const std::string & getWaapModelVersion() const = 0;
|
||||
virtual const std::string & getLastPolicyUpdate() const = 0;
|
||||
virtual const std::string & getLastSettingsUpdate() const = 0;
|
||||
virtual const std::string & getUpgradeMode() const = 0;
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
virtual const std::string & getPolicyVersions() const = 0;
|
||||
virtual const std::string & getPolicyVersion() const = 0;
|
||||
virtual const std::string & getUpdatePolicyVersion() const = 0;
|
||||
virtual void updateReconfStatus(int id, ReconfStatus status) = 0;
|
||||
virtual void updateReconfStatus(int id, const std::string &service_name, ReconfStatus status) = 0;
|
||||
virtual void startReconfStatus(
|
||||
int id,
|
||||
ReconfStatus status,
|
||||
|
||||
@@ -19,13 +19,19 @@
|
||||
#include "i_mainloop.h"
|
||||
#include "i_local_policy_mgmt_gen.h"
|
||||
#include "i_env_details.h"
|
||||
#include "i_shell_cmd.h"
|
||||
#include "i_orchestration_tools.h"
|
||||
|
||||
class LocalPolicyMgmtGenerator
|
||||
:
|
||||
public Component,
|
||||
Singleton::Provide<I_LocalPolicyMgmtGen>,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_EnvDetails>
|
||||
Singleton::Consume<I_EnvDetails>,
|
||||
Singleton::Consume<I_ShellCmd>,
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_Messaging>
|
||||
{
|
||||
public:
|
||||
LocalPolicyMgmtGenerator();
|
||||
|
||||
@@ -81,6 +81,8 @@ private:
|
||||
uint64_t req_proccessing_timeout = 0;
|
||||
uint64_t res_proccessing_timeout = 0;
|
||||
uint64_t req_failed_to_reach_upstream = 0;
|
||||
uint64_t req_overall_size = 0;
|
||||
uint64_t res_overall_size = 0;
|
||||
CPUEvent cpu_event;
|
||||
};
|
||||
|
||||
@@ -140,6 +142,8 @@ private:
|
||||
Counter thread_failure{this, "attachmentThreadFailureSum"};
|
||||
Counter req_proccessing_timeout{this, "httpRequestProcessingReachedTimeoutSum"};
|
||||
Counter res_proccessing_timeout{this, "httpResponseProcessingReachedTimeoutSum"};
|
||||
Counter req_overall_size{this, "httpRequestsSizeSum"};
|
||||
Counter res_overall_size{this, "httpResponsesSizeSum"};
|
||||
Counter req_failed_to_reach_upstream{this, "httpRequestFailedToReachWebServerUpstreamSum"};
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "i_time_get.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "i_agent_details.h"
|
||||
#include "i_details_resolver.h"
|
||||
#include "customized_cereal_map.h"
|
||||
|
||||
class OrchestrationStatus
|
||||
@@ -33,7 +32,6 @@ class OrchestrationStatus
|
||||
Singleton::Provide<I_OrchestrationStatus>,
|
||||
Singleton::Consume<I_TimeGet>,
|
||||
Singleton::Consume<I_AgentDetails>,
|
||||
Singleton::Consume<I_DetailsResolver>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_MainLoop>
|
||||
{
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
#include "singleton.h"
|
||||
#include "i_mainloop.h"
|
||||
#include "i_environment.h"
|
||||
#include "i_generic_rulebase.h"
|
||||
|
||||
class RateLimit
|
||||
:
|
||||
public Component,
|
||||
Singleton::Consume<I_MainLoop>,
|
||||
Singleton::Consume<I_TimeGet>,
|
||||
Singleton::Consume<I_Environment>
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_GenericRulebase>
|
||||
{
|
||||
public:
|
||||
RateLimit();
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
#include "layer_7_access_control.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "config.h"
|
||||
#include "cache.h"
|
||||
#include "http_inspection_events.h"
|
||||
#include "http_transaction_common.h"
|
||||
#include "nginx_attachment_common.h"
|
||||
#include "intelligence_comp_v2.h"
|
||||
#include "intelligence_is_v2/intelligence_query_v2.h"
|
||||
#include "intelligence_is_v2/query_request_v2.h"
|
||||
#include "log_generator.h"
|
||||
|
||||
@@ -103,7 +101,7 @@ private:
|
||||
unsigned int crowdsec_event_id;
|
||||
};
|
||||
|
||||
class Layer7AccessControl::Impl : public Listener<HttpRequestHeaderEvent>
|
||||
class Layer7AccessControl::Impl : public Listener<HttpRequestHeaderEvent>, Listener<WaitTransactionEvent>
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
@@ -126,27 +124,25 @@ public:
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT;
|
||||
}
|
||||
|
||||
auto source_identifier = i_env->get<string>(HttpTransactionData::source_identifier);
|
||||
if (source_identifier.ok() && IPAddr::createIPAddr(source_identifier.unpack()).ok()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Found a valid source identifier value: " << source_identifier.unpack();
|
||||
return checkReputation(source_identifier.unpack());
|
||||
}
|
||||
return handleEvent();
|
||||
}
|
||||
|
||||
auto orig_source_ip = i_env->get<IPAddr>(HttpTransactionData::client_ip_ctx);
|
||||
if (!orig_source_ip.ok()) {
|
||||
dbgWarning(D_L7_ACCESS_CONTROL) << "Could not extract the Client IP address from context";
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
}
|
||||
EventVerdict
|
||||
respond(const WaitTransactionEvent &) override
|
||||
{
|
||||
dbgFlow(D_L7_ACCESS_CONTROL) << "Handling wait verdict";
|
||||
|
||||
stringstream ss_client_ip;
|
||||
ss_client_ip << orig_source_ip.unpack();
|
||||
return checkReputation(ss_client_ip.str());
|
||||
return handleEvent();
|
||||
}
|
||||
|
||||
private:
|
||||
void queryIntelligence();
|
||||
void scheduleIntelligenceQuery(const string &ip);
|
||||
void processIntelligenceResponse(const string &ip, const vector<AssetReply<IntelligenceIpReputation>> &response);
|
||||
Maybe<IntelligenceIpReputation> getIpReputation(const string &ip);
|
||||
ngx_http_cp_verdict_e checkReputation(const string &source_ip);
|
||||
void generateLog(const string &source_ip, const IntelligenceIpReputation &ip_reputation) const;
|
||||
EventVerdict generateLog(const string &source_ip, const IntelligenceIpReputation &ip_reputation) const;
|
||||
EventVerdict queryIpReputation(const string &source_ip);
|
||||
EventVerdict handleEvent();
|
||||
|
||||
bool isAppEnabled() const;
|
||||
bool isPrevent() const;
|
||||
@@ -154,9 +150,12 @@ private:
|
||||
Maybe<LogField, Context::Error> genLogField(const string &log_key, const string &env_key) const;
|
||||
Maybe<LogField, Context::Error> genLogIPField(const string &log_key, const string &env_key) const;
|
||||
|
||||
bool is_intelligence_routine_running = false;
|
||||
I_Environment *i_env = nullptr;
|
||||
I_Intelligence_IS_V2 *i_intelligence = nullptr;
|
||||
I_MainLoop *i_mainloop = nullptr;
|
||||
TemporaryCache<string, IntelligenceIpReputation> ip_reputation_cache;
|
||||
unordered_set<string> pending_ips;
|
||||
};
|
||||
|
||||
bool
|
||||
@@ -177,79 +176,139 @@ Layer7AccessControl::Impl::isPrevent() const
|
||||
return mode == "prevent";
|
||||
}
|
||||
|
||||
void
|
||||
Layer7AccessControl::Impl::scheduleIntelligenceQuery(const string &ip)
|
||||
{
|
||||
dbgFlow(D_L7_ACCESS_CONTROL) << "Scheduling intelligence query about reputation of IP: " << ip;
|
||||
|
||||
pending_ips.emplace(ip);
|
||||
|
||||
if (!is_intelligence_routine_running) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Starting intelligence routine";
|
||||
is_intelligence_routine_running = true;
|
||||
i_mainloop->addOneTimeRoutine(
|
||||
I_MainLoop::RoutineType::System,
|
||||
[&] () { queryIntelligence(); },
|
||||
"Check IP reputation"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<IntelligenceIpReputation>
|
||||
Layer7AccessControl::Impl::getIpReputation(const string &ip)
|
||||
{
|
||||
dbgFlow(D_L7_ACCESS_CONTROL) << "Getting reputation of IP " << ip;
|
||||
|
||||
if (ip_reputation_cache.doesKeyExists(ip)) return ip_reputation_cache.getEntry(ip);
|
||||
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Not found in cache - about to query intelligence";
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << ip << " reputation was not found in cache";
|
||||
|
||||
QueryRequest request = QueryRequest(
|
||||
Condition::EQUALS,
|
||||
"ipv4Addresses",
|
||||
ip,
|
||||
true,
|
||||
AttributeKeyType::REGULAR
|
||||
);
|
||||
|
||||
auto response = i_intelligence->queryIntelligence<IntelligenceIpReputation>(request);
|
||||
|
||||
if (!response.ok()) {
|
||||
dbgWarning(D_L7_ACCESS_CONTROL) << "Failed to query intelligence about reputation of IP: " << ip;
|
||||
return genError("Failed to query intelligence");
|
||||
}
|
||||
|
||||
auto &unpacked_response = response.unpack();
|
||||
if (unpacked_response.empty()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Intelligence reputation response collection is empty. IP is clean.";
|
||||
return IntelligenceIpReputation();
|
||||
}
|
||||
|
||||
for (const auto &intelligence_reply : unpacked_response) {
|
||||
if (intelligence_reply.getAssetType() == crowdsec_asset_type && !intelligence_reply.getData().empty()){
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << intelligence_reply.getData().front();
|
||||
return intelligence_reply.getData().front();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return IntelligenceIpReputation();
|
||||
return genError("Intelligence needed");
|
||||
}
|
||||
|
||||
ngx_http_cp_verdict_e
|
||||
Layer7AccessControl::Impl::checkReputation(const string &source_ip)
|
||||
EventVerdict
|
||||
Layer7AccessControl::Impl::queryIpReputation(const string &source_ip)
|
||||
{
|
||||
auto ip_reputation = getIpReputation(source_ip);
|
||||
if (!ip_reputation.ok()) {
|
||||
dbgWarning(D_L7_ACCESS_CONTROL) << "Could not query intelligence. Retruning default verdict";
|
||||
bool is_drop_by_default = getProfileAgentSettingWithDefault<bool>(false, "layer7AccessControl.dropByDefault");
|
||||
if (!(is_drop_by_default && isPrevent())) return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
generateLog(source_ip, IntelligenceIpReputation());
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Scheduling Intelligence query - returning Wait verdict";
|
||||
scheduleIntelligenceQuery(source_ip);
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_WAIT;
|
||||
}
|
||||
|
||||
if (!ip_reputation.unpack().isMalicious()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Accepting IP: " << source_ip;
|
||||
ip_reputation_cache.deleteEntry(source_ip);
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
}
|
||||
|
||||
ip_reputation_cache.emplaceEntry(source_ip, ip_reputation.unpack());
|
||||
return generateLog(source_ip, ip_reputation.unpack());
|
||||
}
|
||||
|
||||
if (isPrevent()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Dropping IP: " << source_ip;
|
||||
generateLog(source_ip, ip_reputation.unpack());
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||
EventVerdict
|
||||
Layer7AccessControl::Impl::handleEvent()
|
||||
{
|
||||
auto source_identifier = i_env->get<string>(HttpTransactionData::source_identifier);
|
||||
if (source_identifier.ok() && IPAddr::createIPAddr(source_identifier.unpack()).ok()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Found a valid source identifier value: " << source_identifier.unpack();
|
||||
return queryIpReputation(source_identifier.unpack());
|
||||
}
|
||||
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Detecting IP: " << source_ip;
|
||||
generateLog(source_ip, ip_reputation.unpack());
|
||||
auto orig_source_ip = i_env->get<IPAddr>(HttpTransactionData::client_ip_ctx);
|
||||
if (orig_source_ip.ok()) {
|
||||
stringstream ss_client_ip;
|
||||
ss_client_ip << orig_source_ip.unpack();
|
||||
return queryIpReputation(ss_client_ip.str());
|
||||
}
|
||||
|
||||
dbgWarning(D_L7_ACCESS_CONTROL) << "Could not extract the Client IP address from context";
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
}
|
||||
|
||||
void
|
||||
Layer7AccessControl::Impl::processIntelligenceResponse(
|
||||
const string &ip,
|
||||
const vector<AssetReply<IntelligenceIpReputation>> &response)
|
||||
{
|
||||
if (response.empty()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Intelligence reputation response collection is empty. IP is clean.";
|
||||
ip_reputation_cache.emplaceEntry(ip, IntelligenceIpReputation());
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &intelligence_reply : response) {
|
||||
if (intelligence_reply.getAssetType() == crowdsec_asset_type && !intelligence_reply.getData().empty()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << intelligence_reply.getData().front();
|
||||
ip_reputation_cache.emplaceEntry(ip, intelligence_reply.getData().front());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Could not find a matching intelligence asset type for IP: " << ip;
|
||||
ip_reputation_cache.emplaceEntry(ip, IntelligenceIpReputation());
|
||||
}
|
||||
|
||||
void
|
||||
Layer7AccessControl::Impl::queryIntelligence()
|
||||
{
|
||||
dbgFlow(D_L7_ACCESS_CONTROL) << "Started IP reputation intelligence routine";
|
||||
|
||||
while (!pending_ips.empty()) {
|
||||
i_mainloop->yield();
|
||||
|
||||
auto ip = *(pending_ips.begin());
|
||||
pending_ips.erase(pending_ips.begin());
|
||||
|
||||
if (ip_reputation_cache.doesKeyExists(ip)) continue;
|
||||
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Querying intelligence about reputation of IP: " << ip;
|
||||
|
||||
QueryRequest request = QueryRequest(
|
||||
Condition::EQUALS,
|
||||
"ipv4Addresses",
|
||||
ip,
|
||||
true,
|
||||
AttributeKeyType::REGULAR
|
||||
);
|
||||
|
||||
auto response = i_intelligence->queryIntelligence<IntelligenceIpReputation>(request);
|
||||
|
||||
if (!response.ok()) {
|
||||
dbgWarning(D_L7_ACCESS_CONTROL)
|
||||
<< "Failed to query intelligence about reputation of IP: "
|
||||
<< ip
|
||||
<< ", error: "
|
||||
<< response.getErr();
|
||||
ip_reputation_cache.emplaceEntry(ip, IntelligenceIpReputation());
|
||||
continue;
|
||||
}
|
||||
|
||||
processIntelligenceResponse(ip, response.unpack());
|
||||
}
|
||||
|
||||
is_intelligence_routine_running = false;
|
||||
}
|
||||
|
||||
EventVerdict
|
||||
Layer7AccessControl::Impl::generateLog(const string &source_ip, const IntelligenceIpReputation &ip_reputation) const
|
||||
{
|
||||
dbgFlow(D_L7_ACCESS_CONTROL) << "About to generate Layer-7 Access Control log";
|
||||
@@ -287,6 +346,14 @@ Layer7AccessControl::Impl::generateLog(const string &source_ip, const Intelligen
|
||||
<< ip_reputation.getOrigin()
|
||||
<< ip_reputation.getIpv4Address()
|
||||
<< ip_reputation.getScenario();
|
||||
|
||||
if (isPrevent()) {
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Dropping IP: " << source_ip;
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||
}
|
||||
|
||||
dbgTrace(D_L7_ACCESS_CONTROL) << "Detecting IP: " << source_ip;
|
||||
return ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
}
|
||||
|
||||
Maybe<LogField, Context::Error>
|
||||
@@ -315,6 +382,7 @@ Layer7AccessControl::Impl::init()
|
||||
registerListener();
|
||||
i_env = Singleton::Consume<I_Environment>::by<Layer7AccessControl>();
|
||||
i_intelligence = Singleton::Consume<I_Intelligence_IS_V2>::by<Layer7AccessControl>();
|
||||
i_mainloop = Singleton::Consume<I_MainLoop>::by<Layer7AccessControl>();
|
||||
|
||||
chrono::minutes expiration(
|
||||
getProfileAgentSettingWithDefault<uint>(60u, "layer7AccessControl.crowdsec.cacheExpiration")
|
||||
@@ -322,7 +390,7 @@ Layer7AccessControl::Impl::init()
|
||||
|
||||
ip_reputation_cache.startExpiration(
|
||||
expiration,
|
||||
Singleton::Consume<I_MainLoop>::by<Layer7AccessControl>(),
|
||||
i_mainloop,
|
||||
Singleton::Consume<I_TimeGet>::by<Layer7AccessControl>()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public:
|
||||
const EventVerdict drop_verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_DROP;
|
||||
const EventVerdict accept_verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_ACCEPT;
|
||||
const EventVerdict inspect_verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_INSPECT;
|
||||
const EventVerdict wait_verdict = ngx_http_cp_verdict_e::TRAFFIC_VERDICT_WAIT;
|
||||
Layer7AccessControl l7_access_control;
|
||||
::Environment env;
|
||||
ConfigComponent config;
|
||||
@@ -62,6 +63,7 @@ public:
|
||||
NiceMock<MockRestApi> mock_rest;
|
||||
AgentDetails agent_details;
|
||||
IntelligenceComponentV2 intelligence_comp;
|
||||
I_MainLoop::Routine query_intelligence_routine;
|
||||
Context ctx;
|
||||
};
|
||||
|
||||
@@ -273,6 +275,13 @@ TEST_F(Layer7AccessControlTest, ReturnAcceptVerdict)
|
||||
const HttpHeader header2{ Buffer("date"), Buffer("Sun, 26 Mar 2023 18:45:22 GMT"), 1 };
|
||||
const HttpHeader header3{ Buffer("x-forwarded-for"), Buffer("1.2.3.4"), 2, true};
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(_, _, "Check IP reputation", _))
|
||||
.WillOnce(DoAll(SaveArg<1>(&query_intelligence_routine), Return(0))
|
||||
);
|
||||
EXPECT_CALL(mock_ml, yield(A<bool>())).Times(1);
|
||||
|
||||
EXPECT_THAT(
|
||||
HttpRequestHeaderEvent(header1).performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", inspect_verdict))
|
||||
@@ -283,6 +292,13 @@ TEST_F(Layer7AccessControlTest, ReturnAcceptVerdict)
|
||||
);
|
||||
EXPECT_THAT(
|
||||
HttpRequestHeaderEvent(header3).performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", wait_verdict))
|
||||
);
|
||||
|
||||
query_intelligence_routine();
|
||||
|
||||
EXPECT_THAT(
|
||||
WaitTransactionEvent().performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", accept_verdict))
|
||||
);
|
||||
}
|
||||
@@ -299,6 +315,13 @@ TEST_F(Layer7AccessControlTest, ReturnDropVerdictOnMaliciousReputation)
|
||||
sendMessage(true, _, _, _, _, _, _, MessageTypeTag::INTELLIGENCE)
|
||||
).WillOnce(Return(malicious_intelligence_response));
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(_, _, "Check IP reputation", _))
|
||||
.WillOnce(DoAll(SaveArg<1>(&query_intelligence_routine), Return(0))
|
||||
);
|
||||
EXPECT_CALL(mock_ml, yield(A<bool>())).Times(1);
|
||||
|
||||
registerTransactionData();
|
||||
ctx.registerValue<string>(HttpTransactionData::source_identifier, "1.2.3.4");
|
||||
const HttpHeader header1{ Buffer("Content-Type"), Buffer("application/json"), 0 };
|
||||
@@ -310,7 +333,18 @@ TEST_F(Layer7AccessControlTest, ReturnDropVerdictOnMaliciousReputation)
|
||||
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header1).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header2).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header3).query(), ElementsAre(drop_verdict));
|
||||
|
||||
EXPECT_THAT(
|
||||
HttpRequestHeaderEvent(header3).performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", wait_verdict))
|
||||
);
|
||||
|
||||
query_intelligence_routine();
|
||||
|
||||
EXPECT_THAT(
|
||||
WaitTransactionEvent().performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", drop_verdict))
|
||||
);
|
||||
|
||||
verifyReport(report, "1.2.3.4", "Prevent");
|
||||
}
|
||||
@@ -327,6 +361,13 @@ TEST_F(Layer7AccessControlTest, ReturnDropVerdictCacheBased)
|
||||
sendMessage(true, _, _, _, _, _, _, MessageTypeTag::INTELLIGENCE)
|
||||
).WillOnce(Return(malicious_intelligence_response));
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(_, _, "Check IP reputation", _))
|
||||
.WillOnce(DoAll(SaveArg<1>(&query_intelligence_routine), Return(0))
|
||||
);
|
||||
EXPECT_CALL(mock_ml, yield(A<bool>())).Times(1);
|
||||
|
||||
registerTransactionData();
|
||||
ctx.registerValue<string>(HttpTransactionData::source_identifier, "1.2.3.4");
|
||||
const HttpHeader header1{ Buffer("Content-Type"), Buffer("application/json"), 0 };
|
||||
@@ -338,7 +379,18 @@ TEST_F(Layer7AccessControlTest, ReturnDropVerdictCacheBased)
|
||||
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header1).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header2).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header3).query(), ElementsAre(drop_verdict));
|
||||
|
||||
EXPECT_THAT(
|
||||
HttpRequestHeaderEvent(header3).performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", wait_verdict))
|
||||
);
|
||||
|
||||
query_intelligence_routine();
|
||||
|
||||
EXPECT_THAT(
|
||||
WaitTransactionEvent().performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", drop_verdict))
|
||||
);
|
||||
|
||||
verifyReport(report, "1.2.3.4", "Prevent");
|
||||
|
||||
@@ -361,6 +413,13 @@ TEST_F(Layer7AccessControlTest, AcceptOnDetect)
|
||||
sendMessage(true, _, _, _, _, _, _, MessageTypeTag::INTELLIGENCE)
|
||||
).WillOnce(Return(malicious_intelligence_response));
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(_, _, "Check IP reputation", _))
|
||||
.WillOnce(DoAll(SaveArg<1>(&query_intelligence_routine), Return(0))
|
||||
);
|
||||
EXPECT_CALL(mock_ml, yield(A<bool>())).Times(1);
|
||||
|
||||
registerTransactionData();
|
||||
ctx.registerValue<string>(HttpTransactionData::source_identifier, "1.2.3.4");
|
||||
const HttpHeader header1{ Buffer("Content-Type"), Buffer("application/json"), 0 };
|
||||
@@ -372,7 +431,18 @@ TEST_F(Layer7AccessControlTest, AcceptOnDetect)
|
||||
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header1).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header2).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header3).query(), ElementsAre(accept_verdict));
|
||||
|
||||
EXPECT_THAT(
|
||||
HttpRequestHeaderEvent(header3).performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", wait_verdict))
|
||||
);
|
||||
|
||||
query_intelligence_routine();
|
||||
|
||||
EXPECT_THAT(
|
||||
WaitTransactionEvent().performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", accept_verdict))
|
||||
);
|
||||
|
||||
verifyReport(report, "1.2.3.4", "Detect");
|
||||
}
|
||||
@@ -389,6 +459,13 @@ TEST_F(Layer7AccessControlTest, FallbackToSourceIPAndDrop)
|
||||
sendMessage(true, _, _, _, _, _, _, MessageTypeTag::INTELLIGENCE)
|
||||
).WillOnce(Return(malicious_intelligence_response));
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_ml,
|
||||
addOneTimeRoutine(_, _, "Check IP reputation", _))
|
||||
.WillOnce(DoAll(SaveArg<1>(&query_intelligence_routine), Return(0))
|
||||
);
|
||||
EXPECT_CALL(mock_ml, yield(A<bool>())).Times(1);
|
||||
|
||||
registerTransactionData();
|
||||
const HttpHeader header1{ Buffer("Content-Type"), Buffer("application/json"), 0 };
|
||||
const HttpHeader header2{ Buffer("date"), Buffer("Sun, 26 Mar 2023 18:45:22 GMT"), 1, true };
|
||||
@@ -397,7 +474,18 @@ TEST_F(Layer7AccessControlTest, FallbackToSourceIPAndDrop)
|
||||
EXPECT_CALL(mock_logging, sendLog(_)).WillOnce(SaveArg<0>(&report));
|
||||
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header1).query(), ElementsAre(inspect_verdict));
|
||||
EXPECT_THAT(HttpRequestHeaderEvent(header2).query(), ElementsAre(drop_verdict));
|
||||
|
||||
EXPECT_THAT(
|
||||
HttpRequestHeaderEvent(header2).performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", wait_verdict))
|
||||
);
|
||||
|
||||
query_intelligence_routine();
|
||||
|
||||
EXPECT_THAT(
|
||||
WaitTransactionEvent().performNamedQuery(),
|
||||
ElementsAre(Pair("Layer-7 Access Control app", drop_verdict))
|
||||
);
|
||||
|
||||
verifyReport(report, "", "Prevent");
|
||||
}
|
||||
|
||||
@@ -20,4 +20,5 @@ add_library(local_policy_mgmt_gen
|
||||
new_exceptions.cc
|
||||
access_control_practice.cc
|
||||
configmaps.cc
|
||||
reverse_proxy_section.cc
|
||||
)
|
||||
|
||||
@@ -316,7 +316,7 @@ TriggersInWaapSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
}
|
||||
|
||||
ParsedMatch::ParsedMatch(const string &_operator, const string &_tag, const string &_value)
|
||||
:
|
||||
:
|
||||
operator_type(_operator),
|
||||
tag(_tag),
|
||||
value(_value)
|
||||
@@ -368,7 +368,7 @@ AppSecOverride::AppSecOverride(const SourcesIdentifiers &parsed_trusted_sources)
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
AppSecOverride::AppSecOverride(const InnerException &parsed_exceptions)
|
||||
:
|
||||
:
|
||||
id(parsed_exceptions.getBehaviorId()),
|
||||
parsed_match(parsed_exceptions.getMatch())
|
||||
{
|
||||
@@ -413,7 +413,7 @@ WebAppSection::WebAppSection(
|
||||
const string &default_mode,
|
||||
const AppSecTrustedSources &parsed_trusted_sources,
|
||||
const vector<InnerException> &parsed_exceptions)
|
||||
:
|
||||
:
|
||||
application_urls(_application_urls),
|
||||
asset_id(_asset_id),
|
||||
asset_name(_asset_name),
|
||||
@@ -460,7 +460,7 @@ WebAppSection::WebAppSection(
|
||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||
const LogTriggerSection &parsed_log_trigger,
|
||||
const AppSecTrustedSources &parsed_trusted_sources)
|
||||
:
|
||||
:
|
||||
application_urls(_application_urls),
|
||||
asset_id(_asset_id),
|
||||
asset_name(_asset_name),
|
||||
@@ -477,6 +477,7 @@ WebAppSection::WebAppSection(
|
||||
{
|
||||
web_attack_mitigation = true;
|
||||
web_attack_mitigation_action =
|
||||
web_attack_mitigation_mode != "Prevent" ? "Transparent" :
|
||||
web_attack_mitigation_severity == "critical" ? "low" :
|
||||
web_attack_mitigation_severity == "high" ? "balanced" :
|
||||
web_attack_mitigation_severity == "medium" ? "high" :
|
||||
@@ -584,6 +585,9 @@ ParsedRule::load(cereal::JSONInputArchive &archive_in)
|
||||
parseAppsecJSONKey<string>("custom-response", custom_response, archive_in);
|
||||
parseAppsecJSONKey<string>("source-identifiers", source_identifiers, archive_in);
|
||||
parseAppsecJSONKey<string>("trusted-sources", trusted_sources, archive_in);
|
||||
parseAppsecJSONKey<string>("upstream", rpm_upstream, archive_in);
|
||||
parseAppsecJSONKey<string>("rp-settings", rpm_settings, archive_in);
|
||||
parseAppsecJSONKey<bool>("ssl", rpm_is_ssl, archive_in);
|
||||
try {
|
||||
archive_in(cereal::make_nvp("host", host));
|
||||
} catch (const cereal::Exception &e)
|
||||
@@ -620,6 +624,24 @@ ParsedRule::getMode() const
|
||||
return mode;
|
||||
}
|
||||
|
||||
const string &
|
||||
ParsedRule::rpmGetUpstream() const
|
||||
{
|
||||
return rpm_upstream;
|
||||
}
|
||||
|
||||
const std::string &
|
||||
ParsedRule::rpmGetRPSettings() const
|
||||
{
|
||||
return rpm_settings;
|
||||
}
|
||||
|
||||
bool
|
||||
ParsedRule::rpmIsHttps() const
|
||||
{
|
||||
return rpm_is_ssl;
|
||||
}
|
||||
|
||||
void
|
||||
ParsedRule::setHost(const string &_host)
|
||||
{
|
||||
@@ -691,6 +713,7 @@ AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading Appsec Linux Policy";
|
||||
parseAppsecJSONKey<AppsecPolicySpec>("policies", policies, archive_in);
|
||||
parseAppsecJSONKey<vector<RPMSettings>>("rp-settings", rpm_settings, archive_in);
|
||||
parseAppsecJSONKey<vector<AppSecPracticeSpec>>("practices", practices, archive_in);
|
||||
parseAppsecJSONKey<vector<AppsecTriggerSpec>>("log-triggers", log_triggers, archive_in);
|
||||
parseAppsecJSONKey<vector<AppSecCustomResponseSpec>>("custom-responses", custom_responses, archive_in);
|
||||
@@ -745,6 +768,13 @@ AppsecLinuxPolicy::getAppsecSourceIdentifierSpecs() const
|
||||
return sources_identifiers;
|
||||
}
|
||||
|
||||
|
||||
const vector<RPMSettings> &
|
||||
AppsecLinuxPolicy::rpmGetRPSettings() const
|
||||
{
|
||||
return rpm_settings;
|
||||
}
|
||||
|
||||
void
|
||||
AppsecLinuxPolicy::addSpecificRule(const ParsedRule &_rule)
|
||||
{
|
||||
|
||||
@@ -304,11 +304,13 @@ ExceptionMatch::getMatch() const
|
||||
ExceptionBehavior::ExceptionBehavior(const string &_value)
|
||||
{
|
||||
key = _value == "suppressLog" ? "log" : "action";
|
||||
value = key_to_action.at(_value);
|
||||
try {
|
||||
value = key_to_action.at(_value);
|
||||
id = to_string(boost::uuids::random_generator()());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate exception behavior UUID. Error: " << e.what();
|
||||
} catch (std::exception &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to find exception name: " << _value << ". Error: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "triggers_section.h"
|
||||
#include "exceptions_section.h"
|
||||
#include "trusted_sources_section.h"
|
||||
#include "reverse_proxy_section.h"
|
||||
#include "new_practice.h"
|
||||
|
||||
class AppSecWebBotsURI
|
||||
@@ -148,7 +149,7 @@ public:
|
||||
PracticeAdvancedConfig() {}
|
||||
|
||||
PracticeAdvancedConfig(const AppSecPracticeSpec &parsed_appsec_spec)
|
||||
:
|
||||
:
|
||||
http_header_max_size(parsed_appsec_spec.getWebAttacks().getMaxHeaderSizeBytes()),
|
||||
http_illegal_methods_allowed(0),
|
||||
http_request_body_max_size(parsed_appsec_spec.getWebAttacks().getMaxBodySizeKb()),
|
||||
@@ -162,7 +163,7 @@ public:
|
||||
int _http_request_body_max_size,
|
||||
int _json_max_object_depth,
|
||||
int _url_max_size)
|
||||
:
|
||||
:
|
||||
http_header_max_size(_http_header_max_size),
|
||||
http_illegal_methods_allowed(0),
|
||||
http_request_body_max_size(_http_request_body_max_size),
|
||||
@@ -186,7 +187,7 @@ class TriggersInWaapSection
|
||||
{
|
||||
public:
|
||||
TriggersInWaapSection(const LogTriggerSection &log_section)
|
||||
:
|
||||
:
|
||||
trigger_type("log"),
|
||||
id(log_section.getTriggerId()),
|
||||
name(log_section.getTriggerName()),
|
||||
@@ -241,13 +242,13 @@ public:
|
||||
AppsecPracticeAntiBotSection(const NewAppSecPracticeAntiBot &anti_bot) :
|
||||
injected_uris(anti_bot.getIjectedUris()),
|
||||
validated_uris(anti_bot.getValidatedUris())
|
||||
{};
|
||||
{};
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
AppsecPracticeAntiBotSection(const AppSecPracticeAntiBot &anti_bot) :
|
||||
injected_uris(anti_bot.getIjectedUris()),
|
||||
validated_uris(anti_bot.getValidatedUris())
|
||||
{};
|
||||
{};
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
@@ -278,20 +279,20 @@ public:
|
||||
);
|
||||
|
||||
WebAppSection(
|
||||
const std::string &_application_urls,
|
||||
const std::string &_asset_id,
|
||||
const std::string &_asset_name,
|
||||
const std::string &_rule_id,
|
||||
const std::string &_rule_name,
|
||||
const std::string &_practice_id,
|
||||
const std::string &_practice_name,
|
||||
const std::string &_context,
|
||||
const std::string &_web_attack_mitigation_severity,
|
||||
const std::string &_web_attack_mitigation_mode,
|
||||
const PracticeAdvancedConfig &_practice_advanced_config,
|
||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||
const LogTriggerSection &parsed_log_trigger,
|
||||
const AppSecTrustedSources &parsed_trusted_sources);
|
||||
const std::string &_application_urls,
|
||||
const std::string &_asset_id,
|
||||
const std::string &_asset_name,
|
||||
const std::string &_rule_id,
|
||||
const std::string &_rule_name,
|
||||
const std::string &_practice_id,
|
||||
const std::string &_practice_name,
|
||||
const std::string &_context,
|
||||
const std::string &_web_attack_mitigation_severity,
|
||||
const std::string &_web_attack_mitigation_mode,
|
||||
const PracticeAdvancedConfig &_practice_advanced_config,
|
||||
const AppsecPracticeAntiBotSection &_anti_bots,
|
||||
const LogTriggerSection &parsed_log_trigger,
|
||||
const AppSecTrustedSources &parsed_trusted_sources);
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
@@ -331,7 +332,7 @@ public:
|
||||
const std::string &_web_attack_mitigation_mode,
|
||||
bool _web_attack_mitigation,
|
||||
const PracticeAdvancedConfig &_practice_advanced_config)
|
||||
:
|
||||
:
|
||||
application_urls(_application_urls),
|
||||
asset_id(_asset_id),
|
||||
asset_name(_asset_name),
|
||||
@@ -345,7 +346,7 @@ public:
|
||||
web_attack_mitigation_mode(_web_attack_mitigation_mode),
|
||||
web_attack_mitigation(_web_attack_mitigation),
|
||||
practice_advanced_config(_practice_advanced_config)
|
||||
{}
|
||||
{}
|
||||
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
@@ -371,7 +372,7 @@ public:
|
||||
AppSecRulebase(
|
||||
std::vector<WebAppSection> _webApplicationPractices,
|
||||
std::vector<WebAPISection> _webAPIPractices)
|
||||
:
|
||||
:
|
||||
webApplicationPractices(_webApplicationPractices),
|
||||
webAPIPractices(_webAPIPractices) {}
|
||||
|
||||
@@ -387,7 +388,7 @@ class AppSecWrapper
|
||||
{
|
||||
public:
|
||||
AppSecWrapper(const AppSecRulebase &_app_sec)
|
||||
:
|
||||
:
|
||||
app_sec_rulebase(_app_sec)
|
||||
{}
|
||||
|
||||
@@ -409,6 +410,9 @@ public:
|
||||
const std::vector<std::string> & getPractices() const;
|
||||
const std::string & getHost() const;
|
||||
const std::string & getMode() const;
|
||||
const std::string &rpmGetUpstream() const;
|
||||
const std::string &rpmGetRPSettings() const;
|
||||
bool rpmIsHttps() const;
|
||||
void setHost(const std::string &_host);
|
||||
void setMode(const std::string &_mode);
|
||||
const std::string & getCustomResponse() const;
|
||||
@@ -424,6 +428,9 @@ private:
|
||||
std::string custom_response;
|
||||
std::string source_identifiers;
|
||||
std::string trusted_sources;
|
||||
std::string rpm_upstream;
|
||||
std::string rpm_settings;
|
||||
bool rpm_is_ssl = false;
|
||||
};
|
||||
|
||||
class AppsecPolicySpec : Singleton::Consume<I_Environment>
|
||||
@@ -453,7 +460,7 @@ public:
|
||||
const std::vector<AppsecException> &_exceptions,
|
||||
const std::vector<TrustedSourcesSpec> &_trusted_sources,
|
||||
const std::vector<SourceIdentifierSpecWrapper> &_sources_identifiers)
|
||||
:
|
||||
:
|
||||
policies(_policies),
|
||||
practices(_practices),
|
||||
log_triggers(_log_triggers),
|
||||
@@ -471,6 +478,7 @@ public:
|
||||
const std::vector<AppsecException> & getAppsecExceptions() const;
|
||||
const std::vector<TrustedSourcesSpec> & getAppsecTrustedSourceSpecs() const;
|
||||
const std::vector<SourceIdentifierSpecWrapper> & getAppsecSourceIdentifierSpecs() const;
|
||||
const std::vector<RPMSettings> &rpmGetRPSettings() const;
|
||||
void addSpecificRule(const ParsedRule &_rule);
|
||||
|
||||
private:
|
||||
@@ -481,6 +489,7 @@ private:
|
||||
std::vector<AppsecException> exceptions;
|
||||
std::vector<TrustedSourcesSpec> trusted_sources;
|
||||
std::vector<SourceIdentifierSpecWrapper> sources_identifiers;
|
||||
std::vector<RPMSettings> rpm_settings;
|
||||
};
|
||||
|
||||
#endif // __APPSEC_PRACTICE_SECTION_H__
|
||||
|
||||
@@ -50,7 +50,7 @@ static const std::unordered_map<std::string, TriggerType> string_to_trigger_type
|
||||
|
||||
static const std::unordered_map<std::string, std::string> key_to_practices_val = {
|
||||
{ "prevent-learn", "Prevent"},
|
||||
{ "detect-learn", "Detect"},
|
||||
{ "detect-learn", "Learn"},
|
||||
{ "prevent", "Prevent"},
|
||||
{ "detect", "Detect"},
|
||||
{ "inactive", "Inactive"}
|
||||
@@ -70,9 +70,9 @@ parseAppsecJSONKey(
|
||||
archive_in.setNextName(nullptr);
|
||||
value = default_value;
|
||||
dbgDebug(D_LOCAL_POLICY)
|
||||
<< "Could not parse the required key. Key: "
|
||||
<< "Could not parse the required key. Key: \""
|
||||
<< key_name
|
||||
<< ", Error: "
|
||||
<< "\", Error: "
|
||||
<< e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
trusted_sources(_trusted_sources),
|
||||
sources_identifiers(_sources_identifiers) {}
|
||||
// LCOV_EXCL_STOP
|
||||
void serialize(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const NewAppsecPolicySpec & getAppsecPolicySpec() const;
|
||||
const std::vector<NewAppSecPracticeSpec> & getAppSecPracticeSpecs() const;
|
||||
|
||||
@@ -147,8 +147,8 @@ public:
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
FileSecurityProtectionsSection(
|
||||
int _file_size_limit,
|
||||
int _archive_file_size_limit,
|
||||
uint64_t _file_size_limit,
|
||||
uint64_t _archive_file_size_limit,
|
||||
bool _allow_files_without_name,
|
||||
bool _required_file_size_limit,
|
||||
bool _required_archive_extraction,
|
||||
@@ -171,8 +171,8 @@ public:
|
||||
void save(cereal::JSONOutputArchive &out_ar) const;
|
||||
|
||||
private:
|
||||
int file_size_limit;
|
||||
int archive_file_size_limit;
|
||||
uint64_t file_size_limit;
|
||||
uint64_t archive_file_size_limit;
|
||||
bool allow_files_without_name;
|
||||
bool required_file_size_limit;
|
||||
bool required_archive_extraction;
|
||||
@@ -233,13 +233,13 @@ class NewFileSecurityArchiveInspection
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getArchiveFileSizeLimit() const;
|
||||
uint64_t getArchiveFileSizeLimit() const;
|
||||
bool getrequiredArchiveExtraction() const;
|
||||
const std::string & getMultiLevelArchiveAction() const;
|
||||
const std::string & getUnopenedArchiveAction() const;
|
||||
|
||||
private:
|
||||
int scan_max_file_size;
|
||||
uint64_t scan_max_file_size;
|
||||
bool extract_archive_files;
|
||||
std::string scan_max_file_size_unit;
|
||||
std::string archived_files_within_archived_files;
|
||||
@@ -251,11 +251,11 @@ class NewFileSecurityLargeFileInspection
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
int getFileSizeLimit() const;
|
||||
uint64_t getFileSizeLimit() const;
|
||||
const std::string & getFileSizeLimitAction() const;
|
||||
|
||||
private:
|
||||
int file_size_limit;
|
||||
uint64_t file_size_limit;
|
||||
std::string file_size_limit_unit;
|
||||
std::string files_exceeding_size_limit_action;
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "trusted_sources_section.h"
|
||||
#include "new_appsec_linux_policy.h"
|
||||
#include "access_control_practice.h"
|
||||
#include "reverse_proxy_section.h"
|
||||
|
||||
enum class AnnotationTypes {
|
||||
PRACTICE,
|
||||
@@ -109,11 +110,6 @@ private:
|
||||
};
|
||||
|
||||
class PolicyMakerUtils
|
||||
:
|
||||
Singleton::Consume<I_Environment>,
|
||||
Singleton::Consume<I_OrchestrationTools>,
|
||||
Singleton::Consume<I_Messaging>,
|
||||
Singleton::Consume<I_ShellCmd>
|
||||
{
|
||||
public:
|
||||
std::string proccesSingleAppsecPolicy(
|
||||
@@ -206,6 +202,7 @@ private:
|
||||
createThreatPreventionPracticeSections(
|
||||
const std::string &asset_name,
|
||||
const std::string &url,
|
||||
const std::string &port,
|
||||
const std::string &uri,
|
||||
const std::string &default_mode,
|
||||
const V1beta2AppsecLinuxPolicy &policy,
|
||||
@@ -231,6 +228,11 @@ private:
|
||||
template<class T, class R>
|
||||
void createAgentPolicyFromAppsecPolicy(const std::string &policy_name, const T &appsec_policy);
|
||||
|
||||
void rpmBuildNginxServers(const AppsecLinuxPolicy &policy);
|
||||
void rpmReportInfo(const std::string &msg);
|
||||
void rpmReportError(const std::string &msg);
|
||||
|
||||
std::string policy_version_name;
|
||||
std::map<std::string, LogTriggerSection> log_triggers;
|
||||
std::map<std::string, WebUserResponseTriggerSection> web_user_res_triggers;
|
||||
std::map<std::string, std::vector<InnerException>> inner_exceptions;
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __REVERSE_PROXY_SECTION_H__
|
||||
#define __REVERSE_PROXY_SECTION_H__
|
||||
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "agent_core_utilities.h"
|
||||
#include "i_shell_cmd.h"
|
||||
|
||||
class ParsedRule;
|
||||
|
||||
class RPMSettings
|
||||
{
|
||||
public:
|
||||
void load(cereal::JSONInputArchive &archive_in);
|
||||
|
||||
const std::string & getName() const;
|
||||
std::string applySettings(const std::string &server_content) const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string host_hdr = "$host";
|
||||
std::string dns_resolver = "127.0.0.11";
|
||||
};
|
||||
|
||||
class ReverseProxyBuilder
|
||||
{
|
||||
public:
|
||||
static void init();
|
||||
|
||||
static Maybe<void> addNginxServerLocation(
|
||||
std::string location,
|
||||
const std::string &host,
|
||||
const ParsedRule &rule,
|
||||
const RPMSettings &rp_settings);
|
||||
|
||||
static Maybe<void> createNewNginxServer(
|
||||
const std::string &host,
|
||||
const ParsedRule &rule,
|
||||
const RPMSettings &rp_settings);
|
||||
|
||||
static std::string replaceTemplate(
|
||||
const std::string &content,
|
||||
const boost::regex &nginx_directive_template,
|
||||
const std::string &value);
|
||||
|
||||
static Maybe<void> reloadNginx();
|
||||
|
||||
private:
|
||||
static Maybe<void> createSSLNginxServer(const std::string &host, const RPMSettings &rp_settings);
|
||||
static Maybe<void> createHTTPNginxServer(const std::string &host, const RPMSettings &rp_settings);
|
||||
|
||||
static Maybe<std::string> getTemplateContent(const std::string &nginx_template_name);
|
||||
};
|
||||
#endif // __REVERSE_PROXY_SECTION_H__
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
RulesConfigRulebase(
|
||||
const std::string &_name,
|
||||
const std::string &_url,
|
||||
const std::string &_port,
|
||||
const std::string &_uri,
|
||||
std::vector<PracticeSection> _practices,
|
||||
std::vector<ParametersSection> _parameters,
|
||||
|
||||
@@ -55,9 +55,7 @@ const static string default_local_mgmt_policy_path = "/conf/local_policy.yaml";
|
||||
|
||||
class LocalPolicyMgmtGenerator::Impl
|
||||
:
|
||||
public Singleton::Provide<I_LocalPolicyMgmtGen>::From<LocalPolicyMgmtGenerator>,
|
||||
public Singleton::Consume<I_MainLoop>,
|
||||
public Singleton::Consume<I_EnvDetails>
|
||||
public Singleton::Provide<I_LocalPolicyMgmtGen>::From<LocalPolicyMgmtGenerator>
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -111,7 +109,6 @@ public:
|
||||
|
||||
private:
|
||||
PolicyMakerUtils policy_maker_utils;
|
||||
|
||||
};
|
||||
|
||||
LocalPolicyMgmtGenerator::LocalPolicyMgmtGenerator()
|
||||
|
||||
@@ -70,3 +70,31 @@ V1beta2AppsecLinuxPolicy::addSpecificRule(const NewParsedRule &_rule)
|
||||
policies.addSpecificRule(_rule);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
void
|
||||
V1beta2AppsecLinuxPolicy::serialize(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgInfo(D_LOCAL_POLICY) << "Loading Appsec V1Beta2 Linux Policy";
|
||||
|
||||
// Check for the presence of "apiVersion" key, present only from V1Beta2
|
||||
string api_version;
|
||||
archive_in(cereal::make_nvp("apiVersion", api_version));
|
||||
if (api_version != "v1beta2") throw cereal::Exception("Failed to parse JSON as v1Beta2 version");
|
||||
|
||||
parseAppsecJSONKey<NewAppsecPolicySpec>("policies", policies, archive_in);
|
||||
parseAppsecJSONKey<vector<NewAppSecPracticeSpec>>(
|
||||
"threatPreventionPractices",
|
||||
threat_prevection_practices,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<vector<AccessControlPracticeSpec>>(
|
||||
"accessControlPractices",
|
||||
access_control_practices,
|
||||
archive_in
|
||||
);
|
||||
parseAppsecJSONKey<vector<NewAppsecLogTrigger>>("logTriggers", log_triggers, archive_in);
|
||||
parseAppsecJSONKey<vector<NewAppSecCustomResponse>>("customResponse", custom_responses, archive_in);
|
||||
parseAppsecJSONKey<vector<NewAppsecException>>("exceptions", exceptions, archive_in);
|
||||
parseAppsecJSONKey<vector<NewTrustedSourcesSpec>>("trustedSources", trusted_sources, archive_in);
|
||||
parseAppsecJSONKey<vector<NewSourcesIdentifiers>>("sourcesIdentifiers", sources_identifiers, archive_in);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ void
|
||||
NewAppsecException::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading New AppSec exception";
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
parseAppsecJSONKey<string>("name", name, archive_in, "exception");
|
||||
parseAppsecJSONKey<string>("action", action, archive_in);
|
||||
parseAppsecJSONKey<string>("appsecClassName", appsec_class_name, archive_in);
|
||||
if (valid_actions.count(action) == 0) {
|
||||
|
||||
@@ -42,7 +42,7 @@ static const std::unordered_map<std::string, std::string> key_to_mode_val = {
|
||||
{ "detect", "Detect"},
|
||||
{ "inactive", "Inactive"}
|
||||
};
|
||||
static const std::unordered_map<std::string, int> unit_to_int = {
|
||||
static const std::unordered_map<std::string, uint64_t> unit_to_int = {
|
||||
{ "bytes", 1},
|
||||
{ "KB", 1024},
|
||||
{ "MB", 1048576},
|
||||
@@ -631,8 +631,8 @@ NewIntrusionPrevention::getMode() const
|
||||
}
|
||||
|
||||
FileSecurityProtectionsSection::FileSecurityProtectionsSection(
|
||||
int _file_size_limit,
|
||||
int _archive_file_size_limit,
|
||||
uint64_t _file_size_limit,
|
||||
uint64_t _archive_file_size_limit,
|
||||
bool _allow_files_without_name,
|
||||
bool _required_file_size_limit,
|
||||
bool _required_archive_extraction,
|
||||
@@ -720,7 +720,7 @@ NewFileSecurityArchiveInspection::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security Archive Inspection practice";
|
||||
parseAppsecJSONKey<bool>("extractArchiveFiles", extract_archive_files, archive_in);
|
||||
parseAppsecJSONKey<int>("scanMaxFileSize", scan_max_file_size, archive_in, 0);
|
||||
parseAppsecJSONKey<uint64_t>("scanMaxFileSize", scan_max_file_size, archive_in, 0);
|
||||
parseAppsecJSONKey<string>("scanMaxFileSizeUnit", scan_max_file_size_unit, archive_in, "bytes");
|
||||
if (size_unit.count(scan_max_file_size_unit) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
@@ -749,7 +749,7 @@ NewFileSecurityArchiveInspection::load(cereal::JSONInputArchive &archive_in)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
uint64_t
|
||||
NewFileSecurityArchiveInspection::getArchiveFileSizeLimit() const
|
||||
{
|
||||
if (unit_to_int.find(scan_max_file_size_unit) == unit_to_int.end()) {
|
||||
@@ -784,7 +784,7 @@ void
|
||||
NewFileSecurityLargeFileInspection::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading AppSec File Security large File Inspection practice";
|
||||
parseAppsecJSONKey<int>("fileSizeLimit", file_size_limit, archive_in);
|
||||
parseAppsecJSONKey<uint64_t>("fileSizeLimit", file_size_limit, archive_in);
|
||||
parseAppsecJSONKey<string>("fileSizeLimitUnit", file_size_limit_unit, archive_in, "bytes");
|
||||
if (size_unit.count(file_size_limit_unit) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY)
|
||||
@@ -803,7 +803,7 @@ NewFileSecurityLargeFileInspection::load(cereal::JSONInputArchive &archive_in)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
uint64_t
|
||||
NewFileSecurityLargeFileInspection::getFileSizeLimit() const
|
||||
{
|
||||
if (unit_to_int.find(file_size_limit_unit) == unit_to_int.end()) {
|
||||
|
||||
@@ -64,7 +64,7 @@ void
|
||||
Identifier::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Loading source identifiers spec";
|
||||
parseAppsecJSONKey<string>("sourceIdentifier", identifier, archive_in);
|
||||
parseAppsecJSONKey<string>("identifier", identifier, archive_in);
|
||||
if (valid_identifiers.count(identifier) == 0) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "AppSec identifier invalid: " << identifier;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
|
||||
#include "policy_maker_utils.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
#include "local_policy_mgmt_gen.h"
|
||||
#include "log_generator.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_NGINX_POLICY);
|
||||
@@ -58,7 +63,7 @@ template<class T>
|
||||
Maybe<T>
|
||||
PolicyMakerUtils::openFileAsJson(const string &path)
|
||||
{
|
||||
auto maybe_file_as_json = Singleton::Consume<I_ShellCmd>::by<PolicyMakerUtils>()->getExecOutput(
|
||||
auto maybe_file_as_json = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator>()->getExecOutput(
|
||||
getFilesystemPathConfig() + "/bin/yq " + path + " -o json"
|
||||
);
|
||||
|
||||
@@ -67,7 +72,7 @@ PolicyMakerUtils::openFileAsJson(const string &path)
|
||||
return genError("Could not convert policy from yaml to json. Error: " + maybe_file_as_json.getErr());
|
||||
}
|
||||
|
||||
auto i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<PolicyMakerUtils>();
|
||||
auto i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<LocalPolicyMgmtGenerator>();
|
||||
auto maybe_file = i_orchestration_tools->jsonStringToObject<T>(
|
||||
maybe_file_as_json.unpack()
|
||||
);
|
||||
@@ -136,10 +141,11 @@ PolicyMakerUtils::splitHostName(const string &host_name)
|
||||
url = url.substr(0, url.find(":"));
|
||||
}
|
||||
|
||||
if (host_name == "*") {
|
||||
if (host_name == "*" || host_name == "*:*") {
|
||||
url = "Any";
|
||||
uri = "Any";
|
||||
}
|
||||
|
||||
return make_tuple(url, port, uri);
|
||||
}
|
||||
|
||||
@@ -323,6 +329,7 @@ extractAnnotationsNames<NewParsedRule>(
|
||||
if (!trusted_sources_annotation_name.empty()) {
|
||||
rule_annotation[AnnotationTypes::TRUSTED_SOURCES] = policy_name + "/" + trusted_sources_annotation_name;
|
||||
}
|
||||
|
||||
return rule_annotation;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
@@ -451,6 +458,23 @@ getAppsecCustomResponseSpec(const string &custom_response_annotation_name, const
|
||||
return *custom_response_it;
|
||||
}
|
||||
|
||||
template<class T, class R>
|
||||
R
|
||||
rpmGetAppsecRPSettingSpec(const string &rp_settings_name, const T &policy)
|
||||
{
|
||||
auto rp_settings_vec = policy.rpmGetRPSettings();
|
||||
auto rp_settings_it = extractElement(
|
||||
rp_settings_vec.begin(),
|
||||
rp_settings_vec.end(),
|
||||
rp_settings_name);
|
||||
|
||||
if (rp_settings_it == rp_settings_vec.end()) {
|
||||
dbgTrace(D_NGINX_POLICY) << "Failed to retrieve AppSec RP Settings";
|
||||
return R();
|
||||
}
|
||||
return *rp_settings_it;
|
||||
}
|
||||
|
||||
template<class T, class R>
|
||||
R
|
||||
getAppsecSourceIdentifierSpecs(const string &source_identifiers_annotation_name, const T &policy)
|
||||
@@ -843,6 +867,7 @@ createUserIdentifiers<V1beta2AppsecLinuxPolicy>(
|
||||
RulesConfigRulebase
|
||||
createMultiRulesSections(
|
||||
const string &url,
|
||||
const string &port,
|
||||
const string &uri,
|
||||
const string &practice_id,
|
||||
const string &practice_name,
|
||||
@@ -878,6 +903,7 @@ createMultiRulesSections(
|
||||
RulesConfigRulebase rules_config = RulesConfigRulebase(
|
||||
asset_name,
|
||||
url,
|
||||
port,
|
||||
uri,
|
||||
{practice},
|
||||
exceptions_result,
|
||||
@@ -890,6 +916,7 @@ createMultiRulesSections(
|
||||
RulesConfigRulebase
|
||||
createMultiRulesSections(
|
||||
const string &url,
|
||||
const string &port,
|
||||
const string &uri,
|
||||
const string &practice_id,
|
||||
const string &practice_name,
|
||||
@@ -907,7 +934,8 @@ createMultiRulesSections(
|
||||
const string &exception_name,
|
||||
const vector<InnerException> &exceptions)
|
||||
{
|
||||
ParametersSection exception_param = ParametersSection(exceptions[0].getBehaviorId(), exception_name);
|
||||
string behaviorId = exceptions.empty() ? "" : exceptions[0].getBehaviorId();
|
||||
ParametersSection exception_param = ParametersSection(behaviorId, exception_name);
|
||||
|
||||
vector<PracticeSection> practices;
|
||||
if (!practice_id.empty()) {
|
||||
@@ -934,6 +962,7 @@ createMultiRulesSections(
|
||||
RulesConfigRulebase rules_config = RulesConfigRulebase(
|
||||
asset_name,
|
||||
url,
|
||||
port,
|
||||
uri,
|
||||
practices,
|
||||
{exception_param},
|
||||
@@ -983,7 +1012,7 @@ PolicyMakerUtils::createSnortProtecionsSection(const string &file_name, const st
|
||||
auto snort_scriipt_path = getFilesystemPathConfig() + "/scripts/snort_to_ips_local.py";
|
||||
auto cmd = "python " + snort_scriipt_path + " " + path + ".rule " + path + ".out " + path + ".err";
|
||||
|
||||
auto res = Singleton::Consume<I_ShellCmd>::by<PolicyMakerUtils>()->getExecOutput(cmd);
|
||||
auto res = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator>()->getExecOutput(cmd);
|
||||
|
||||
if (!res.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY) << res.getErr();
|
||||
@@ -996,7 +1025,7 @@ PolicyMakerUtils::createSnortProtecionsSection(const string &file_name, const st
|
||||
return;
|
||||
}
|
||||
|
||||
auto i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<PolicyMakerUtils>();
|
||||
auto i_orchestration_tools = Singleton::Consume<I_OrchestrationTools>::by<LocalPolicyMgmtGenerator>();
|
||||
i_orchestration_tools->removeFile(path + ".rule");
|
||||
i_orchestration_tools->removeFile(path + ".out");
|
||||
i_orchestration_tools->removeFile(path + ".err");
|
||||
@@ -1153,12 +1182,15 @@ void
|
||||
PolicyMakerUtils::createThreatPreventionPracticeSections(
|
||||
const string &asset_name,
|
||||
const string &url,
|
||||
const string &port,
|
||||
const string &uri,
|
||||
const string &default_mode,
|
||||
const V1beta2AppsecLinuxPolicy &policy,
|
||||
map<AnnotationTypes, string> &rule_annotations)
|
||||
{
|
||||
if (rule_annotations[AnnotationTypes::PRACTICE].empty()) {
|
||||
if (rule_annotations[AnnotationTypes::PRACTICE].empty() ||
|
||||
web_apps.count(asset_name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
string practice_id = "";
|
||||
@@ -1170,6 +1202,7 @@ PolicyMakerUtils::createThreatPreventionPracticeSections(
|
||||
|
||||
RulesConfigRulebase rule_config = createMultiRulesSections(
|
||||
url,
|
||||
port,
|
||||
uri,
|
||||
practice_id,
|
||||
rule_annotations[AnnotationTypes::PRACTICE],
|
||||
@@ -1353,7 +1386,14 @@ PolicyMakerUtils::createPolicyElementsByRule(
|
||||
);
|
||||
}
|
||||
|
||||
if (!rule_annotations[AnnotationTypes::PRACTICE].empty()) {
|
||||
string full_url = rule.getHost() == "*" || rule.getHost() == "*:*"
|
||||
? "Any"
|
||||
: rule.getHost();
|
||||
|
||||
|
||||
if (!rule_annotations[AnnotationTypes::PRACTICE].empty() &&
|
||||
!web_apps.count(full_url)
|
||||
) {
|
||||
string practice_id = "";
|
||||
try {
|
||||
practice_id = to_string(boost::uuids::random_generator()());
|
||||
@@ -1362,12 +1402,10 @@ PolicyMakerUtils::createPolicyElementsByRule(
|
||||
}
|
||||
|
||||
tuple<string, string, string> splited_host_name = splitHostName(rule.getHost());
|
||||
string full_url = rule.getHost() == "*"
|
||||
? "Any"
|
||||
: rule.getHost();
|
||||
|
||||
RulesConfigRulebase rule_config = createMultiRulesSections(
|
||||
std::get<0>(splited_host_name),
|
||||
std::get<1>(splited_host_name),
|
||||
std::get<2>(splited_host_name),
|
||||
practice_id,
|
||||
rule_annotations[AnnotationTypes::PRACTICE],
|
||||
@@ -1426,7 +1464,9 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
dbgTrace(D_LOCAL_POLICY) << "Creating policy elements from version V1beta2";
|
||||
map<AnnotationTypes, string> rule_annotations =
|
||||
extractAnnotationsNames<NewParsedRule>(rule, default_rule, policy_name);
|
||||
|
||||
if (
|
||||
rule_annotations.count(AnnotationTypes::TRIGGER) > 0 &&
|
||||
!rule_annotations[AnnotationTypes::TRIGGER].empty() &&
|
||||
!log_triggers.count(rule_annotations[AnnotationTypes::TRIGGER])
|
||||
) {
|
||||
@@ -1438,6 +1478,7 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
}
|
||||
|
||||
if (
|
||||
rule_annotations.count(AnnotationTypes::WEB_USER_RES) > 0 &&
|
||||
!rule_annotations[AnnotationTypes::WEB_USER_RES].empty() &&
|
||||
!web_user_res_triggers.count(rule_annotations[AnnotationTypes::WEB_USER_RES])
|
||||
) {
|
||||
@@ -1449,6 +1490,7 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
}
|
||||
|
||||
if (
|
||||
rule_annotations.count(AnnotationTypes::EXCEPTION) > 0 &&
|
||||
!rule_annotations[AnnotationTypes::EXCEPTION].empty() &&
|
||||
!inner_exceptions.count(rule_annotations[AnnotationTypes::EXCEPTION])
|
||||
) {
|
||||
@@ -1460,6 +1502,8 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
}
|
||||
|
||||
if (
|
||||
rule_annotations.count(AnnotationTypes::TRUSTED_SOURCES) > 0 &&
|
||||
rule_annotations.count(AnnotationTypes::SOURCE_IDENTIFIERS) > 0 &&
|
||||
!rule_annotations[AnnotationTypes::TRUSTED_SOURCES].empty() &&
|
||||
!rule_annotations[AnnotationTypes::SOURCE_IDENTIFIERS].empty() &&
|
||||
!trusted_sources.count(rule_annotations[AnnotationTypes::TRUSTED_SOURCES])
|
||||
@@ -1473,6 +1517,7 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
}
|
||||
|
||||
if (
|
||||
rule_annotations.count(AnnotationTypes::PRACTICE) > 0 &&
|
||||
!rule_annotations[AnnotationTypes::PRACTICE].empty() &&
|
||||
!web_apps.count(rule_annotations[AnnotationTypes::PRACTICE])
|
||||
) {
|
||||
@@ -1484,7 +1529,7 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
);
|
||||
}
|
||||
|
||||
string full_url = rule.getHost() == "*"
|
||||
string full_url = rule.getHost() == "*" || rule.getHost() == "*:*"
|
||||
? "Any"
|
||||
: rule.getHost();
|
||||
tuple<string, string, string> splited_host_name = splitHostName(rule.getHost());
|
||||
@@ -1501,6 +1546,7 @@ PolicyMakerUtils::createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsed
|
||||
createThreatPreventionPracticeSections(
|
||||
full_url,
|
||||
std::get<0>(splited_host_name),
|
||||
std::get<1>(splited_host_name),
|
||||
std::get<2>(splited_host_name),
|
||||
rule.getMode(),
|
||||
policy,
|
||||
@@ -1531,11 +1577,11 @@ PolicyMakerUtils::createAgentPolicyFromAppsecPolicy(const string &policy_name, c
|
||||
|
||||
R default_rule = appsec_policy.getAppsecPolicySpec().getDefaultRule();
|
||||
|
||||
// add default rule to policy
|
||||
createPolicyElementsByRule<T, R>(default_rule, default_rule, appsec_policy, policy_name);
|
||||
|
||||
vector<R> specific_rules = appsec_policy.getAppsecPolicySpec().getSpecificRules();
|
||||
createPolicyElements<T, R>(specific_rules, default_rule, appsec_policy, policy_name);
|
||||
|
||||
// add default rule to policy
|
||||
createPolicyElementsByRule<T, R>(default_rule, default_rule, appsec_policy, policy_name);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: no test exist
|
||||
@@ -1545,17 +1591,10 @@ PolicyMakerUtils::createAgentPolicyFromAppsecPolicy<V1beta2AppsecLinuxPolicy, Ne
|
||||
const string &policy_name,
|
||||
const V1beta2AppsecLinuxPolicy &appsec_policy)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Proccesing policy, name: " << policy_name;
|
||||
dbgTrace(D_LOCAL_POLICY) << "Proccesing v1beta2 policy, name: " << policy_name;
|
||||
|
||||
NewParsedRule default_rule = appsec_policy.getAppsecPolicySpec().getDefaultRule();
|
||||
|
||||
// add default rule to policy
|
||||
createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsedRule>(
|
||||
default_rule,
|
||||
default_rule,
|
||||
appsec_policy,
|
||||
policy_name);
|
||||
|
||||
vector<NewParsedRule> specific_rules = appsec_policy.getAppsecPolicySpec().getSpecificRules();
|
||||
createPolicyElements<V1beta2AppsecLinuxPolicy, NewParsedRule>(
|
||||
specific_rules,
|
||||
@@ -1563,6 +1602,13 @@ PolicyMakerUtils::createAgentPolicyFromAppsecPolicy<V1beta2AppsecLinuxPolicy, Ne
|
||||
appsec_policy,
|
||||
policy_name
|
||||
);
|
||||
|
||||
// add default rule to policy
|
||||
createPolicyElementsByRule<V1beta2AppsecLinuxPolicy, NewParsedRule>(
|
||||
default_rule,
|
||||
default_rule,
|
||||
appsec_policy,
|
||||
policy_name);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
@@ -1572,15 +1618,31 @@ PolicyMakerUtils::proccesSingleAppsecPolicy(
|
||||
const string &policy_version,
|
||||
const string &local_appsec_policy_path)
|
||||
{
|
||||
Maybe<AppsecLinuxPolicy> maybe_policy = openFileAsJson<AppsecLinuxPolicy>(policy_path);
|
||||
if (!maybe_policy.ok()){
|
||||
dbgWarning(D_LOCAL_POLICY) << maybe_policy.getErr();
|
||||
return "";
|
||||
|
||||
Maybe<V1beta2AppsecLinuxPolicy> maybe_policy_v1beta2 = openFileAsJson<V1beta2AppsecLinuxPolicy>(policy_path);
|
||||
if (maybe_policy_v1beta2.ok()) {
|
||||
policy_version_name = "v1beta2";
|
||||
createAgentPolicyFromAppsecPolicy<V1beta2AppsecLinuxPolicy, NewParsedRule>(
|
||||
getPolicyName(policy_path),
|
||||
maybe_policy_v1beta2.unpack()
|
||||
);
|
||||
} else {
|
||||
policy_version_name = "v1beta1";
|
||||
dbgInfo(D_LOCAL_POLICY)
|
||||
<< "Failed to retrieve AppSec local policy with version: v1beta2, Trying version: v1beta1";
|
||||
|
||||
Maybe<AppsecLinuxPolicy> maybe_policy_v1beta1 = openFileAsJson<AppsecLinuxPolicy>(policy_path);
|
||||
if (!maybe_policy_v1beta1.ok()){
|
||||
dbgWarning(D_LOCAL_POLICY) << maybe_policy_v1beta1.getErr();
|
||||
return "";
|
||||
}
|
||||
createAgentPolicyFromAppsecPolicy<AppsecLinuxPolicy, ParsedRule>(
|
||||
getPolicyName(policy_path),
|
||||
maybe_policy_v1beta1.unpack()
|
||||
);
|
||||
|
||||
if (getenv("OPENAPPSEC_STANDALONE")) rpmBuildNginxServers(maybe_policy_v1beta1.unpack());
|
||||
}
|
||||
createAgentPolicyFromAppsecPolicy<AppsecLinuxPolicy, ParsedRule>(
|
||||
getPolicyName(policy_path),
|
||||
maybe_policy.unpack()
|
||||
);
|
||||
|
||||
PolicyWrapper policy_wrapper = combineElementsToPolicy(policy_version);
|
||||
return dumpPolicyToFile(
|
||||
@@ -1588,3 +1650,114 @@ PolicyMakerUtils::proccesSingleAppsecPolicy(
|
||||
local_appsec_policy_path
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
PolicyMakerUtils::rpmReportInfo(const std::string &msg)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << msg;
|
||||
|
||||
LogGen(
|
||||
msg,
|
||||
ReportIS::Audience::SECURITY,
|
||||
ReportIS::Severity::INFO,
|
||||
ReportIS::Priority::LOW,
|
||||
ReportIS::Tags::ORCHESTRATOR
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
PolicyMakerUtils::rpmReportError(const std::string &msg)
|
||||
{
|
||||
dbgWarning(D_LOCAL_POLICY) << msg;
|
||||
|
||||
LogGen(
|
||||
msg,
|
||||
ReportIS::Audience::SECURITY,
|
||||
ReportIS::Severity::CRITICAL,
|
||||
ReportIS::Priority::URGENT,
|
||||
ReportIS::Tags::ORCHESTRATOR
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
PolicyMakerUtils::rpmBuildNginxServers(const AppsecLinuxPolicy &policy)
|
||||
{
|
||||
rpmReportInfo("Started building NGINX servers");
|
||||
|
||||
ReverseProxyBuilder::init();
|
||||
bool full_success = true;
|
||||
bool partial_success = false;
|
||||
set<pair<string, bool>> processed_rules;
|
||||
for (ParsedRule const &rule : policy.getAppsecPolicySpec().getSpecificRules()) {
|
||||
tuple<string, string, string> splited_host_name = splitHostName(rule.getHost());
|
||||
string host = std::get<0>(splited_host_name);
|
||||
if (host.empty() || rule.rpmGetUpstream().empty()) continue;
|
||||
|
||||
string location = std::get<2>(splited_host_name);
|
||||
if (location.empty()) location = "/";
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY)
|
||||
<< "Building NGINX server: "
|
||||
<< host
|
||||
<< ", location: "
|
||||
<< location
|
||||
<< " RP-Settings: "
|
||||
<< rule.rpmGetRPSettings();
|
||||
|
||||
RPMSettings rp_settings =
|
||||
rpmGetAppsecRPSettingSpec<AppsecLinuxPolicy, RPMSettings>(rule.rpmGetRPSettings(), policy);
|
||||
pair<string, bool> server = {host, rule.rpmIsHttps()};
|
||||
auto it = processed_rules.find(server);
|
||||
if (it != processed_rules.end()) {
|
||||
auto maybe_res = ReverseProxyBuilder::addNginxServerLocation(location, host, rule, rp_settings);
|
||||
if (!maybe_res.ok()) {
|
||||
rpmReportError(
|
||||
"Could not add an NGINX server location: " + location + " to server: " + host +
|
||||
", error: " + maybe_res.getErr()
|
||||
);
|
||||
full_success = false;
|
||||
continue;
|
||||
}
|
||||
rpmReportInfo("NGINX server location: " + location + " was successfully added to server: " + host);
|
||||
partial_success = true;
|
||||
} else {
|
||||
auto maybe_res = ReverseProxyBuilder::createNewNginxServer(host, rule, rp_settings);
|
||||
if (!maybe_res.ok()) {
|
||||
rpmReportError("Could not create a new NGINX server: " + host + ", error: " + maybe_res.getErr());
|
||||
full_success = false;
|
||||
continue;
|
||||
}
|
||||
rpmReportInfo(
|
||||
(rule.rpmIsHttps() ? string("SSL") : string("HTTP")) + " NGINX server: " + host +
|
||||
" was successfully built"
|
||||
);
|
||||
processed_rules.insert(server);
|
||||
|
||||
maybe_res = ReverseProxyBuilder::addNginxServerLocation(location, host, rule, rp_settings);
|
||||
if (!maybe_res.ok()) {
|
||||
rpmReportError(
|
||||
"Could not add an NGINX server location: " + location + " to server: " + host +
|
||||
", error: " + maybe_res.getErr()
|
||||
);
|
||||
full_success = false;
|
||||
continue;
|
||||
}
|
||||
rpmReportInfo("NGINX server location: " + location + " was successfully added to server: " + host);
|
||||
partial_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto maybe_reload_nginx = ReverseProxyBuilder::reloadNginx();
|
||||
if (!maybe_reload_nginx.ok()) {
|
||||
rpmReportError("Could not reload NGINX, error: " + maybe_reload_nginx.getErr());
|
||||
return;
|
||||
}
|
||||
|
||||
if (full_success) {
|
||||
rpmReportInfo("NGINX configuration was loaded successfully!");
|
||||
} else if (partial_success) {
|
||||
rpmReportInfo("NGINX configuration was partially loaded");
|
||||
} else {
|
||||
rpmReportError("Could not load any NGINX configuration");
|
||||
}
|
||||
}
|
||||
|
||||
456
components/security_apps/local_policy_mgmt_gen/reverse_proxy_section.cc
Executable file
456
components/security_apps/local_policy_mgmt_gen/reverse_proxy_section.cc
Executable file
@@ -0,0 +1,456 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "reverse_proxy_section.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <fstream>
|
||||
|
||||
#include "local_policy_mgmt_gen.h"
|
||||
#include "local_policy_common.h"
|
||||
#include "appsec_practice_section.h"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_LOCAL_POLICY);
|
||||
|
||||
static string conf_base_path = "/etc/cp/conf/";
|
||||
static string certs_path = "/etc/certs/";
|
||||
static string nginx_templates_path = "/etc/nginx/nginx-templates/";
|
||||
static const string nginx_configuration_path = "openappsec-nginx-servers/";
|
||||
static const string nginx_http_server_template = "nginx-http-server";
|
||||
static const string nginx_ssl_server_template = "nginx-ssl-server";
|
||||
static const string nginx_location_template = "nginx-location-block";
|
||||
|
||||
static const boost::regex host_template("<host>");
|
||||
static const boost::regex private_key_template("<private-key>");
|
||||
static const boost::regex certificate_template("<certificate>");
|
||||
static const boost::regex location_template("<location>");
|
||||
static const boost::regex upstream_template("<upstream>");
|
||||
static const boost::regex host_header_template("<host-header>");
|
||||
static const boost::regex dns_resolver_template("<dns-resolver>");
|
||||
|
||||
class ReverseProxyCertUtils
|
||||
{
|
||||
public:
|
||||
static std::pair<std::string, std::string> findMatchingCertificate(const std::string &host);
|
||||
static void init();
|
||||
|
||||
private:
|
||||
static std::vector<std::string> getFilesByExtension(const std::string &extension);
|
||||
static void untarCertificatesPackages();
|
||||
|
||||
static Maybe<std::string> extractModulus(const std::string &path, const std::string &type);
|
||||
|
||||
static std::unordered_map<std::string, std::string>
|
||||
calculatePublicModulus(const std::vector<std::string> &certs);
|
||||
|
||||
static std::unordered_map<std::string, std::string>
|
||||
calculatePrivateModulus(const std::vector<std::string> &keys);
|
||||
|
||||
static std::unordered_map<std::string, std::string> cert_key_map;
|
||||
};
|
||||
unordered_map<string, string> ReverseProxyCertUtils::cert_key_map;
|
||||
|
||||
void
|
||||
RPMSettings::load(cereal::JSONInputArchive &archive_in)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Loading RP Settings";
|
||||
|
||||
parseAppsecJSONKey<string>("name", name, archive_in);
|
||||
parseAppsecJSONKey<string>("host-header", host_hdr, archive_in, "$host");
|
||||
parseAppsecJSONKey<string>("dns-resolver", dns_resolver, archive_in, "127.0.0.11");
|
||||
}
|
||||
|
||||
const string &
|
||||
RPMSettings::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
string
|
||||
RPMSettings::applySettings(const std::string &server_content) const
|
||||
{
|
||||
string new_server_content = ReverseProxyBuilder::replaceTemplate(server_content, host_header_template, host_hdr);
|
||||
return ReverseProxyBuilder::replaceTemplate(new_server_content, dns_resolver_template, dns_resolver);
|
||||
}
|
||||
|
||||
void
|
||||
ReverseProxyCertUtils::init()
|
||||
{
|
||||
certs_path = getProfileAgentSettingWithDefault<string>("/etc/certs/", "openappsec.reverseProxy.certs");
|
||||
|
||||
untarCertificatesPackages();
|
||||
cert_key_map.clear();
|
||||
auto public_modulus_map = calculatePublicModulus(getFilesByExtension(".pem"));
|
||||
auto private_modulus_map = calculatePrivateModulus(getFilesByExtension(".key"));
|
||||
for (const auto &public_modulus_entry : public_modulus_map) {
|
||||
auto public_modulus = public_modulus_entry.second;
|
||||
if (private_modulus_map.find(public_modulus) != private_modulus_map.end()) {
|
||||
dbgTrace(D_LOCAL_POLICY)
|
||||
<< "Successfully parsed certificate: "
|
||||
<< public_modulus_entry.first
|
||||
<< " with private key: "
|
||||
<< private_modulus_map[public_modulus];
|
||||
|
||||
cert_key_map[public_modulus_entry.first] = private_modulus_map[public_modulus];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<string>
|
||||
ReverseProxyCertUtils::getFilesByExtension(const string &extension)
|
||||
{
|
||||
auto maybe_files = NGEN::Filesystem::getDirectoryFiles(certs_path);
|
||||
if (!maybe_files.ok()) return {};
|
||||
|
||||
auto files = maybe_files.unpack();
|
||||
files.erase(
|
||||
remove_if(
|
||||
files.begin(),
|
||||
files.end(),
|
||||
[&](const string& file) { return file.length() < 4 || file.substr(file.length() - 4) != extension; }
|
||||
),
|
||||
files.end()
|
||||
);
|
||||
|
||||
for (const auto &file : files) {
|
||||
dbgTrace(D_LOCAL_POLICY) << "Found file: " << file;
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
pair<string, string>
|
||||
ReverseProxyCertUtils::findMatchingCertificate(const string &host)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Looking for a matching certificate to host: " << host;
|
||||
|
||||
for (const auto &entry : cert_key_map) {
|
||||
string cert_path = entry.first;
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY) << "Checking match of certificate: " << cert_path;
|
||||
|
||||
// Create a BIO object to read the certificate
|
||||
BIO* cert_bio = BIO_new_file(cert_path.c_str(), "rb");
|
||||
if (!cert_bio) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Could not open certificate file: " << cert_path;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load the PEM-encoded public key from the file
|
||||
X509 *cert = PEM_read_bio_X509(cert_bio, nullptr, nullptr, nullptr);
|
||||
if (!cert) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Could not parse X509 certificate file: " << cert_path;
|
||||
BIO_free(cert_bio);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the subject alternative name extension
|
||||
STACK_OF(GENERAL_NAME)* san_names = static_cast<STACK_OF(GENERAL_NAME)*>(
|
||||
X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr)
|
||||
);
|
||||
|
||||
if (!san_names) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "No Subject Alternative Name found in the certificate: " << cert_path;
|
||||
X509_free(cert);
|
||||
BIO_free(cert_bio);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Iterate through the SAN entries
|
||||
for (int i = 0; i < sk_GENERAL_NAME_num(san_names); ++i) {
|
||||
GENERAL_NAME* name = sk_GENERAL_NAME_value(san_names, i);
|
||||
if (name->type == GEN_DNS) {
|
||||
const char* san = reinterpret_cast<const char*>(ASN1_STRING_get0_data(name->d.dNSName));
|
||||
|
||||
if (X509_check_host(cert, host.c_str(), host.length(), 0, nullptr) == 1) {
|
||||
dbgTrace(D_LOCAL_POLICY) << "Found matching certificate: " << cert_path << ", DNS name: " << san;
|
||||
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
|
||||
X509_free(cert);
|
||||
BIO_free(cert_bio);
|
||||
return {cert_path, cert_key_map[cert_path]};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY) << "Certificate: " << cert_path << " does not match host: " << host;
|
||||
|
||||
// Clean up
|
||||
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
|
||||
X509_free(cert);
|
||||
BIO_free(cert_bio);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Maybe<std::string>
|
||||
ReverseProxyCertUtils::extractModulus(const string &path, const string &type)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Started calculating modulus of: " << path << ", type: " << type;
|
||||
|
||||
string modulus_cmd = "openssl " + type + " -noout -modulus -in " + path + "; echo $?";
|
||||
auto modulus_maybe = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator>()->getExecOutput(modulus_cmd);
|
||||
if (!modulus_maybe.ok()) return genError("Could not complete command, error: " + modulus_maybe.getErr());
|
||||
|
||||
auto modulus_cmd_output = NGEN::Strings::removeTrailingWhitespaces(modulus_maybe.unpack());
|
||||
if (modulus_cmd_output.back() != '0') return genError("Could not extract modulus, error: " + modulus_cmd_output);
|
||||
|
||||
modulus_cmd_output.pop_back();
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY) << "Extracted modulus for: " << path << ", " << modulus_cmd_output;
|
||||
|
||||
return modulus_cmd_output;
|
||||
}
|
||||
|
||||
unordered_map<string, string>
|
||||
ReverseProxyCertUtils::calculatePublicModulus(const vector<string> &certs)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Calculating certificates modulus";
|
||||
|
||||
unordered_map<string, string> certs_modulus;
|
||||
for (const string &cert_file_name : certs) {
|
||||
string cert_path = certs_path + cert_file_name;
|
||||
auto modulus = extractModulus(cert_path, "x509");
|
||||
if (!modulus.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY) << modulus.getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
certs_modulus[cert_path] = modulus.unpack();
|
||||
}
|
||||
|
||||
return certs_modulus;
|
||||
}
|
||||
|
||||
unordered_map<string, string>
|
||||
ReverseProxyCertUtils::calculatePrivateModulus(const vector<string> &keys)
|
||||
{
|
||||
unordered_map<string, string> key_modulus;
|
||||
for (const string &private_key_file_name : keys) {
|
||||
string private_key_path = certs_path + private_key_file_name;
|
||||
auto modulus = extractModulus(private_key_path, "rsa");
|
||||
if (!modulus.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY) << modulus.getErr();
|
||||
continue;
|
||||
}
|
||||
|
||||
key_modulus[modulus.unpack()] = private_key_path;
|
||||
}
|
||||
|
||||
return key_modulus;
|
||||
}
|
||||
|
||||
void
|
||||
ReverseProxyCertUtils::untarCertificatesPackages()
|
||||
{
|
||||
vector<string> cert_pkgs = getFilesByExtension(".pkg");
|
||||
if (cert_pkgs.empty()) return;
|
||||
|
||||
for (const auto &cert_pkg : cert_pkgs) {
|
||||
dbgTrace(D_LOCAL_POLICY) << "Untaring certificate package: " << cert_pkg;
|
||||
string untar_cmd = "tar -C " + certs_path + " -xvf " + certs_path + cert_pkg;
|
||||
auto maybe_tar_res = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator>()->getExecOutput(untar_cmd);
|
||||
if (!maybe_tar_res.ok()) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Untar package error: " << maybe_tar_res.getErr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
ReverseProxyBuilder::replaceTemplate(
|
||||
const string &content,
|
||||
const boost::regex &nginx_directive_template,
|
||||
const string &value)
|
||||
{
|
||||
return NGEN::Regex::regexReplace(__FILE__, __LINE__, content, nginx_directive_template, value);
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
ReverseProxyBuilder::getTemplateContent(const string &nginx_conf_template)
|
||||
{
|
||||
ifstream nginx_template_in(nginx_templates_path + nginx_conf_template);
|
||||
if (!nginx_template_in.is_open()) return genError("Could not open the " + nginx_conf_template + " template");
|
||||
|
||||
string file_content((istreambuf_iterator<char>(nginx_template_in)), istreambuf_iterator<char>());
|
||||
nginx_template_in.close();
|
||||
|
||||
return file_content;
|
||||
}
|
||||
|
||||
Maybe<void>
|
||||
ReverseProxyBuilder::createSSLNginxServer(const string &host, const RPMSettings &rp_settings)
|
||||
{
|
||||
dbgTrace(D_LOCAL_POLICY) << "Creating SSL NGINX server: " << host;
|
||||
|
||||
pair<string, string> cert_key = ReverseProxyCertUtils::findMatchingCertificate(host);
|
||||
if (cert_key.first.empty() || cert_key.second.empty()) {
|
||||
return genError("Cannot find matching certificates to host: " + host);
|
||||
}
|
||||
|
||||
auto maybe_server_content = getTemplateContent(nginx_ssl_server_template);
|
||||
if (!maybe_server_content.ok()) return maybe_server_content.passErr();
|
||||
|
||||
string server_content = replaceTemplate(maybe_server_content.unpack(), host_template, host);
|
||||
server_content = replaceTemplate(server_content, private_key_template, cert_key.second);
|
||||
server_content = replaceTemplate(server_content, certificate_template, cert_key.first);
|
||||
server_content = rp_settings.applySettings(server_content);
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY) << "NGINX SSL Server content: " << server_content;
|
||||
|
||||
string conf_path = conf_base_path + nginx_configuration_path + "/443_" + host + ".conf";
|
||||
ofstream server_file(conf_path, ofstream::out | ofstream::trunc);
|
||||
if (!server_file.is_open()) {
|
||||
return genError("Could not open the output SSL NGINX configuration file: " + conf_path);
|
||||
}
|
||||
|
||||
server_file << server_content;
|
||||
server_file.close();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Maybe<void>
|
||||
ReverseProxyBuilder::createHTTPNginxServer(const string &host, const RPMSettings &rp_settings)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Creating HTTP NGINX server: " << host;
|
||||
|
||||
auto maybe_server_content = getTemplateContent(nginx_http_server_template);
|
||||
if (!maybe_server_content.ok()) return maybe_server_content.passErr();
|
||||
|
||||
string server_content = replaceTemplate(maybe_server_content.unpack(), host_template, host);
|
||||
server_content = rp_settings.applySettings(server_content);
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY) << "NGINX HTTP Server content: " << server_content;
|
||||
|
||||
string http_server_conf_path = conf_base_path + nginx_configuration_path + "80_" + host + ".conf";
|
||||
ofstream server_file(http_server_conf_path, ofstream::out | ofstream::trunc);
|
||||
if (!server_file.is_open()) {
|
||||
return genError("Could not open the output HTTP NGINX configuration file: " + http_server_conf_path);
|
||||
}
|
||||
|
||||
server_file << server_content;
|
||||
server_file.close();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Maybe<void>
|
||||
ReverseProxyBuilder::addNginxServerLocation(
|
||||
string location,
|
||||
const string &host,
|
||||
const ParsedRule &rule,
|
||||
const RPMSettings &rp_settings)
|
||||
{
|
||||
string port = rule.rpmIsHttps() ? string("443") : string("80");
|
||||
string location_conf_path = conf_base_path + nginx_configuration_path + port + '_' + host + "_locations/";
|
||||
|
||||
dbgFlow(D_LOCAL_POLICY) << "Adding a new NGINX location: " << location << " to: " << location_conf_path;
|
||||
|
||||
NGEN::Filesystem::makeDirRecursive(location_conf_path);
|
||||
|
||||
if (location.empty() || location.find_first_not_of('/') == string::npos)
|
||||
{
|
||||
location = "/";
|
||||
location_conf_path += "root_location.conf";
|
||||
}
|
||||
else
|
||||
{
|
||||
string location_conf_basename = location.substr(1, location.length() - 1) + "_location";
|
||||
replace(location_conf_basename.begin(), location_conf_basename.end(), '/', '_');
|
||||
location_conf_path += location_conf_basename + ".conf";
|
||||
}
|
||||
auto maybe_location_content = getTemplateContent(nginx_location_template);
|
||||
if (!maybe_location_content.ok()) return maybe_location_content.passErr();
|
||||
|
||||
string location_content = replaceTemplate(maybe_location_content.unpack(), location_template, location);
|
||||
location_content = replaceTemplate(location_content, upstream_template, rule.rpmGetUpstream());
|
||||
location_content = rp_settings.applySettings(location_content);
|
||||
|
||||
dbgTrace(D_LOCAL_POLICY) << "NGINX server location content: " << location_content;
|
||||
|
||||
ofstream location_file(location_conf_path, ofstream::out | ofstream::trunc);
|
||||
if (!location_file.is_open()) {
|
||||
return genError("Could not open the output NGINX location block: " + location_conf_path);
|
||||
}
|
||||
|
||||
location_file << location_content;
|
||||
location_file.close();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Maybe<void>
|
||||
ReverseProxyBuilder::createNewNginxServer(const string &host, const ParsedRule &rule, const RPMSettings &rp_settings)
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Creating a new NGINX server: " << host << ", SSL: " << rule.rpmIsHttps();
|
||||
|
||||
if (rule.rpmIsHttps()) {
|
||||
auto maybe_res = ReverseProxyBuilder::createSSLNginxServer(host, rp_settings);
|
||||
if (!maybe_res.ok()) {
|
||||
return genError("Could not create an SSL NGINX server configuration: " + maybe_res.getErr());
|
||||
}
|
||||
} else {
|
||||
auto maybe_res = ReverseProxyBuilder::createHTTPNginxServer(host, rp_settings);
|
||||
if (!maybe_res.ok()) {
|
||||
return genError("Could not create an HTTP NGINX server: " + maybe_res.getErr());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Maybe<void>
|
||||
ReverseProxyBuilder::reloadNginx()
|
||||
{
|
||||
dbgFlow(D_LOCAL_POLICY) << "Reloading NGINX...";
|
||||
|
||||
auto maybe_nginx_t = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator>()->getExecOutput(
|
||||
"nginx -t 2>&1; echo $?"
|
||||
);
|
||||
|
||||
if (!maybe_nginx_t.ok()){
|
||||
return genError("Could not check NGINX configuration: " + maybe_nginx_t.getErr());
|
||||
}
|
||||
|
||||
string nginx_t_output = NGEN::Strings::removeTrailingWhitespaces(maybe_nginx_t.unpack());
|
||||
if (nginx_t_output.back() != '0') return genError("Invalid NGINX configuration: " + nginx_t_output);
|
||||
|
||||
auto maybe_nginx_reload = Singleton::Consume<I_ShellCmd>::by<LocalPolicyMgmtGenerator>()->getExecOutput(
|
||||
"nginx -s reload 2>&1;"
|
||||
);
|
||||
|
||||
if (!maybe_nginx_reload.ok()){
|
||||
return genError("Could not reload NGINX: " + maybe_nginx_reload.getErr());
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void
|
||||
ReverseProxyBuilder::init()
|
||||
{
|
||||
conf_base_path = getConfigurationWithDefault<string>("/etc/cp/conf/", "Config Component", "configuration path");
|
||||
nginx_templates_path = getProfileAgentSettingWithDefault<string>(
|
||||
"/etc/nginx/nginx-templates/", "openappsec.reverseProxy.nginxTemplates"
|
||||
);
|
||||
|
||||
NGEN::Filesystem::deleteDirectory(conf_base_path + nginx_configuration_path, true);
|
||||
NGEN::Filesystem::makeDir(conf_base_path + nginx_configuration_path);
|
||||
ReverseProxyCertUtils::init();
|
||||
}
|
||||
@@ -156,6 +156,7 @@ RulesTriggerSection::save(cereal::JSONOutputArchive &out_ar) const
|
||||
RulesConfigRulebase::RulesConfigRulebase(
|
||||
const string &_name,
|
||||
const string &_url,
|
||||
const string &_port,
|
||||
const string &_uri,
|
||||
vector<PracticeSection> _practices,
|
||||
vector<ParametersSection> _parameters,
|
||||
@@ -169,39 +170,19 @@ RulesConfigRulebase::RulesConfigRulebase(
|
||||
try {
|
||||
bool any = _name == "Any" && _url == "Any" && _uri == "Any";
|
||||
id = any ? "Any" : _url+_uri;
|
||||
if (_uri != "/") {
|
||||
context = any ? "All()" : "Any("
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(80)" +
|
||||
string(_uri.empty() ? "" : ",BeginWithUri(" + _uri + ")") +
|
||||
"),"
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(443)" +
|
||||
string(_uri.empty() ? "" : ",BeginWithUri(" + _uri + ")") +
|
||||
")"
|
||||
")";
|
||||
} else {
|
||||
context = any ? "All()" : "Any("
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(80)"
|
||||
"),"
|
||||
"All("
|
||||
"Any("
|
||||
"EqualHost(" + _url + ")"
|
||||
"),"
|
||||
"EqualListeningPort(443)"
|
||||
")"
|
||||
")";
|
||||
if (any) {
|
||||
context ="All()";
|
||||
return;
|
||||
}
|
||||
string host_check = "Any(EqualHost(" + _url + ")),";
|
||||
string uri_check = (_uri.empty() || _uri == "/" ) ? "" : ",BeginWithUri(" + _uri + ")";
|
||||
auto ports = _port.empty() ? vector<string>({"80", "443"}) : vector<string>({_port});
|
||||
context = "Any(";
|
||||
for (auto &port : ports) {
|
||||
string check_last = (ports.size() == 1 || port == "443") ? ")" : "),";
|
||||
context += "All(" + host_check + "EqualListeningPort(" + port + ")" + uri_check + check_last;
|
||||
}
|
||||
context += ")";
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgWarning(D_LOCAL_POLICY) << "Failed to generate rule UUID. Error: " << e.what();
|
||||
}
|
||||
@@ -284,6 +265,7 @@ UsersIdentifiersRulebase::UsersIdentifiersRulebase(
|
||||
const string &
|
||||
UsersIdentifiersRulebase::getIdentifier() const
|
||||
{
|
||||
if (source_identifiers.empty()) return source_identifier;
|
||||
return source_identifiers[0].getIdentifier();
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
@@ -45,11 +45,7 @@ checkSamlPortal(const string &command_output)
|
||||
Maybe<string>
|
||||
getIDAGaia(const string &command_output)
|
||||
{
|
||||
if (command_output.find("Portal is running") != string::npos) {
|
||||
return string("ida_gaia");
|
||||
}
|
||||
|
||||
return genError("Current host does not have SAML Portal configured");
|
||||
return string("ida_gaia");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
@@ -72,6 +68,22 @@ checkIDP(shared_ptr<istream> file_stream)
|
||||
|
||||
#if defined(gaia) || defined(smb)
|
||||
|
||||
Maybe<string>
|
||||
checkIsCpviewRunning(const string &command_output)
|
||||
{
|
||||
if (command_output == "true" || command_output == "false") return command_output;
|
||||
|
||||
return genError("cpview is not running");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
checkIsCPotelcolGRET64(const string &command_output)
|
||||
{
|
||||
if (command_output == "true" || command_output == "false") return command_output;
|
||||
|
||||
return genError("CPotelcol is not installed or its take is below T64");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
checkHasSDWan(const string &command_output)
|
||||
{
|
||||
@@ -193,6 +205,12 @@ checkIfSdwanRunning(const string &command_output)
|
||||
return genError("Could not determine if sd-wan is running or not");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getClusterObjectIP(const string &command_output)
|
||||
{
|
||||
return getAttr(command_output, "Cluster object IP was not found");
|
||||
}
|
||||
|
||||
Maybe<string>
|
||||
getSmbObjectName(const string &command_output)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,14 @@
|
||||
#ifdef SHELL_CMD_HANDLER
|
||||
#if defined(gaia) || defined(smb)
|
||||
SHELL_CMD_HANDLER("cpProductIntegrationMgmtObjectType", "cpprod_util CPPROD_IsMgmtMachine", getMgmtObjType)
|
||||
SHELL_CMD_HANDLER("isCpviewRunning",
|
||||
"pidof cpview_api_service > /dev/null 2>&1 && [ -f $CPDIR/conf/cpview_api_service.version ] "
|
||||
"&& echo 'true' || echo 'false'",
|
||||
checkIsCpviewRunning)
|
||||
SHELL_CMD_HANDLER("isCPotelcolGRET64",
|
||||
"grep -A 10 '(BUNDLE_CPOTELCOL_AUTOUPDATE' ${CPDIR}/registry/HKLM_registry.data | "
|
||||
"awk '/SU_Build_Take/{val = substr($2, 2, length($2)-2); if (val >=64) print \"true\"; else print \"false\" }'",
|
||||
checkIsCPotelcolGRET64)
|
||||
SHELL_CMD_HANDLER("hasSDWan", "[ -f $FWDIR/bin/sdwan_steering ] && echo '1' || echo '0'", checkHasSDWan)
|
||||
SHELL_CMD_HANDLER(
|
||||
"canUpdateSDWanData",
|
||||
@@ -50,12 +58,20 @@ SHELL_CMD_HANDLER(
|
||||
"cat /etc/cp-release | grep -oE 'R[0-9]+(\\.[0-9]+)?'",
|
||||
getGWVersion
|
||||
)
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectIP",
|
||||
"obj=\"$(cpsdwan get_data | jq -r .cluster_name)\";"
|
||||
" awk -v obj=\"$obj\" '$1 == \":\" && $2 == \"(\" obj, $1 == \":ip_address\" { if ($1 == \":ip_address\")"
|
||||
" { gsub(/[()]/, \"\", $2); print $2; exit; } }'"
|
||||
" $FWDIR/state/local/FW1/local.gateway_cluster",
|
||||
getClusterObjectIP
|
||||
)
|
||||
#endif //gaia || smb
|
||||
|
||||
#if defined(gaia)
|
||||
SHELL_CMD_HANDLER("hasSupportedBlade", "enabled_blades", checkHasSupportedBlade)
|
||||
SHELL_CMD_HANDLER("hasSamlPortal", "mpclient status saml-vpn", checkSamlPortal)
|
||||
SHELL_CMD_HANDLER("requiredNanoServices", "mpclient status saml-vpn", getIDAGaia)
|
||||
SHELL_CMD_HANDLER("requiredNanoServices", "ida_gaia", getIDAGaia)
|
||||
SHELL_CMD_HANDLER(
|
||||
"cpProductIntegrationMgmtParentObjectName",
|
||||
"cat $FWDIR/database/myself_objects.C "
|
||||
|
||||
@@ -278,36 +278,6 @@ HttpsCurl::HttpsCurl(const HttpsCurl &other) :
|
||||
HttpCurl(other),
|
||||
ca_path(other.ca_path) {}
|
||||
|
||||
bool
|
||||
HttpsCurl::downloadOpenAppsecPackages()
|
||||
{
|
||||
char errorstr[CURL_ERROR_SIZE];
|
||||
CURL* curl_handle = curl_easy_init();
|
||||
if (!curl_handle) return false;
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, ("https://" + curl_url).c_str());
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeResponseCallback);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &out_file);
|
||||
|
||||
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorstr);
|
||||
|
||||
CURLcode res = curl_easy_perform(curl_handle);
|
||||
if (res == CURLE_OK) {
|
||||
dbgTrace(D_HTTP_REQUEST) << "CURL HTTP request successfully completed.";
|
||||
} else {
|
||||
dbgWarning(D_HTTP_REQUEST) << "CURL result " + string(curl_easy_strerror(res));
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HttpsCurl::setCurlOpts(long timeout, HTTP_VERSION http_version)
|
||||
{
|
||||
@@ -347,7 +317,7 @@ HttpsCurl::setCurlOpts(long timeout, HTTP_VERSION http_version)
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeResponseCallback);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &out_file);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, timeout);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_CAINFO, ca_path.c_str());
|
||||
if (ca_path != "") curl_easy_setopt(curl_handle, CURLOPT_CAINFO, ca_path.c_str());
|
||||
headers = curl_slist_append(headers, "Accept: */*");
|
||||
string auth = string("Authorization: Bearer ") + bearer;
|
||||
headers = curl_slist_append(headers, auth.c_str());
|
||||
|
||||
@@ -105,7 +105,6 @@ public:
|
||||
static CURLcode ssl_ctx_verify_certificate(CURL *curl, void *ssl_ctx, void *opq);
|
||||
static int verify_certificate(int preverify_ok, X509_STORE_CTX *ctx);
|
||||
void setCurlOpts(long timeout = 60L, HTTP_VERSION http_version = HTTP_VERSION::HTTP_VERSION_1_1) override;
|
||||
bool downloadOpenAppsecPackages();
|
||||
|
||||
private:
|
||||
std::string ca_path;
|
||||
|
||||
@@ -592,13 +592,8 @@ HTTPClient::curlGetFileOverSSL(const URLParser &url, ofstream &out_file, const s
|
||||
proxy_config->getProxyCredentials(ProxyProtocol::HTTPS),
|
||||
cert_file_path);
|
||||
|
||||
bool connection_ok;
|
||||
if (url.getBaseURL().unpack() == "downloads.openappsec.io") {
|
||||
connection_ok = ssl_curl_client.downloadOpenAppsecPackages();
|
||||
} else {
|
||||
ssl_curl_client.setCurlOpts();
|
||||
connection_ok = ssl_curl_client.connect();
|
||||
}
|
||||
ssl_curl_client.setCurlOpts();
|
||||
bool connection_ok = ssl_curl_client.connect();
|
||||
if (!connection_ok)
|
||||
{
|
||||
stringstream url_s;
|
||||
|
||||
@@ -256,10 +256,23 @@ private:
|
||||
if (!getenv("DOCKER_RPM_ENABLED")) return HealthCheckStatus::IGNORED;
|
||||
|
||||
static const string standalone_cmd = "/usr/sbin/cpnano -s --docker-rpm; echo $?";
|
||||
static int timeout_tolerance = 1;
|
||||
static HealthCheckStatus health_status = HealthCheckStatus::HEALTHY;
|
||||
|
||||
dbgTrace(D_HEALTH_CHECK) << "Checking the standalone docker health status with command: " << standalone_cmd;
|
||||
|
||||
auto maybe_result = Singleton::Consume<I_ShellCmd>::by<HealthChecker>()->getExecOutput(standalone_cmd, 1000);
|
||||
auto maybe_result = Singleton::Consume<I_ShellCmd>::by<HealthChecker>()->getExecOutput(standalone_cmd, 5000);
|
||||
if (!maybe_result.ok()) {
|
||||
if (maybe_result.getErr().find("Reached timeout") != string::npos) {
|
||||
dbgWarning(D_HEALTH_CHECK)
|
||||
<< "Reached timeout while querying standalone health status, attempt number: "
|
||||
<< timeout_tolerance;
|
||||
|
||||
return health_status == HealthCheckStatus::UNHEALTHY || timeout_tolerance++ > 3 ?
|
||||
HealthCheckStatus::UNHEALTHY :
|
||||
health_status;
|
||||
}
|
||||
|
||||
dbgWarning(D_HEALTH_CHECK) << "Unable to get the standalone docker status. Returning unhealthy status.";
|
||||
return HealthCheckStatus::UNHEALTHY;
|
||||
}
|
||||
@@ -267,10 +280,10 @@ private:
|
||||
|
||||
auto response = NGEN::Strings::removeTrailingWhitespaces(maybe_result.unpack());
|
||||
|
||||
if (response.back() == '0') return HealthCheckStatus::HEALTHY;
|
||||
if (response.back() == '1') return HealthCheckStatus::UNHEALTHY;
|
||||
if (response.back() == '1') return health_status = HealthCheckStatus::UNHEALTHY;
|
||||
|
||||
return HealthCheckStatus::DEGRADED;
|
||||
timeout_tolerance = 1;
|
||||
return health_status = (response.back() == '0') ? HealthCheckStatus::HEALTHY : HealthCheckStatus::DEGRADED;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -87,10 +87,12 @@ public:
|
||||
|
||||
private:
|
||||
std::string getCleanChecksum(const std::string &unclean_checksum);
|
||||
void periodicPolicyLoad();
|
||||
|
||||
std::string local_policy_path;
|
||||
std::string curr_version;
|
||||
std::string curr_policy;
|
||||
std::string curr_checksum;
|
||||
bool should_apply_policy;
|
||||
};
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ public:
|
||||
last_update = i_orch_status->getUpdateTime();
|
||||
last_update_status = i_orch_status->getUpdateStatus();
|
||||
policy_version = i_orch_status->getPolicyVersion();
|
||||
waap_model_version = i_orch_status->getWaapModelVersion();
|
||||
last_policy_update = i_orch_status->getLastPolicyUpdate();
|
||||
last_manifest_update = i_orch_status->getLastManifestUpdate();
|
||||
last_settings_update = i_orch_status->getLastSettingsUpdate();
|
||||
@@ -73,7 +72,6 @@ private:
|
||||
S2C_LABEL_PARAM(std::string, last_update, "Last update");
|
||||
S2C_LABEL_PARAM(std::string, last_update_status, "Last update status");
|
||||
S2C_LABEL_PARAM(std::string, policy_version, "Policy version");
|
||||
S2C_LABEL_PARAM(std::string, waap_model_version, "AI model version");
|
||||
S2C_LABEL_PARAM(std::string, last_policy_update, "Last policy update");
|
||||
S2C_LABEL_PARAM(std::string, last_manifest_update, "Last manifest update");
|
||||
S2C_LABEL_PARAM(std::string, last_settings_update, "Last settings update");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user