diff --git a/website/404.html b/website/404.html index 08761e5b4..00c1c35d6 100644 --- a/website/404.html +++ b/website/404.html @@ -10,7 +10,7 @@ - + diff --git a/website/assets/js/a2130fc2.03c28918.js b/website/assets/js/a2130fc2.03c28918.js new file mode 100644 index 000000000..2aeea4f41 --- /dev/null +++ b/website/assets/js/a2130fc2.03c28918.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1459],{87:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=t(5893),a=t(1151);const r={id:"host-network-ports",title:"Host Networking Ports"},o="Host Networking Ports",i={id:"validation/host-network-ports",title:"Host Networking Ports",description:"Description",source:"@site/docs/validation/host-network-ports.md",sourceDirName:"validation",slug:"/validation/host-network-ports",permalink:"/gatekeeper-library/website/validation/host-network-ports",draft:!1,unlisted:!1,editUrl:"https://github.com/open-policy-agent/gatekeeper-library/edit/master/website/docs/validation/host-network-ports.md",tags:[],version:"current",frontMatter:{id:"host-network-ports",title:"Host Networking Ports"},sidebar:"docs",previous:{title:"Host Namespace",permalink:"/gatekeeper-library/website/validation/host-namespaces"},next:{title:"Privileged Container",permalink:"/gatekeeper-library/website/validation/privileged-containers"}},p={},l=[{value:"Description",id:"description",level:2},{value:"Template",id:"template",level:2},{value:"Usage",id:"usage",level:3},{value:"Examples",id:"examples",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.a)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"host-networking-ports",children:"Host Networking Ports"}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the ",(0,s.jsx)(n.code,{children:"hostNetwork"})," and ",(0,s.jsx)(n.code,{children:"hostPorts"})," fields in a PodSecurityPolicy. For more information, see ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces",children:"https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces"})]}),"\n",(0,s.jsx)(n.h2,{id:"template",children:"Template"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: templates.gatekeeper.sh/v1\nkind: ConstraintTemplate\nmetadata:\n name: k8spsphostnetworkingports\n annotations:\n metadata.gatekeeper.sh/title: "Host Networking Ports"\n metadata.gatekeeper.sh/version: 1.1.4\n description: >-\n Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific\n ports must be specified. Corresponds to the `hostNetwork` and\n `hostPorts` fields in a PodSecurityPolicy. For more information, see\n https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces\nspec:\n crd:\n spec:\n names:\n kind: K8sPSPHostNetworkingPorts\n validation:\n # Schema for the `parameters` field\n openAPIV3Schema:\n type: object\n description: >-\n Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific\n ports must be specified. Corresponds to the `hostNetwork` and\n `hostPorts` fields in a PodSecurityPolicy. For more information, see\n https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces\n properties:\n exemptImages:\n description: >-\n Any container that uses an image that matches an entry in this list will be excluded\n from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.\n\n It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)\n in order to avoid unexpectedly exempting images from an untrusted repository.\n type: array\n items:\n type: string\n hostNetwork:\n description: "Determines if the policy allows the use of HostNetwork in the pod spec."\n type: boolean\n min:\n description: "The start of the allowed port range, inclusive."\n type: integer\n max:\n description: "The end of the allowed port range, inclusive."\n type: integer\n targets:\n - target: admission.k8s.gatekeeper.sh\n code:\n - engine: K8sNativeValidation\n source:\n variables:\n - name: containers\n expression: \'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []\'\n - name: initContainers\n expression: \'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []\'\n - name: ephemeralContainers\n expression: \'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []\'\n - name: exemptImagePrefixes\n expression: |\n !has(variables.params.exemptImages) ? [] :\n variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", ""))\n - name: exemptImageExplicit\n expression: |\n !has(variables.params.exemptImages) ? [] : \n variables.params.exemptImages.filter(image, !image.endsWith("*"))\n - name: exemptImages\n expression: |\n (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,\n container.image in variables.exemptImageExplicit ||\n variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption))\n ).map(container, container.image)\n - name: badContainers\n expression: |\n (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,\n !(container.image in variables.exemptImages) && has(container.ports) &&\n (\n (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) ||\n (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max))\n )\n )\n - name: isUpdate\n expression: has(request.operation) && request.operation == "UPDATE"\n - name: hostNetworkAllowed\n expression: has(variables.params.hostNetwork) && variables.params.hostNetwork\n - name: hostNetworkEnabled\n expression: has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork\n - name: hostNetworkViolation\n expression: variables.hostNetworkEnabled && !variables.hostNetworkAllowed\n validations:\n - expression: \'variables.isUpdate || size(variables.badContainers) == 0\'\n messageExpression: \'"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name\'\n - expression: variables.isUpdate || !variables.hostNetworkViolation\n messageExpression: \'"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name\'\n - engine: Rego\n source:\n rego: |\n package k8spsphostnetworkingports\n\n import data.lib.exclude_update.is_update\n import data.lib.exempt_container.is_exempt\n\n violation[{"msg": msg, "details": {}}] {\n # spec.hostNetwork field is immutable.\n not is_update(input.review)\n\n input_share_hostnetwork(input.review.object)\n msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters])\n }\n\n input_share_hostnetwork(o) {\n not input.parameters.hostNetwork\n o.spec.hostNetwork\n }\n\n input_share_hostnetwork(_) {\n hostPort := input_containers[_].ports[_].hostPort\n hostPort < input.parameters.min\n }\n\n input_share_hostnetwork(_) {\n hostPort := input_containers[_].ports[_].hostPort\n hostPort > input.parameters.max\n }\n\n input_containers[c] {\n c := input.review.object.spec.containers[_]\n not is_exempt(c)\n }\n\n input_containers[c] {\n c := input.review.object.spec.initContainers[_]\n not is_exempt(c)\n }\n\n input_containers[c] {\n c := input.review.object.spec.ephemeralContainers[_]\n not is_exempt(c)\n }\n libs:\n - |\n package lib.exclude_update\n\n is_update(review) {\n review.operation == "UPDATE"\n }\n - |\n package lib.exempt_container\n\n is_exempt(container) {\n exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])\n img := container.image\n exemption := exempt_images[_]\n _matches_exemption(img, exemption)\n }\n\n _matches_exemption(img, exemption) {\n not endswith(exemption, "*")\n exemption == img\n }\n\n _matches_exemption(img, exemption) {\n endswith(exemption, "*")\n prefix := trim_suffix(exemption, "*")\n startswith(img, prefix)\n }\n\n'})}),"\n",(0,s.jsx)(n.h3,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/template.yaml\n"})}),"\n",(0,s.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"port-range-with-host-network-allowed"}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"constraint"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: constraints.gatekeeper.sh/v1beta1\nkind: K8sPSPHostNetworkingPorts\nmetadata:\n name: psp-host-network-ports\nspec:\n match:\n kinds:\n - apiGroups: [""]\n kinds: ["Pod"]\n parameters:\n hostNetwork: true\n min: 80\n max: 9000\n exemptImages:\n - "safeimages.com/*"\n\n'})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"out-of-range"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"example-allowed"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-allowed\n labels:\n app: nginx-host-networking-ports\nspec:\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9000\n hostPort: 80\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"out-of-range-ephemeral"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n ephemeralContainers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/disallowed_ephemeral.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"no-ports-specified"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"port-violation-exempted"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-exempted\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: safeimages.com/nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_out_of_range_exempted.yaml\n"})})]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"host-network-forbidden"}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"constraint"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: constraints.gatekeeper.sh/v1beta1\nkind: K8sPSPHostNetworkingPorts\nmetadata:\n name: psp-host-network\nspec:\n match:\n kinds:\n - apiGroups: [""]\n kinds: ["Pod"]\n parameters:\n hostNetwork: false\n\n'})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"hostnetwork-true"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-network-true\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"hostnetwork-false"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-network-false\nspec:\n hostNetwork: false\n containers:\n - name: nginx\n image: nginx\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml\n"})})]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"port-range-with-host-network-forbidden"}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"constraint"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: constraints.gatekeeper.sh/v1beta1\nkind: K8sPSPHostNetworkingPorts\nmetadata:\n name: psp-host-network-ports\nspec:\n match:\n kinds:\n - apiGroups: [""]\n kinds: ["Pod"]\n parameters:\n hostNetwork: false\n min: 80\n max: 9000\n exemptImages:\n - "safeimages.com/*"\n\n'})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"out-of-range-and-host-network-true"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"exempted-image-still-violates-on-hostnetwork"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-hn-ok-bad-port\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: safeimages.com/nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_exempted_container_host_network_enabled.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"in-range-host-network-false"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-allowed\n labels:\n app: nginx-host-networking-ports\nspec:\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9000\n hostPort: 80\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"disallowed-ephemeral"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n ephemeralContainers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/disallowed_ephemeral.yaml\n"})})]})]})]})}function m(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>o});var s=t(7294);const a={},r=s.createContext(a);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/website/assets/js/a2130fc2.052f6c08.js b/website/assets/js/a2130fc2.052f6c08.js deleted file mode 100644 index 1c9766280..000000000 --- a/website/assets/js/a2130fc2.052f6c08.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1459],{87:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=t(5893),a=t(1151);const r={id:"host-network-ports",title:"Host Networking Ports"},o="Host Networking Ports",i={id:"validation/host-network-ports",title:"Host Networking Ports",description:"Description",source:"@site/docs/validation/host-network-ports.md",sourceDirName:"validation",slug:"/validation/host-network-ports",permalink:"/gatekeeper-library/website/validation/host-network-ports",draft:!1,unlisted:!1,editUrl:"https://github.com/open-policy-agent/gatekeeper-library/edit/master/website/docs/validation/host-network-ports.md",tags:[],version:"current",frontMatter:{id:"host-network-ports",title:"Host Networking Ports"},sidebar:"docs",previous:{title:"Host Namespace",permalink:"/gatekeeper-library/website/validation/host-namespaces"},next:{title:"Privileged Container",permalink:"/gatekeeper-library/website/validation/privileged-containers"}},p={},l=[{value:"Description",id:"description",level:2},{value:"Template",id:"template",level:2},{value:"Usage",id:"usage",level:3},{value:"Examples",id:"examples",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.a)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"host-networking-ports",children:"Host Networking Ports"}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific ports must be specified. Corresponds to the ",(0,s.jsx)(n.code,{children:"hostNetwork"})," and ",(0,s.jsx)(n.code,{children:"hostPorts"})," fields in a PodSecurityPolicy. For more information, see ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces",children:"https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces"})]}),"\n",(0,s.jsx)(n.h2,{id:"template",children:"Template"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: templates.gatekeeper.sh/v1\nkind: ConstraintTemplate\nmetadata:\n name: k8spsphostnetworkingports\n annotations:\n metadata.gatekeeper.sh/title: "Host Networking Ports"\n metadata.gatekeeper.sh/version: 1.1.3\n description: >-\n Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific\n ports must be specified. Corresponds to the `hostNetwork` and\n `hostPorts` fields in a PodSecurityPolicy. For more information, see\n https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces\nspec:\n crd:\n spec:\n names:\n kind: K8sPSPHostNetworkingPorts\n validation:\n # Schema for the `parameters` field\n openAPIV3Schema:\n type: object\n description: >-\n Controls usage of host network namespace by pod containers. HostNetwork verification happens without exception for exemptImages. Specific\n ports must be specified. Corresponds to the `hostNetwork` and\n `hostPorts` fields in a PodSecurityPolicy. For more information, see\n https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces\n properties:\n exemptImages:\n description: >-\n Any container that uses an image that matches an entry in this list will be excluded\n from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.\n\n It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)\n in order to avoid unexpectedly exempting images from an untrusted repository.\n type: array\n items:\n type: string\n hostNetwork:\n description: "Determines if the policy allows the use of HostNetwork in the pod spec."\n type: boolean\n min:\n description: "The start of the allowed port range, inclusive."\n type: integer\n max:\n description: "The end of the allowed port range, inclusive."\n type: integer\n targets:\n - target: admission.k8s.gatekeeper.sh\n code:\n - engine: K8sNativeValidation\n source:\n variables:\n - name: containers\n expression: \'has(variables.anyObject.spec.containers) ? variables.anyObject.spec.containers : []\'\n - name: initContainers\n expression: \'has(variables.anyObject.spec.initContainers) ? variables.anyObject.spec.initContainers : []\'\n - name: ephemeralContainers\n expression: \'has(variables.anyObject.spec.ephemeralContainers) ? variables.anyObject.spec.ephemeralContainers : []\'\n - name: exemptImagePrefixes\n expression: |\n !has(variables.params.exemptImages) ? [] :\n variables.params.exemptImages.filter(image, image.endsWith("*")).map(image, string(image).replace("*", ""))\n - name: exemptImageExplicit\n expression: |\n !has(variables.params.exemptImages) ? [] : \n variables.params.exemptImages.filter(image, !image.endsWith("*"))\n - name: exemptImages\n expression: |\n (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,\n container.image in variables.exemptImageExplicit ||\n variables.exemptImagePrefixes.exists(exemption, string(container.image).startsWith(exemption)))\n - name: badContainers\n expression: |\n (variables.containers + variables.initContainers + variables.ephemeralContainers).filter(container,\n !(container.image in variables.exemptImages) && has(container.ports) &&\n (\n (container.ports.all(port, has(port.hostPort) && has(variables.params.min) && port.hostPort < variables.params.min)) ||\n (container.ports.all(port, has(port.hostPort) && has(variables.params.max) && port.hostPort > variables.params.max))\n )\n )\n - name: isUpdate\n expression: has(request.operation) && request.operation == "UPDATE"\n - name: hostNetworkAllowed\n expression: has(variables.params.hostNetwork) && variables.params.hostNetwork\n - name: hostNetworkEnabled\n expression: has(variables.anyObject.spec.hostNetwork) && variables.anyObject.spec.hostNetwork\n - name: hostNetworkViolation\n expression: variables.hostNetworkEnabled && !variables.hostNetworkAllowed\n validations:\n - expression: \'variables.isUpdate || size(variables.badContainers) == 0\'\n messageExpression: \'"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name\'\n - expression: variables.isUpdate || !variables.hostNetworkViolation\n messageExpression: \'"The specified hostNetwork and hostPort are not allowed, pod: " + variables.anyObject.metadata.name\'\n - engine: Rego\n source:\n rego: |\n package k8spsphostnetworkingports\n\n import data.lib.exclude_update.is_update\n import data.lib.exempt_container.is_exempt\n\n violation[{"msg": msg, "details": {}}] {\n # spec.hostNetwork field is immutable.\n not is_update(input.review)\n\n input_share_hostnetwork(input.review.object)\n msg := sprintf("The specified hostNetwork and hostPort are not allowed, pod: %v. Allowed values: %v", [input.review.object.metadata.name, input.parameters])\n }\n\n input_share_hostnetwork(o) {\n not input.parameters.hostNetwork\n o.spec.hostNetwork\n }\n\n input_share_hostnetwork(_) {\n hostPort := input_containers[_].ports[_].hostPort\n hostPort < input.parameters.min\n }\n\n input_share_hostnetwork(_) {\n hostPort := input_containers[_].ports[_].hostPort\n hostPort > input.parameters.max\n }\n\n input_containers[c] {\n c := input.review.object.spec.containers[_]\n not is_exempt(c)\n }\n\n input_containers[c] {\n c := input.review.object.spec.initContainers[_]\n not is_exempt(c)\n }\n\n input_containers[c] {\n c := input.review.object.spec.ephemeralContainers[_]\n not is_exempt(c)\n }\n libs:\n - |\n package lib.exclude_update\n\n is_update(review) {\n review.operation == "UPDATE"\n }\n - |\n package lib.exempt_container\n\n is_exempt(container) {\n exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])\n img := container.image\n exemption := exempt_images[_]\n _matches_exemption(img, exemption)\n }\n\n _matches_exemption(img, exemption) {\n not endswith(exemption, "*")\n exemption == img\n }\n\n _matches_exemption(img, exemption) {\n endswith(exemption, "*")\n prefix := trim_suffix(exemption, "*")\n startswith(img, prefix)\n }\n\n'})}),"\n",(0,s.jsx)(n.h3,{id:"usage",children:"Usage"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/template.yaml\n"})}),"\n",(0,s.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"port-range-with-host-network-allowed"}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"constraint"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: constraints.gatekeeper.sh/v1beta1\nkind: K8sPSPHostNetworkingPorts\nmetadata:\n name: psp-host-network-ports\nspec:\n match:\n kinds:\n - apiGroups: [""]\n kinds: ["Pod"]\n parameters:\n hostNetwork: true\n min: 80\n max: 9000\n'})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/constraint.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"out-of-range"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"example-allowed"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-allowed\n labels:\n app: nginx-host-networking-ports\nspec:\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9000\n hostPort: 80\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"out-of-range-ephemeral"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n ephemeralContainers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/disallowed_ephemeral.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"no-ports-specified"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports.yaml\n"})})]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"host-network-forbidden"}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"constraint"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: constraints.gatekeeper.sh/v1beta1\nkind: K8sPSPHostNetworkingPorts\nmetadata:\n name: psp-host-network\nspec:\n match:\n kinds:\n - apiGroups: [""]\n kinds: ["Pod"]\n parameters:\n hostNetwork: false\n\n'})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/block_host_network/constraint.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"hostnetwork-true"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-network-true\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_true.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"hostnetwork-false"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-network-false\nspec:\n hostNetwork: false\n containers:\n - name: nginx\n image: nginx\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_no_ports_host_network_false.yaml\n"})})]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"port-range-with-host-network-forbidden"}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"constraint"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: constraints.gatekeeper.sh/v1beta1\nkind: K8sPSPHostNetworkingPorts\nmetadata:\n name: psp-host-network-ports\nspec:\n match:\n kinds:\n - apiGroups: [""]\n kinds: ["Pod"]\n parameters:\n hostNetwork: false\n min: 80\n max: 9000\n\n'})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/constraint.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"out-of-range-and-host-network-true"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/port_range_block_host_network/example_disallowed_out_of_range_host_network_true.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"in-range-host-network-false"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-allowed\n labels:\n app: nginx-host-networking-ports\nspec:\n containers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9000\n hostPort: 80\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/example_allowed_in_range.yaml\n"})})]}),(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"disallowed-ephemeral"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: nginx-host-networking-ports-disallowed\n labels:\n app: nginx-host-networking-ports\nspec:\n hostNetwork: true\n ephemeralContainers:\n - name: nginx\n image: nginx\n ports:\n - containerPort: 9001\n hostPort: 9001\n\n"})}),(0,s.jsx)(n.p,{children:"Usage"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/samples/psp-host-network-ports/disallowed_ephemeral.yaml\n"})})]})]})]})}function m(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>o});var s=t(7294);const a={},r=s.createContext(a);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/website/assets/js/runtime~main.3d841f46.js b/website/assets/js/runtime~main.e24eaac4.js similarity index 98% rename from website/assets/js/runtime~main.3d841f46.js rename to website/assets/js/runtime~main.e24eaac4.js index c0652f0d8..abadb00fa 100644 --- a/website/assets/js/runtime~main.3d841f46.js +++ b/website/assets/js/runtime~main.e24eaac4.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,c,d,t,f={},r={};function b(e){var a=r[e];if(void 0!==a)return a.exports;var c=r[e]={id:e,loaded:!1,exports:{}};return f[e].call(c.exports,c,c.exports,b),c.loaded=!0,c.exports}b.m=f,b.c=r,e=[],b.O=(a,c,d,t)=>{if(!c){var f=1/0;for(i=0;i=t)&&Object.keys(b.O).every((e=>b.O[e](c[o])))?c.splice(o--,1):(r=!1,t0&&e[i-1][2]>t;i--)e[i]=e[i-1];e[i]=[c,d,t]},b.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return b.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var t=Object.create(null);b.r(t);var f={};a=a||[null,c({}),c([]),c(c)];for(var r=2&d&&e;"object"==typeof r&&!~a.indexOf(r);r=c(r))Object.getOwnPropertyNames(r).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,b.d(t,f),t},b.d=(e,a)=>{for(var c in a)b.o(a,c)&&!b.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((a,c)=>(b.f[c](e,a),a)),[])),b.u=e=>"assets/js/"+({53:"935f2afb",69:"059073b3",214:"61298cc8",266:"a626ceec",273:"b4799182",289:"ab8c744e",459:"611c77b5",1021:"f01c4a09",1094:"74e10ba6",1263:"6bbbbc97",1383:"330e5e62",1459:"a2130fc2",1484:"4a273407",1880:"318f4b2b",1922:"a54020da",2044:"bd7f9487",2327:"800c1403",2570:"5b4ca663",3050:"2461ad02",3113:"ff130930",3118:"992c5be4",3141:"ab525c33",3142:"dc411dd3",3589:"cde0e7e3",3733:"11f39a2f",3741:"f5fbf028",3790:"d48e9a38",3828:"86369c27",4059:"56357698",4129:"3faa71d4",4368:"a94703ab",4381:"ac15eb1d",4659:"27378163",4825:"c81f6b5a",5444:"3448e3c1",5568:"16654c41",5842:"619c8fd2",6472:"8cfa593c",6626:"eb8009f2",6796:"6406880e",6942:"cdfdc496",6950:"3aadb5f1",7014:"b2dd0056",7108:"0090e13a",7511:"212d14e7",7744:"1f48d90f",7918:"17896441",7920:"1a4e3797",8090:"0bc8830e",8164:"33ab50e4",8303:"ee99e688",8467:"87772db6",8510:"c3ccd8cd",8518:"a7bd4aaa",8587:"23dd7564",8626:"ed579555",9053:"25698ad3",9361:"54db8573",9661:"5e95c892",9671:"0e384e19",9910:"edbd0621"}[e]||e)+"."+{53:"198027f6",69:"00169746",214:"f7db448c",266:"f6037b29",273:"366c17bf",289:"0af77619",459:"c1ecfc36",1021:"0bd27114",1094:"2ae764a1",1263:"f85e776c",1383:"69975a4b",1426:"c23d7627",1459:"052f6c08",1484:"bcc68fe5",1772:"61f6592f",1880:"8920e162",1922:"97815500",2044:"802eb5aa",2327:"9bc7dd5a",2570:"824de329",3050:"283d24a9",3113:"c1d9131d",3118:"53db40ea",3141:"c325c860",3142:"b6a05cab",3589:"94ed5144",3733:"d0538b38",3741:"7be71919",3790:"40d0d80b",3828:"7330b736",4059:"3198f616",4129:"09179e24",4368:"b8952552",4381:"471b4cb5",4659:"e01f8776",4825:"a4e43ca1",5444:"988bf4c2",5568:"3fafe7d9",5842:"f0db9345",6472:"ebc6b9e4",6626:"5812346b",6796:"5f43467a",6942:"f19260a9",6945:"8e8e2060",6950:"85aac289",7014:"426eab83",7108:"aeb7b86e",7511:"61b7c43a",7744:"d8ac2903",7918:"acd792fa",7920:"ec211f02",8090:"408acede",8164:"921d2c14",8303:"97bf8553",8467:"c015bb52",8510:"5086c9f1",8518:"45274bc2",8587:"5ccea759",8626:"9c2a17c4",8894:"46125374",9053:"4ce33965",9361:"aafd95d2",9661:"b00730d7",9671:"aaef400e",9910:"513a8948"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},t="website:",b.l=(e,a,c,f)=>{if(d[e])d[e].push(a);else{var r,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i{r.onerror=r.onload=null,clearTimeout(s);var t=d[e];if(delete d[e],r.parentNode&&r.parentNode.removeChild(r),t&&t.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=l.bind(null,r.onerror),r.onload=l.bind(null,r.onload),o&&document.head.appendChild(r)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/gatekeeper-library/website/",b.gca=function(e){return e={17896441:"7918",27378163:"4659",56357698:"4059","935f2afb":"53","059073b3":"69","61298cc8":"214",a626ceec:"266",b4799182:"273",ab8c744e:"289","611c77b5":"459",f01c4a09:"1021","74e10ba6":"1094","6bbbbc97":"1263","330e5e62":"1383",a2130fc2:"1459","4a273407":"1484","318f4b2b":"1880",a54020da:"1922",bd7f9487:"2044","800c1403":"2327","5b4ca663":"2570","2461ad02":"3050",ff130930:"3113","992c5be4":"3118",ab525c33:"3141",dc411dd3:"3142",cde0e7e3:"3589","11f39a2f":"3733",f5fbf028:"3741",d48e9a38:"3790","86369c27":"3828","3faa71d4":"4129",a94703ab:"4368",ac15eb1d:"4381",c81f6b5a:"4825","3448e3c1":"5444","16654c41":"5568","619c8fd2":"5842","8cfa593c":"6472",eb8009f2:"6626","6406880e":"6796",cdfdc496:"6942","3aadb5f1":"6950",b2dd0056:"7014","0090e13a":"7108","212d14e7":"7511","1f48d90f":"7744","1a4e3797":"7920","0bc8830e":"8090","33ab50e4":"8164",ee99e688:"8303","87772db6":"8467",c3ccd8cd:"8510",a7bd4aaa:"8518","23dd7564":"8587",ed579555:"8626","25698ad3":"9053","54db8573":"9361","5e95c892":"9661","0e384e19":"9671",edbd0621:"9910"}[e]||e,b.p+b.u(e)},(()=>{var e={1303:0,532:0};b.f.j=(a,c)=>{var d=b.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var t=new Promise(((c,t)=>d=e[a]=[c,t]));c.push(d[2]=t);var f=b.p+b.u(a),r=new Error;b.l(f,(c=>{if(b.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var t=c&&("load"===c.type?"missing":c.type),f=c&&c.target&&c.target.src;r.message="Loading chunk "+a+" failed.\n("+t+": "+f+")",r.name="ChunkLoadError",r.type=t,r.request=f,d[1](r)}}),"chunk-"+a,a)}},b.O.j=a=>0===e[a];var a=(a,c)=>{var d,t,f=c[0],r=c[1],o=c[2],n=0;if(f.some((a=>0!==e[a]))){for(d in r)b.o(r,d)&&(b.m[d]=r[d]);if(o)var i=o(b)}for(a&&a(c);n{"use strict";var e,a,c,d,t,f={},r={};function b(e){var a=r[e];if(void 0!==a)return a.exports;var c=r[e]={id:e,loaded:!1,exports:{}};return f[e].call(c.exports,c,c.exports,b),c.loaded=!0,c.exports}b.m=f,b.c=r,e=[],b.O=(a,c,d,t)=>{if(!c){var f=1/0;for(i=0;i=t)&&Object.keys(b.O).every((e=>b.O[e](c[o])))?c.splice(o--,1):(r=!1,t0&&e[i-1][2]>t;i--)e[i]=e[i-1];e[i]=[c,d,t]},b.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return b.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var t=Object.create(null);b.r(t);var f={};a=a||[null,c({}),c([]),c(c)];for(var r=2&d&&e;"object"==typeof r&&!~a.indexOf(r);r=c(r))Object.getOwnPropertyNames(r).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,b.d(t,f),t},b.d=(e,a)=>{for(var c in a)b.o(a,c)&&!b.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((a,c)=>(b.f[c](e,a),a)),[])),b.u=e=>"assets/js/"+({53:"935f2afb",69:"059073b3",214:"61298cc8",266:"a626ceec",273:"b4799182",289:"ab8c744e",459:"611c77b5",1021:"f01c4a09",1094:"74e10ba6",1263:"6bbbbc97",1383:"330e5e62",1459:"a2130fc2",1484:"4a273407",1880:"318f4b2b",1922:"a54020da",2044:"bd7f9487",2327:"800c1403",2570:"5b4ca663",3050:"2461ad02",3113:"ff130930",3118:"992c5be4",3141:"ab525c33",3142:"dc411dd3",3589:"cde0e7e3",3733:"11f39a2f",3741:"f5fbf028",3790:"d48e9a38",3828:"86369c27",4059:"56357698",4129:"3faa71d4",4368:"a94703ab",4381:"ac15eb1d",4659:"27378163",4825:"c81f6b5a",5444:"3448e3c1",5568:"16654c41",5842:"619c8fd2",6472:"8cfa593c",6626:"eb8009f2",6796:"6406880e",6942:"cdfdc496",6950:"3aadb5f1",7014:"b2dd0056",7108:"0090e13a",7511:"212d14e7",7744:"1f48d90f",7918:"17896441",7920:"1a4e3797",8090:"0bc8830e",8164:"33ab50e4",8303:"ee99e688",8467:"87772db6",8510:"c3ccd8cd",8518:"a7bd4aaa",8587:"23dd7564",8626:"ed579555",9053:"25698ad3",9361:"54db8573",9661:"5e95c892",9671:"0e384e19",9910:"edbd0621"}[e]||e)+"."+{53:"198027f6",69:"00169746",214:"f7db448c",266:"f6037b29",273:"366c17bf",289:"0af77619",459:"c1ecfc36",1021:"0bd27114",1094:"2ae764a1",1263:"f85e776c",1383:"69975a4b",1426:"c23d7627",1459:"03c28918",1484:"bcc68fe5",1772:"61f6592f",1880:"8920e162",1922:"97815500",2044:"802eb5aa",2327:"9bc7dd5a",2570:"824de329",3050:"283d24a9",3113:"c1d9131d",3118:"53db40ea",3141:"c325c860",3142:"b6a05cab",3589:"94ed5144",3733:"d0538b38",3741:"7be71919",3790:"40d0d80b",3828:"7330b736",4059:"3198f616",4129:"09179e24",4368:"b8952552",4381:"471b4cb5",4659:"e01f8776",4825:"a4e43ca1",5444:"988bf4c2",5568:"3fafe7d9",5842:"f0db9345",6472:"ebc6b9e4",6626:"5812346b",6796:"5f43467a",6942:"f19260a9",6945:"8e8e2060",6950:"85aac289",7014:"426eab83",7108:"aeb7b86e",7511:"61b7c43a",7744:"d8ac2903",7918:"acd792fa",7920:"ec211f02",8090:"408acede",8164:"921d2c14",8303:"97bf8553",8467:"c015bb52",8510:"5086c9f1",8518:"45274bc2",8587:"5ccea759",8626:"9c2a17c4",8894:"46125374",9053:"4ce33965",9361:"aafd95d2",9661:"b00730d7",9671:"aaef400e",9910:"513a8948"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},t="website:",b.l=(e,a,c,f)=>{if(d[e])d[e].push(a);else{var r,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i{r.onerror=r.onload=null,clearTimeout(s);var t=d[e];if(delete d[e],r.parentNode&&r.parentNode.removeChild(r),t&&t.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=l.bind(null,r.onerror),r.onload=l.bind(null,r.onload),o&&document.head.appendChild(r)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/gatekeeper-library/website/",b.gca=function(e){return e={17896441:"7918",27378163:"4659",56357698:"4059","935f2afb":"53","059073b3":"69","61298cc8":"214",a626ceec:"266",b4799182:"273",ab8c744e:"289","611c77b5":"459",f01c4a09:"1021","74e10ba6":"1094","6bbbbc97":"1263","330e5e62":"1383",a2130fc2:"1459","4a273407":"1484","318f4b2b":"1880",a54020da:"1922",bd7f9487:"2044","800c1403":"2327","5b4ca663":"2570","2461ad02":"3050",ff130930:"3113","992c5be4":"3118",ab525c33:"3141",dc411dd3:"3142",cde0e7e3:"3589","11f39a2f":"3733",f5fbf028:"3741",d48e9a38:"3790","86369c27":"3828","3faa71d4":"4129",a94703ab:"4368",ac15eb1d:"4381",c81f6b5a:"4825","3448e3c1":"5444","16654c41":"5568","619c8fd2":"5842","8cfa593c":"6472",eb8009f2:"6626","6406880e":"6796",cdfdc496:"6942","3aadb5f1":"6950",b2dd0056:"7014","0090e13a":"7108","212d14e7":"7511","1f48d90f":"7744","1a4e3797":"7920","0bc8830e":"8090","33ab50e4":"8164",ee99e688:"8303","87772db6":"8467",c3ccd8cd:"8510",a7bd4aaa:"8518","23dd7564":"8587",ed579555:"8626","25698ad3":"9053","54db8573":"9361","5e95c892":"9661","0e384e19":"9671",edbd0621:"9910"}[e]||e,b.p+b.u(e)},(()=>{var e={1303:0,532:0};b.f.j=(a,c)=>{var d=b.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var t=new Promise(((c,t)=>d=e[a]=[c,t]));c.push(d[2]=t);var f=b.p+b.u(a),r=new Error;b.l(f,(c=>{if(b.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var t=c&&("load"===c.type?"missing":c.type),f=c&&c.target&&c.target.src;r.message="Loading chunk "+a+" failed.\n("+t+": "+f+")",r.name="ChunkLoadError",r.type=t,r.request=f,d[1](r)}}),"chunk-"+a,a)}},b.O.j=a=>0===e[a];var a=(a,c)=>{var d,t,f=c[0],r=c[1],o=c[2],n=0;if(f.some((a=>0!==e[a]))){for(d in r)b.o(r,d)&&(b.m[d]=r[d]);if(o)var i=o(b)}for(a&&a(c);n