Example #1
0
    def test_ap_ingress_batch_start(
        self,
        request,
        kube_apis,
        crd_ingress_controller_with_ap,
        ap_ingress_setup,
        ingress_controller_prerequisites,
        test_namespace,
    ):
        """
        Pod startup time with AP Ingress
        """
        print(
            "------------- Run test for AP policy: dataguard-alarm --------------"
        )
        print(
            f"Request URL: {ap_ingress_setup.req_url} and Host: {ap_ingress_setup.ingress_host}"
        )

        ensure_response_from_backend(ap_ingress_setup.req_url,
                                     ap_ingress_setup.ingress_host,
                                     check404=True)

        total_ing = int(request.config.getoption("--batch-resources"))

        manifest = f"{TEST_DATA}/appprotect/appprotect-ingress.yaml"
        for i in range(1, total_ing + 1):
            with open(manifest) as f:
                doc = yaml.safe_load(f)
                doc["metadata"]["name"] = f"appprotect-ingress-{i}"
                doc["spec"]["rules"][0]["host"] = f"appprotect-{i}.example.com"
                create_ingress(kube_apis.networking_v1, test_namespace, doc)
        print(f"Total resources deployed is {total_ing}")
        wait_before_test()
        ic_ns = ingress_controller_prerequisites.namespace
        scale_deployment(kube_apis.v1, kube_apis.apps_v1_api, "nginx-ingress",
                         ic_ns, 0)
        while get_pods_amount(kube_apis.v1, ic_ns) is not 0:
            print(f"Number of replicas not 0, retrying...")
            wait_before_test()
        num = scale_deployment(kube_apis.v1, kube_apis.apps_v1_api,
                               "nginx-ingress", ic_ns, 1)

        assert (get_total_ingresses(ap_ingress_setup.metrics_url, "nginx")
                == str(total_ing + 1) and get_last_reload_status(
                    ap_ingress_setup.metrics_url, "nginx") == "1")

        for i in range(1, total_ing + 1):
            delete_ingress(kube_apis.networking_v1, f"appprotect-ingress-{i}",
                           test_namespace)

        assert num is None
    def test_ap_perf_multiple_ingress(
        self,
        kube_apis,
        ingress_controller_prerequisites,
        ingress_controller_endpoint,
        crd_ingress_controller_with_ap,
        appprotect_setup,
        enable_prometheus_port,
        test_namespace,
    ):
        """
        Test reload times for creating AP ingress while a simple ingress exists.
        """

        src1_ing_yaml = f"{TEST_DATA}/appprotect/appprotect-ingress.yaml"
        print(src1_ing_yaml)
        src2_ing_yaml = os.path.join(os.path.dirname(__file__),
                                     "../data/non-ap-ingress.yaml")
        print(src2_ing_yaml)

        with open(src2_ing_yaml) as f:
            doc = yaml.safe_load(f)
        # create ingress without AP annotation
        create_ingress(kube_apis.extensions_v1_beta1, test_namespace, doc)
        wait_before_test(10)
        #  create ingress with AP annotations
        create_ingress_with_ap_annotations(kube_apis, src1_ing_yaml,
                                           test_namespace, ap_policy, "True",
                                           "True", "127.0.0.1:514")
        ingress_host = get_first_ingress_host_from_yaml(src1_ing_yaml)

        print(
            "--------- Run test while AppProtect module is enabled with correct policy ---------"
        )
        ensure_response_from_backend(appprotect_setup.req_url, ingress_host)
        wait_before_test(30)
        response = requests.get(appprotect_setup.req_url + "/<script>",
                                headers={"host": ingress_host},
                                verify=False)
        print(response.text)
        self.collect_prom_reload_metrics(
            reload_ap_with_ingress,
            "creating AP ingress alongside a simple ingress",
            ingress_controller_endpoint.public_ip,
            ingress_controller_endpoint.metrics_port,
        )
        delete_items_from_yaml(kube_apis, src1_ing_yaml, test_namespace)
        delete_items_from_yaml(kube_apis, src2_ing_yaml, test_namespace)
        assert_invalid_responses(response)
    def test_ap_multi_sec_logs(self, kube_apis, crd_ingress_controller_with_ap,
                               appprotect_setup, test_namespace):
        """
        Test corresponding log entries with multiple log destinations (in this case, two syslog servers)
        """
        src_syslog_yaml = f"{TEST_DATA}/appprotect/syslog.yaml"
        src_syslog2_yaml = f"{TEST_DATA}/appprotect/syslog2.yaml"
        log_loc = f"/var/log/messages"

        print("Create two syslog servers")
        create_items_from_yaml(kube_apis, src_syslog_yaml, test_namespace)
        create_items_from_yaml(kube_apis, src_syslog2_yaml, test_namespace)

        syslog_ep = get_service_endpoint(kube_apis, "syslog-svc",
                                         test_namespace)
        syslog2_ep = get_service_endpoint(kube_apis, "syslog2-svc",
                                          test_namespace)

        syslog_pod = kube_apis.v1.list_namespaced_pod(
            test_namespace).items[-2].metadata.name
        syslog2_pod = kube_apis.v1.list_namespaced_pod(
            test_namespace).items[-1].metadata.name

        with open(src_ing_yaml) as f:
            doc = yaml.safe_load(f)

            doc["metadata"]["annotations"][
                "appprotect.f5.com/app-protect-policy"] = ap_policy
            doc["metadata"]["annotations"][
                "appprotect.f5.com/app-protect-enable"] = "True"
            doc["metadata"]["annotations"][
                "appprotect.f5.com/app-protect-security-log-enable"] = "True"

            # both lists need to be the same length, if one of the referenced configs is invalid/non-existent then no logconfs are applied.
            doc["metadata"]["annotations"][
                "appprotect.f5.com/app-protect-security-log"] = f"{test_namespace}/logconf,{test_namespace}/logconf"

            doc["metadata"]["annotations"][
                "appprotect.f5.com/app-protect-security-log-destination"] = f"syslog:server={syslog_ep}:514,syslog:server={syslog2_ep}:514"

        create_ingress(kube_apis.extensions_v1_beta1, test_namespace, doc)

        ingress_host = get_first_ingress_host_from_yaml(src_ing_yaml)

        ensure_response_from_backend(appprotect_setup.req_url,
                                     ingress_host,
                                     check404=True)

        print("----------------------- Send request ----------------------")
        response = requests.get(appprotect_setup.req_url + "/<script>",
                                headers={"host": ingress_host},
                                verify=False)
        print(response.text)
        log_contents = ""
        log2_contents = ""
        retry = 0
        while ("ASM:attack_type" not in log_contents
               and "ASM:attack_type" not in log2_contents and retry <= 30):
            log_contents = get_file_contents(kube_apis.v1, log_loc, syslog_pod,
                                             test_namespace)
            log2_contents = get_file_contents(kube_apis.v1, log_loc,
                                              syslog2_pod, test_namespace)
            retry += 1
            wait_before_test(1)
            print(f"Security log not updated, retrying... #{retry}")

        delete_items_from_yaml(kube_apis, src_ing_yaml, test_namespace)
        delete_items_from_yaml(kube_apis, src_syslog_yaml, test_namespace)
        delete_items_from_yaml(kube_apis, src_syslog2_yaml, test_namespace)

        assert_invalid_responses(response)
        # check logs in dest. #1 i.e. syslog server #1
        assert (
            f'ASM:attack_type="Non-browser Client,Abuse of Functionality,Cross Site Scripting (XSS)"'
            in log_contents and f'severity="Critical"' in log_contents
            and f'request_status="blocked"' in log_contents
            and f'outcome="REJECTED"' in log_contents)
        # check logs in dest. #2 i.e. syslog server #2
        assert (
            f'ASM:attack_type="Non-browser Client,Abuse of Functionality,Cross Site Scripting (XSS)"'
            in log2_contents and f'severity="Critical"' in log2_contents
            and f'request_status="blocked"' in log2_contents
            and f'outcome="REJECTED"' in log2_contents)