From 0dabdc4b7b6b0cf50b80fbd115770f3331d46b7c Mon Sep 17 00:00:00 2001 From: Yoan Moscatelli Date: Fri, 29 Nov 2024 10:14:23 +0000 Subject: [PATCH] :lock: first iteration ingress hardenning --- CHANGELOG.md | 5 ++ buildchain/buildchain/codegen.py | 19 +++-- buildchain/buildchain/salt_tree.py | 9 +++ .../cluster_and_service_configuration.rst | 69 ++++++++++++++++++- .../config/ingress-controller.yaml.j2 | 11 +++ .../deployed/chart.sls | 17 ----- .../deployed/config-map.sls | 29 ++++++++ .../deployed/init.sls | 2 + .../deployed/service-configuration.sls | 37 ++++++++++ .../config/ingress-controller.yaml.j2 | 3 + .../deployed/service-configuration.sls | 2 +- 11 files changed, 175 insertions(+), 28 deletions(-) create mode 100644 salt/metalk8s/addons/nginx-ingress-control-plane/config/ingress-controller.yaml.j2 create mode 100644 salt/metalk8s/addons/nginx-ingress-control-plane/deployed/config-map.sls create mode 100644 salt/metalk8s/addons/nginx-ingress-control-plane/deployed/service-configuration.sls diff --git a/CHANGELOG.md b/CHANGELOG.md index b54b23db7f..e3029b8fd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Release 128.0.1 (in development) +### Enhancements + +- Only use modern Ciphers in Ingress configuration + (PR[#4488](https://github.com/scality/metalk8s/pull/4488)) + ## Release 128.0.0 ### Enhancements diff --git a/buildchain/buildchain/codegen.py b/buildchain/buildchain/codegen.py index e44b2bdf50..3cbb1a2f82 100644 --- a/buildchain/buildchain/codegen.py +++ b/buildchain/buildchain/codegen.py @@ -128,6 +128,7 @@ def codegen_chart_fluent_bit() -> types.TaskDict: def codegen_chart_ingress_nginx() -> types.TaskDict: """Generate the SLS file for NGINX Ingress using the chart render script.""" chart_dir = constants.CHART_ROOT / "ingress-nginx" + namespace = "metalk8s-ingress" actions = [] file_dep = list(utils.git_ls(chart_dir)) file_dep.append(constants.CHART_RENDER_SCRIPT) @@ -136,12 +137,13 @@ def codegen_chart_ingress_nginx() -> types.TaskDict: target_sls = ( constants.ROOT / "salt/metalk8s/addons/nginx-ingress/deployed/chart.sls" ) - value_file = constants.CHART_ROOT / "ingress-nginx.yaml" + name = "ingress-nginx" + value_file = constants.CHART_ROOT / f"{name}.yaml" actions.append( doit.action.CmdAction( - f"{constants.CHART_RENDER_CMD} ingress-nginx {value_file} {chart_dir} " - f"--namespace metalk8s-ingress --remove-manifest ConfigMap " - f"ingress-nginx-controller " + f"{constants.CHART_RENDER_CMD} {name} {value_file} {chart_dir} " + f"--namespace {namespace} --remove-manifest ConfigMap " + f"{name}-controller " f"--output {target_sls}", cwd=constants.ROOT, ) @@ -154,11 +156,14 @@ def codegen_chart_ingress_nginx() -> types.TaskDict: / "salt/metalk8s/addons/nginx-ingress-control-plane" / "deployed/chart.sls" ) - value_file = constants.CHART_ROOT / "ingress-nginx-control-plane.yaml" + name = "ingress-nginx-control-plane" + value_file = constants.CHART_ROOT / f"{name}.yaml" actions.append( doit.action.CmdAction( - f"{constants.CHART_RENDER_CMD} ingress-nginx-control-plane {value_file} " - f"{chart_dir} --namespace metalk8s-ingress --output {target_sls}", + f"{constants.CHART_RENDER_CMD} {name} {value_file} {chart_dir} " + f"--namespace {namespace} --remove-manifest ConfigMap " + f"{name}-controller " + f"--output {target_sls}", cwd=constants.ROOT, ) ) diff --git a/buildchain/buildchain/salt_tree.py b/buildchain/buildchain/salt_tree.py index e588befb2f..c9cd52bb1f 100644 --- a/buildchain/buildchain/salt_tree.py +++ b/buildchain/buildchain/salt_tree.py @@ -443,6 +443,15 @@ def task(self) -> types.TaskDict: Path("salt/metalk8s/addons/nginx-ingress-control-plane/certs/server.sls"), Path("salt/metalk8s/addons/nginx-ingress-control-plane/deployed/init.sls"), Path("salt/metalk8s/addons/nginx-ingress-control-plane/deployed/chart.sls"), + Path("salt/metalk8s/addons/nginx-ingress-control-plane/deployed/config-map.sls"), + Path( + "salt/metalk8s/addons/nginx-ingress-control-plane/deployed/", + "service-configuration.sls", + ), + Path( + "salt/metalk8s/addons/nginx-ingress-control-plane/config/", + "ingress-controller.yaml.j2", + ), Path("salt/metalk8s/addons/nginx-ingress-control-plane/deployed/tls-secret.sls"), Path("salt/metalk8s/backup/certs/ca.sls"), Path("salt/metalk8s/backup/certs/server.sls"), diff --git a/docs/operation/cluster_and_service_configuration.rst b/docs/operation/cluster_and_service_configuration.rst index f9352d19fc..a4d05e2665 100644 --- a/docs/operation/cluster_and_service_configuration.rst +++ b/docs/operation/cluster_and_service_configuration.rst @@ -142,6 +142,23 @@ The default Shell UI workload plane configuration values are specified below: .. literalinclude:: ../../salt/metalk8s/addons/ui/config/workloadplane-shell-ui-config.yaml.j2 :lines: 3- +Ingress Control Plane Default Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The default Control Plane Ingress Controller configuration values +are specified below: + +.. literalinclude:: ../../salt/metalk8s/addons/nginx-ingress-control-plane/config/ingress-controller.yaml.j2 + :lines: 8-11 + +Ingress Workload Plane Default Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The default Workload Plane Ingress Controller configuration values +are specified below: + +.. literalinclude:: ../../salt/metalk8s/addons/nginx-ingress/config/ingress-controller.yaml.j2 + :lines: 8-11 Service Configurations Customization ------------------------------------ @@ -163,6 +180,28 @@ under the key ``data.config\.yaml``: metalk8s-ingress-controller-config +The following documentation is not exhaustive and is just here to give +some hints on basic usage, for more details or advanced +configuration, see the official `Nginx Ingress Controller documentation`_. + +.. _Nginx Ingress Controller documentation: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/ + +Control plane Ingress Controller Configuration Customization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Same as the Workload plane Ingress Controller, Control Plane can be overridden +by editing its Cluster and Service ConfigMap +``metalk8s-ingress-control-plane-controller-config`` +in namespace ``metalk8s-ingress`` +under the key ``data.config\.yaml``: + + .. code-block:: shell + + root@bootstrap $ kubectl --kubeconfig /etc/kubernetes/admin.conf \ + edit configmap -n metalk8s-ingress \ + metalk8s-ingress-control-plane-controller-config + + The following documentation is not exhaustive and is just here to give some hints on basic usage, for more details or advanced configuration, see the official `Nginx Ingress Controller documentation`_. @@ -186,6 +225,29 @@ HTTP2 can be disabled by setting ``use-http2`` to ``false``: config: use-http2: "false" +Modify authorized Ciphers +""""""""""""""""""""""""" + +Strong cipher configurations may not allow legacy user agents or user agents +with weak configurations to connect to your site. If your server must also +pass to a legacy upstream server, this may prevent it from being able to +negotiate a cipher upstream. + +If you use an old client that does not support modern ciphers, you can use the +ones provided by the CIS Nginx Benchmark for example: + + .. code-block:: yaml + + apiVersion: v1 + kind: ConfigMap + data: + config.yaml: |- + apiVersion: addons.metalk8s.scality.com/v1alpha2 + kind: IngressControllerConfig + spec: + config: + ssl-ciphers: "ALL:!EXP:!NULL:!ADH:!LOW:!SSLv2:!SSLv3:!MD5:!RC4" + Applying configuration """""""""""""""""""""" @@ -195,9 +257,10 @@ then be applied with Salt. .. parsed-literal:: root\@bootstrap $ kubectl exec --kubeconfig /etc/kubernetes/admin.conf \\ - -n kube-system -c salt-master salt-master-bootstrap -- \\ - salt-run state.sls \\ - metalk8s.addons.nginx-ingress.deployed \\ + $(kubectl --kubeconfig /etc/kubernetes/admin.conf \\ + get pod -n kube-system -l app=salt-master -o name) \\ + -n kube-system -c salt-master -- \\ + salt-run state.sls metalk8s.addons.nginx-ingress.deployed \\ saltenv=metalk8s-|version| diff --git a/salt/metalk8s/addons/nginx-ingress-control-plane/config/ingress-controller.yaml.j2 b/salt/metalk8s/addons/nginx-ingress-control-plane/config/ingress-controller.yaml.j2 new file mode 100644 index 0000000000..accad03a8d --- /dev/null +++ b/salt/metalk8s/addons/nginx-ingress-control-plane/config/ingress-controller.yaml.j2 @@ -0,0 +1,11 @@ +#!jinja|yaml + +# Defaults for configuration of Ingress Controller +apiVersion: addons.metalk8s.scality.com/v1alpha2 +kind: IngressControllerConfig +spec: + config: + allow-snippet-annotations: 'true' + hide-headers: 'Server,X-Powered-By' + ssl-ciphers: 'EECDH+AESGCM:EDH+AESGCM' + ssl-protocols: 'TLSv1.2 TLSv1.3' diff --git a/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/chart.sls b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/chart.sls index 889579c38e..ec14b94fcf 100644 --- a/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/chart.sls +++ b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/chart.sls @@ -23,23 +23,6 @@ metadata: name: ingress-nginx-control-plane namespace: metalk8s-ingress --- -apiVersion: v1 -data: - allow-snippet-annotations: 'true' -kind: ConfigMap -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: ingress-nginx-control-plane - app.kubernetes.io/managed-by: salt - app.kubernetes.io/name: ingress-nginx - app.kubernetes.io/part-of: metalk8s - app.kubernetes.io/version: 1.10.3 - helm.sh/chart: ingress-nginx-4.10.3 - heritage: metalk8s - name: ingress-nginx-control-plane-controller - namespace: metalk8s-ingress ---- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/config-map.sls b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/config-map.sls new file mode 100644 index 0000000000..7a09502914 --- /dev/null +++ b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/config-map.sls @@ -0,0 +1,29 @@ +{%- set ingress_control_plane_controller_defaults = salt.slsutil.renderer( + 'salt://metalk8s/addons/nginx-ingress-control-plane/config/ingress-controller.yaml.j2', saltenv=saltenv + ) +%} + +{%- set ingress_control_plane_controller = salt.metalk8s_service_configuration.get_service_conf( + 'metalk8s-ingress', 'metalk8s-ingress-control-plane-controller-config', ingress_control_plane_controller_defaults + ) +%} + +Create Control Plane Ingress Controller configuration Config Map: + metalk8s_kubernetes.object_present: + - manifest: + apiVersion: v1 + kind: ConfigMap + metadata: + name: ingress-nginx-control-plane-controller + namespace: metalk8s-ingress + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx-control-plane + app.kubernetes.io/managed-by: salt + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: metalk8s + heritage: metalk8s + annotations: + ingressclass.kubernetes.io/is-default-class: "true" + data: + {{ ingress_control_plane_controller.spec.config | yaml(False) | indent(10) }} diff --git a/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/init.sls b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/init.sls index c1a259eee6..b202872be4 100644 --- a/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/init.sls +++ b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/init.sls @@ -2,3 +2,5 @@ include: - metalk8s.addons.nginx-ingress.deployed.namespace - .tls-secret - .chart + - .service-configuration + - .config-map diff --git a/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/service-configuration.sls b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/service-configuration.sls new file mode 100644 index 0000000000..a18ca538b9 --- /dev/null +++ b/salt/metalk8s/addons/nginx-ingress-control-plane/deployed/service-configuration.sls @@ -0,0 +1,37 @@ +include: + - metalk8s.addons.nginx-ingress.deployed.namespace + +{%- set namespace = 'metalk8s-ingress' %} +{%- set name = 'metalk8s-ingress-control-plane-controller-config' %} + +{%- set ingress_service_config = salt.metalk8s_kubernetes.get_object( + kind='ConfigMap', + apiVersion='v1', + namespace=namespace, + name=name + ) +%} + +{%- if ingress_service_config is none %} + +Create Ingress ServiceConfiguration (metalk8s-ingress/metalk8s-ingress-control-plane-controller-config): + metalk8s_kubernetes.object_present: + - manifest: + apiVersion: v1 + kind: ConfigMap + metadata: + name: {{ name }} + namespace: {{ namespace }} + data: + config.yaml: |- + apiVersion: addons.metalk8s.scality.com/v1alpha2 + kind: IngressControllerConfig + spec: {} + + +{%- else %} + +Ingress Control Plane ServiceConfiguration already exists: + test.succeed_without_changes: [] + +{%- endif %} \ No newline at end of file diff --git a/salt/metalk8s/addons/nginx-ingress/config/ingress-controller.yaml.j2 b/salt/metalk8s/addons/nginx-ingress/config/ingress-controller.yaml.j2 index 2aa5243d7d..accad03a8d 100644 --- a/salt/metalk8s/addons/nginx-ingress/config/ingress-controller.yaml.j2 +++ b/salt/metalk8s/addons/nginx-ingress/config/ingress-controller.yaml.j2 @@ -6,3 +6,6 @@ kind: IngressControllerConfig spec: config: allow-snippet-annotations: 'true' + hide-headers: 'Server,X-Powered-By' + ssl-ciphers: 'EECDH+AESGCM:EDH+AESGCM' + ssl-protocols: 'TLSv1.2 TLSv1.3' diff --git a/salt/metalk8s/addons/nginx-ingress/deployed/service-configuration.sls b/salt/metalk8s/addons/nginx-ingress/deployed/service-configuration.sls index 9b2aa6215f..340b0f221a 100644 --- a/salt/metalk8s/addons/nginx-ingress/deployed/service-configuration.sls +++ b/salt/metalk8s/addons/nginx-ingress/deployed/service-configuration.sls @@ -31,7 +31,7 @@ Create Ingress ServiceConfiguration (metalk8s-ingress/metalk8s-ingress-controlle {%- else %} -Ingress ServiceConfiguration already exists: +Ingress Workload Plane ServiceConfiguration already exists: test.succeed_without_changes: [] {%- endif %}