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

Security: Test added for traffic over the IPsec tunnel. #1003

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/opi-lab.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Install python requirements
run: pip install -r ./demos/tgen/requirements.txt
- name: Run ipsec test automation
run: pytest -s ./demos/security/nvidia/ipsec-config.py
run: pip install -r ./demos/security/nvidia/requirements.txt
- name: Run CyPerf ipsec test automation
run: pytest -s ./demos/security/nvidia/test_ipsec.py

opi-ansible:
runs-on: self-hosted
Expand Down
24 changes: 7 additions & 17 deletions demos/security/nvidia/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
## hardware

- server with Ubuntu 22.04
- Nvidia BlueField2
- Nvidia BlueField2 or BlueField3
- Keysight CloudStorm 100G

## configuration

### host (the server holding the DPU)

- install Ubuntu 22.04 server
- install `MLNX_OFED_LINUX-5.8-1.1.2.1-ubuntu22.04-x86_64.iso`
- install `DOCA_1.5.1_BSP_3.9.3_Ubuntu_20.04-4.2211-LTS.signed.bfb` on the BlueField2
- install `MLNX_OFED_LINUX-24.04-0.6.6.0-ubuntu22.04-x86_64.iso`
- install `bf-bundle-2.7.0-33_24.04_ubuntu-22.04_prod.bfb` on the BlueField2
- set BlueField2 in SEPARATED_HOST mode to make things easier

```Shell
Expand Down Expand Up @@ -78,18 +78,8 @@ see <https://github.com/opiproject/pydpu> and <https://github.com/opiproject/god

```Shell
# add python api lib to path
git clone https://github.com/opiproject/opi-api.git
export PYTHONPATH=${PYTHONPATH}:${HOME}/opi-api/security/v1/gen/python/

pip3 install grpcio

python3

