Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve NAP DoS tests #2996

Merged
merged 6 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions tests/suite/dos_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import os
import subprocess

from kubernetes.client import CoreV1Api
from kubernetes.stream import stream
from suite.resources_utils import get_file_contents, wait_before_test
Expand Down Expand Up @@ -74,3 +77,31 @@ def get_admd_s_contents(v1: CoreV1Api, pod_name, pod_namespace, time):
)
admd_contents = str(resp)
return admd_contents


def clean_good_bad_clients():
command = "exec ps -aux | grep good_clients_xff.sh | awk '{print $2}' | xargs kill -9"

subprocess.Popen(
[command],
preexec_fn=os.setsid,
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)

command = "exec ps -aux | grep bad_clients_xff.sh | awk '{print $2}' | xargs kill -9"
subprocess.Popen(
[command],
preexec_fn=os.setsid,
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)


def print_admd_log(log):
matches = ["ADMD", "DAEMONLESS"]
for line in log.splitlines():
if any(x in line for x in matches):
print(line)
82 changes: 12 additions & 70 deletions tests/suite/test_dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
delete_dos_policy,
delete_dos_protected,
)
from suite.dos_utils import check_learning_status_with_admd_s, find_in_log, log_content_to_dic
from suite.dos_utils import (
check_learning_status_with_admd_s,
clean_good_bad_clients,
find_in_log,
log_content_to_dic,
print_admd_log,
)
from suite.resources_utils import (
clear_file_contents,
create_dos_arbitrator,
Expand All @@ -27,7 +33,6 @@
ensure_response_from_backend,
get_file_contents,
get_ingress_nginx_template_conf,
get_pods_amount,
get_pods_amount_with_name,
get_test_file_name,
nginx_reload,
Expand Down Expand Up @@ -77,6 +82,9 @@ def dos_setup(
:return: DosSetup
"""

# Clean old scripts if still running
clean_good_bad_clients()

print(f"------------- Replace ConfigMap --------------")
replace_configmap_from_yaml(
kube_apis.v1,
Expand Down Expand Up @@ -125,6 +133,7 @@ def fin():
delete_common_app(kube_apis, "dos", test_namespace)
delete_items_from_yaml(kube_apis, src_sec_yaml, test_namespace)
write_to_json(f"reload-{get_test_file_name(request.node.fspath)}.json", reload_times)
clean_good_bad_clients()

request.addfinalizer(fin)

Expand All @@ -140,6 +149,7 @@ def fin():
f"-enable-custom-resources",
f"-enable-app-protect-dos",
f"-v=3",
f"-app-protect-dos-debug",
]
}
],
Expand Down Expand Up @@ -233,74 +243,6 @@ def test_dos_sec_logs_on(
assert f'vs_name="{test_namespace}/dos-protected/name"' in log_contents
assert "bad_actor" in log_contents

def test_dos_under_attack_no_learning(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need this anymore?

self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller_with_dos, dos_setup, test_namespace
):
"""
Test App Protect Dos: Block bad clients attack
"""
log_loc = f"/var/log/messages"
print("----------------------- Get syslog pod name ----------------------")
syslog_pod = self.getPodNameThatContains(kube_apis, ingress_controller_prerequisites.namespace, "syslog")
assert "syslog" in syslog_pod
clear_file_contents(kube_apis.v1, log_loc, syslog_pod, ingress_controller_prerequisites.namespace)

print("------------------------- Deploy ingress -----------------------------")
create_ingress_with_dos_annotations(kube_apis, src_ing_yaml, test_namespace, test_namespace + "/dos-protected")
ingress_host = get_first_ingress_host_from_yaml(src_ing_yaml)

print("------------------------- Attack -----------------------------")
wait_before_test(10)
print("start bad clients requests")
p_attack = subprocess.Popen(
[f"exec {TEST_DATA}/dos/bad_clients_xff.sh {ingress_host} {dos_setup.req_url}"],
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)

print("Attack for 30 seconds")
wait_before_test(30)

print("Stop Attack")
p_attack.terminate()

print("wait max 140 seconds after attack stop, to get attack ended")
find_in_log(
kube_apis,
log_loc,
syslog_pod,
ingress_controller_prerequisites.namespace,
140,
'attack_event="Attack ended"',
)

log_contents = get_file_contents(kube_apis.v1, log_loc, syslog_pod, ingress_controller_prerequisites.namespace)
log_info_dic = log_content_to_dic(log_contents)

# Analyze the log
no_attack = False
attack_started = False
under_attack = False
attack_ended = False
for log in log_info_dic:
# Start with no attack
if log["attack_event"] == "No Attack" and int(log["dos_attack_id"]) == 0 and not no_attack:
no_attack = True
# Attack started
elif log["attack_event"] == "Attack started" and int(log["dos_attack_id"]) > 0 and not attack_started:
attack_started = True
# Under attack
elif log["attack_event"] == "Under Attack" and int(log["dos_attack_id"]) > 0 and not under_attack:
under_attack = True
# Attack ended
elif log["attack_event"] == "Attack ended" and int(log["dos_attack_id"]) > 0 and not attack_ended:
attack_ended = True

delete_items_from_yaml(kube_apis, src_ing_yaml, test_namespace)

assert no_attack and attack_started and under_attack and attack_ended

def test_dos_under_attack_with_learning(
self, kube_apis, ingress_controller_prerequisites, crd_ingress_controller_with_dos, dos_setup, test_namespace
):
Expand Down
14 changes: 10 additions & 4 deletions tests/suite/test_virtual_server_dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
delete_dos_policy,
delete_dos_protected,
)
from suite.dos_utils import check_learning_status_with_admd_s, find_in_log, log_content_to_dic
from suite.dos_utils import (
check_learning_status_with_admd_s,
clean_good_bad_clients,
find_in_log,
log_content_to_dic,
print_admd_log,
)
from suite.resources_utils import (
clear_file_contents,
create_example_app,
Expand Down Expand Up @@ -100,6 +106,8 @@ def dos_setup(
:return: DosSetup
"""

# Clean old scripts if still running
clean_good_bad_clients()
print(f"------------- Replace ConfigMap --------------")
replace_configmap_from_yaml(
kube_apis.v1,
Expand Down Expand Up @@ -133,9 +141,7 @@ def fin():
delete_dos_policy(kube_apis.custom_objects, pol_name, test_namespace)
delete_dos_logconf(kube_apis.custom_objects, log_name, test_namespace)
delete_dos_protected(kube_apis.custom_objects, protected_name, test_namespace)
# delete_items_from_yaml(kube_apis, src_webapp_yaml, test_namespace)
# delete_common_app(kube_apis, "dos", test_namespace)
# write_to_json(f"reload-{get_test_file_name(request.node.fspath)}.json", reload_times)
clean_good_bad_clients()

request.addfinalizer(fin)

Expand Down