From 521823f874a1a60a2989d1eb4afcaf2a5a930ba4 Mon Sep 17 00:00:00 2001 From: Maximilian Bischoff Date: Fri, 21 Aug 2020 07:24:19 +0200 Subject: [PATCH] Limit length of created service names (#122) * Fix illuminatio generating illegal service names --- e2e-manifests/expected/max-length-labels.yml | 4 ++++ e2e-manifests/max-length-labels.yml | 18 ++++++++++++++++++ src/illuminatio/illuminatio_runner.py | 16 ++-------------- src/illuminatio/k8s_util.py | 6 ++++-- src/illuminatio/test_orchestrator.py | 16 ++++------------ tests/test_e2e.py | 6 +++++- 6 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 e2e-manifests/expected/max-length-labels.yml create mode 100644 e2e-manifests/max-length-labels.yml diff --git a/e2e-manifests/expected/max-length-labels.yml b/e2e-manifests/expected/max-length-labels.yml new file mode 100644 index 0000000..f402bae --- /dev/null +++ b/e2e-manifests/expected/max-length-labels.yml @@ -0,0 +1,4 @@ +max-length-labels:253-characters-or-less.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/63-characters-or-less_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=63-characters-or-less_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: + max-length-labels:253-characters-or-less.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/63-characters-or-less_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=63-characters-or-less_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: + -*: + success: true diff --git a/e2e-manifests/max-length-labels.yml b/e2e-manifests/max-length-labels.yml new file mode 100644 index 0000000..cb2ba78 --- /dev/null +++ b/e2e-manifests/max-length-labels.yml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: max-length-labels + labels: + illuminatio-e2e: max-length-labels +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: web-deny-all + namespace: max-length-labels +spec: + podSelector: + matchLabels: + 253-characters-or-less.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/63-characters-or-less_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: + 63-characters-or-less_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ingress: [] diff --git a/src/illuminatio/illuminatio_runner.py b/src/illuminatio/illuminatio_runner.py index 73b9918..652ede9 100644 --- a/src/illuminatio/illuminatio_runner.py +++ b/src/illuminatio/illuminatio_runner.py @@ -6,7 +6,6 @@ import json import logging import os -import socket import subprocess import time import platform @@ -167,25 +166,14 @@ def run_tests_for_target(network_ns, ports, target): LOGGER.info("Target: %s", target) port_on_nums = {port.replace("-", ""): port for port in ports} port_string = ",".join(port_on_nums.keys()) - # ToDo do we really need this -> we know the service already and could use the cluster IP - # DNS could be blocked - # Only IPv4 currently -> https://docs.python.org/3/library/socket.html#socket.getaddrinfo - svc_dns_entry = get_domain_name_for(target) - LOGGER.info(svc_dns_entry) - try: - svc_ip = socket.gethostbyname(svc_dns_entry) - except (socket.gaierror, socket.herror) as error: - return {port_string: {"success": False, "error": error}} - - LOGGER.info("Service IP: %s for Service: %s", svc_ip, target) ipv6_arg = "" - if ipaddress.ip_address(svc_ip).version == 6: + if ipaddress.ip_address(target).version == 6: ipv6_arg = "-6" nm_scanner = nmap.PortScanner() with Namespace(network_ns, "net"): - nm_scanner.scan(svc_ip, arguments=f"-n -Pn -p {port_string} {ipv6_arg}") + nm_scanner.scan(target, arguments=f"-n -Pn -p {port_string} {ipv6_arg}") LOGGER.info("Ran nmap with cmd %s", nm_scanner.command_line()) return extract_results_from_nmap(nm_scanner, port_on_nums, target) diff --git a/src/illuminatio/k8s_util.py b/src/illuminatio/k8s_util.py index f88663f..3325000 100644 --- a/src/illuminatio/k8s_util.py +++ b/src/illuminatio/k8s_util.py @@ -89,12 +89,14 @@ def create_pod_manifest(host: Host, additional_labels, generate_name, container) def create_service_manifest( - host: Host, additional_selector_labels, svc_labels, name, port_nums + host: Host, additional_selector_labels, svc_labels, port_nums ): """ Creates and returns a service manifest with given parameters """ - svc_meta = k8s.client.V1ObjectMeta(name=name, namespace=host.namespace) + svc_meta = k8s.client.V1ObjectMeta( + generate_name="illuminatio-test-target", namespace=host.namespace + ) svc = k8s.client.V1Service(api_version="v1", kind="Service", metadata=svc_meta) svc.spec = k8s.client.V1ServiceSpec() svc.spec.selector = {k: v for k, v in host.pod_labels.items()} diff --git a/src/illuminatio/test_orchestrator.py b/src/illuminatio/test_orchestrator.py index a28ca5b..8538436 100644 --- a/src/illuminatio/test_orchestrator.py +++ b/src/illuminatio/test_orchestrator.py @@ -262,21 +262,13 @@ def _get_target_names_creating_them_if_missing( int(port.replace("-", "")) for port in port_dict_per_host[host_string].values() ] - # ToDo we should use the cluser ip instead of the DNS names - # so we don't need the lookups - service_name = "svc-%s" % convert_to_resource_name(host.to_identifier()) svc = create_service_manifest( host, {pod_labels_tuple[0]: pod_labels_tuple[1]}, {ROLE_LABEL: "test_target_svc", CLEANUP_LABEL: CLEANUP_ALWAYS}, - service_name, target_ports, ) target_pod_namespace = host.namespace - service_names_per_host[host_string] = "%s:%s" % ( - target_pod_namespace, - service_name, - ) resp = api.create_namespaced_pod( namespace=target_pod_namespace, body=target_pod ) @@ -289,6 +281,7 @@ def _get_target_names_creating_them_if_missing( self.logger.error("Failed to create pod! Resp: %s", resp) resp = api.create_namespaced_service(namespace=host.namespace, body=svc) if isinstance(resp, k8s.client.V1Service): + service_names_per_host[host_string] = resp.spec.cluster_ip self.logger.debug( "Target svc %s created succesfully", resp.metadata.name ) @@ -296,10 +289,9 @@ def _get_target_names_creating_them_if_missing( else: self.logger.error("Failed to create target svc! Resp: %s", resp) else: - service_names_per_host[host_string] = "%s:%s" % ( - services_for_host[0].metadata.namespace, - services_for_host[0].metadata.name, - ) + service_names_per_host[host_string] = services_for_host[ + 0 + ].spec.cluster_ip return service_names_per_host, port_dict_per_host def _find_or_create_cluster_resources_for_cases( diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 0d3eb4a..04860c5 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -46,7 +46,11 @@ def clean_cluster(core_v1): @pytest.mark.parametrize( "e2e_test_case", - ["01-deny-all-traffic-to-an-application", "labels-with-all-legal-characters"], + [ + "01-deny-all-traffic-to-an-application", + "labels-with-all-legal-characters", + "max-length-labels", + ], ) @pytest.mark.e2e def test__e2e__clean_setup__results_are_expected(e2e_test_case, api_client, apps_v1):