# run the ipsec-config.py from this folder
git clone https://github.com/opiproject/opi-poc.git
cd ./opi-poc/
pip3 install -r demos/security/nvidia/requirements.txt
pytest -s -v demos/security/nvidia/test_ipsec.py
```

### ixload

- load `opi-ipsec-demo-1.rxf`
- assign the ports
- click start button
2,174 changes: 2,174 additions & 0 deletions demos/security/nvidia/RESTasV3.py

Large diffs are not rendered by default.

140 changes: 140 additions & 0 deletions demos/security/nvidia/Statistics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import json
import os

import pandas as pd
from tabulate import tabulate


class JSONObject:
def __init__(self, dict):
vars(self).update(dict)


def json_to_class(path):
"""
Converts a json into a class
"""
json_file = open(path)
s = json_file.read()
return json.loads(s, object_hook=JSONObject)


class Statistics:
criteria_message = ''

def __init__(self, csvs_path):
"""
Takes in the path to csv folder
"""
self.csvs_path = csvs_path
self.headers = ['Condition', 'Status']
self.table = []
self.stats_failures = []
self.config_type = None
self.stats = {}
self.include_baseline_file = True
for csv in os.listdir(csvs_path):
if csv.endswith(".csv"):
self.stats[csv[:-4]] = self.make_dataframe(os.path.join(csvs_path, csv))

def make_dataframe(self, csv_file_path):
'''
Creates a data frame from a csv found at that path
:csv_file_path
'''
with open(csv_file_path, encoding='utf-8') as csvf:
try:
csv = pd.read_csv(csvf)
except pd.errors.EmptyDataError:
raise Exception("{} is empty".format(csv_file_path))
except pd.errors.ParserError:
raise Exception("{} is corupt".format(csv_file_path))
return csv

@staticmethod
def last(df):
df = df[df['Timestamp epoch ms'] == max(df['Timestamp epoch ms'])]
return df

def preform_validation(self, validation_entry):
stats = self.stats
last = Statistics.last
try:
validation_ok = eval(validation_entry.condition)
except :
raise Exception("This validation is not written correctly: {}".format(validation_entry.condition))
if validation_ok:
self.table.append([validation_entry.description, 'Pass'])
else:
self.table.append([validation_entry.description, 'Fail'])
self.stats_failures.append(validation_entry.description)

def validate_criteria_file(self, criteria_path):
"""
Preforms specific validation for a config and decides if the baseline validation needs to be added
criteria path: path to the json criteria
"""
validator = json_to_class(criteria_path)
self.include_baseline_file = validator.include_baseline
if self.config_type['dut']:
validator = validator.DUT
else:
validator = validator.B2B
for validation_entry in validator:
self.preform_validation(validation_entry)

def validate_baseline_file(self, criteria_path):
"""
Checks what type of profiles are present in the test and preforms general validation
criteria path: path to the json criteria
config_type: A dictionary that flags the types of profiles present inside the test
"""
validator = json_to_class(criteria_path)
if self.config_type['dut']:
validator = validator.DUT
else:
validator = validator.B2B
if self.config_type['traffic'] or self.config_type['attack']:
for validation_entry in validator.general:
self.preform_validation(validation_entry)
else:
raise Exception('The config does not have an attack or traffic profile')
if self.config_type['traffic']:
for validation_entry in validator.traffic:
self.preform_validation(validation_entry)
if self.config_type['attack']:
for validation_entry in validator.attack:
self.preform_validation(validation_entry)

def validate_mdw_stats(self, config_type, config_path=""):
"""
Using a the criteria json and the baseline json, validates the resources returned after the run.
config_type: A dictionary that flags the types of profiles present inside the test
config_name: same name as the test that ran.
"""

self.config_type = config_type
if os.path.exists(config_path):
config_name = os.path.basename(config_path)
print("Config: {}\n\n".format(config_name))
criteria_path = os.path.join(config_path, 'validation.json')
print(criteria_path)
print('Running Validations for {}'.format(config_name))

if os.path.exists(criteria_path):

try:
self.validate_criteria_file(criteria_path)
except AttributeError as e:
print('Criteria {} could not be applied due to: {}'.format(config_name, e))
else:
self.include_baseline_file = True
if self.include_baseline_file:
print('Baseline validation applied')
criteria_path = os.path.join("./resources", "baseline_validation.json")
self.validate_baseline_file(criteria_path)
else:
print('Baseline validation skipped')
print(tabulate(self.table, self.headers, tablefmt="grid"))
return "; ".join(self.stats_failures)

Binary file added demos/security/nvidia/cyperf-ipsec-config.zip
Binary file not shown.
11 changes: 11 additions & 0 deletions demos/security/nvidia/deployment/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
DOCKER_REGISTRY=ghcr.io/open-traffic-generator
CONTROLLER_VERSION=latest
TRAFFIC_ENGINE_VERSION=latest
AUR_VERSION=latest
IFC1=enp129s0f0np0
IFC2=enp129s0f1np1
TCP_PORT_IFC1=5555
TCP_PORT_IFC2=5556
CPU_CORES_IFC1="0,1,2"
CPU_CORES_IFC2="0,3,4"
OPT_ENABLE_IPv6="No"
8 changes: 8 additions & 0 deletions demos/security/nvidia/deployment/conf/k.swanctl.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
secrets {
ike-tun1_0_0 {
secret = "ipsec"
}
ike-tun1_0_1 {
secret = "ipsec"
}
}
10 changes: 10 additions & 0 deletions demos/security/nvidia/deployment/conf/vici.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
vici {

# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
load = yes

# Socket the vici plugin serves clients.
socket = unix:///var/run/charon.vici

}
49 changes: 49 additions & 0 deletions demos/security/nvidia/deployment/cyperf_with_ipsec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
version: '3.7'

services:
client:
image: public.ecr.aws/keysight/cyperf-agent:latest
container_name: ClientAgent
#network_mode: "host"
restart: always
privileged: true
cpuset: ${CPU_CORES_IFC1:-"0"}
#command: sh -c "ip link set enp129s0f0np0 netns {} name enp129s0f0np0 && cyperfagent interface test set enp129s0f0np0"
environment:
- AGENT_TAGS="Dockers-Group=CyPerf-Agent-Client,node-owner=KB"
- AGENT_MANAGEMENT_INTERFACE=br1
- AGENT_TEST_INTERFACE=enp129s0f0np0
cap_add:
- NET_ADMIN
- IPC_LOCK
- NET_RAW
networks:
cyperf-mgmt-net:
ipv4_address: 192.168.0.10
server:
image: public.ecr.aws/keysight/cyperf-agent:latest
container_name: ServerAgent
#network_mode: "host"
restart: always
privileged: true
cpuset: ${CPU_CORES_IFC2:-"1"}
#command: sh -c "ip link set enp129s0f1np1 netns {} name enp129s0f1np1 && cyperfagent interface test set enp129s0f1np1"
environment:
- AGENT_TAGS="Dockers-Group=CyPerf-Agent-Server,node-owner=KB"
- AGENT_MANAGEMENT_INTERFACE=br1
- AGENT_TEST_INTERFACE=enp129s0f1np1
cap_add:
- NET_ADMIN
- IPC_LOCK
- NET_RAW

networks:
cyperf-mgmt-net:
ipv4_address: 192.168.0.11

networks:
cyperf-mgmt-net:
name: mgmt-net
ipam:
config:
- subnet: "192.168.0.0/24"
Loading
Loading