# Table of Contents
- [NSM-SecurityChainingService](#nsm-securitychainingservice)
- [IBN](#ibn)
- [NSM](#nsm)
- [NSM DETAILS](#nsm-details)
- [OPERATOR](#operator)
  - [Custom Resource Definition (CRD) - SecurityChain](#custom-resource-definition-crd---securitychain)
- [APIs used by sfc-cli](#apis-used-by-sfc-cli)
  - [API Endpoints](#api-endpoints)
    - [Upload JSON File](#1-upload-json-file)
    - [Deploy Kubernetes Operator](#2-deploy-kubernetes-operator)
  - [Example Usage](#example-usage)
- [USAGE](#usage)

# NSM-SecurityChainingService
The value of this project is to provide a Kubernetes cluster where the latter will be able to deploy a security chain, where different security features are implemented, based on Network Service Mesh.
The main feature is represented by Kopf: python library which is useful to develop a kubernetes's operator.
It is important to understand how this operator works:
 - It needs a CRD (in our case service-chain)
 - An instance of the CRD (the chain that we want to develop)

Doing this, the operator is able to observe the events related to the instance of CRD.

# NSM
There are several components that enable the implementation of NSM. 
In general, a client, which in this context will be called a Network Service Client, makes a request for a specific service. 
This request is made explicit through a notation in the client's yaml file.
Once this request is received by the nsmgr (NS Manager), it is forwarded to the forwarder who will then manage the connection between the Network Service Endpoint (NSE) and NSC.
Just a short specification reguards the nsmgr that has to be one for each worker node of the cluster and exploits the unix connections to make possible the connection of the client to the NSM infrastructure. 
The client in the request will specify what type of mechanism it prefers, kernel or memif, as well as the endpoint associated with the requested service.
If the NSC request is successful, NSM's webhook admission will take care of modifying the client yaml file by adding the containers "cmd-nsc-init" and "cmd-nsc" (in case working with kernel-type mechanisms) for NSC to be able to work in the NSM ecosystem.
Once this is done, NSC will be able to communicate with the endpoint. 
Wanting to implement an endpoint composition, it was necessary to configure an intermediate pod, using 2 containers:
- cmd-nse-icmp-response
- cmd-nsc

These 2 were necessary in order to have 2 kernel interfaces in the same pod, so as to handle both incoming and outgoing traffic to the next pod.
We must also consider the network service definition file because through this the order of the chain is specified, so that each client knows which next endpoint to request from.
An important note is that in this case where you want to make a chain, the important thing is to reason in pairs of 2, where from time to time NSC and NSE switch roles.
By doing so, it is possible to introduce a third container in the intermediary pods where the security functions can be realized.
A special note also concerns the environment variables used by NSM to configure the various endpoints, because through these it is possible to specify several useful characteristics in order to compose the chain.
Once the chain is created it is important to configure the container, within the pods, in order to handle the traffic.
Just as example it is possible to run these commands inside the pods, adjusting each time the ip addresses:
```
- /bin/sh
- -c
- |
    apk add --no-cache iptables
    INTERFACE=$(ip -o -4 addr list | grep "172.16.0.0/32" | awk '{print $2}')
    iptables -t nat -A PREROUTING -i $INTERFACE -j DNAT --to 172.16.1.0
    iptables -t nat -A POSTROUTING -o kernelint2 -j SNAT --to 172.16.1.1
    iptables -A FORWARD -i $INTERFACE -o kernelint2 -j ACCEPT
    iptables -A FORWARD -i kernelint2 -o $INTERFACE -j ACCEPT
```
Basically this piece of code installs the package iptables in the container and configure the rules that have to be set in order to forward the traffic to the next element of the chain.

If it is desired, a way to check if everthing works is adding a 3° container in the deplyoment like this:
```
    - name: tcpdump
      image: corfr/tcpdump
      imagePullPolicy: IfNotPresent
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
            - NET_RAW  
```
which exploits an image containing tcpdump, useful for monitoring the interfaces.
Once the container is running it is possibile to execute this command:
```
tcpdump -i kernelint2 dst 172.16.1.0 -n -l

```
and it is possible to see that the traffic is coming from 172,16.0.1, directed to 172.16.1.0 and it is passing through kernelint2 interface.

## NSM DETAILS
Here's a list of the NSM configuration variables:

- **SPIFFE_ENDPOINT_SOCKET**
  - Description: Specifies the endpoint socket for SPIFFE (Secure Production Identity Framework For Everyone).
  - Value: `unix:///run/spire/sockets/agent.sock`

- **NSM_LABELS**
  - Description: Defines the labels for the NSM. Used for identification and categorization.
  - Value: `app:security-function-1`

- **NSM_SERVICE_NAMES**
  - Description: Specifies the service names associated with the NSM. Thanks to this variable, the endpoint can know which service to attach to. There are other example in the official repository where the endpoint could serve multiple services.
  - Value: `"security-chain"`

- **NSM_LOG_LEVEL**
  - Description: Sets the log level for NSM, useful for debugging and troubleshooting. Performing the log of the specific container within the POD it is possible to retrieve more information about the possible errors.
  - Value: `TRACE`

- **NSM_CIDR_PREFIX**
  - Description: Specifies the CIDR (Classless Inter-Domain Routing) prefix for network addressing within the NSM. This provides only 2 IP addresses, one for the client and the other for the endpoint.
  - Value: `172.16.0.0/31`

- **NSM_NAME**
  - Description: Dynamically generated from the metadata of the resource. It sets the name of the NSM.

- **NSM_NETWORK_SERVICES**
  - Description: Specifies the network services and their configurations. For example it is possible to specify the mechanisms (kernel,memif), the network service desired, the name of the interface that will be created, At the end it is specified the selector that is needed to create the chain, because it is used, considering also the `NetworkService` file, to identify the destination of the request made by the client.
  - Value: `kernel://security-chain/kernelint2?app=passthrough-1`

# OPERATOR
# Custom Resource Definition (CRD) - SecurityChain

This document provides an overview of the Custom Resource Definition (CRD) named "SecurityChain" defined in Kubernetes.

## CRD Specifications

- **group**: kopf.dev
- **names**: Specifies the names for the custom resources associated with this CRD.
  - **kind**: The singular name of the custom resource (SecurityChain).
  - **plural**: The plural name of the custom resource (securitychains).
  - **singular**: The singular name of the custom resource (securitychain).
  - **shortNames**: Abbreviated aliases for the custom resource (scs, sc).
- **scope**: Defines the scope in which the CRD is valid (Namespaced indicates it is valid only within a specific namespace).

## CRD

- **versions**: Lists the supported versions of the CRD. In this case, only one version is defined.
  - **name**: Version name (v1).
  - **schema**: OpenAPI v3 schema for this version of the CRD.
    - **properties**: Defines the properties of the custom resource.
      - **spec**: A spec property of type object that can contain custom fields for the CRD specification.
        - **type**: Data type for spec (object).
        - **x-kubernetes-preserve-unknown-fields**: Preserves unknown fields within the spec field.
      - **status**: A status property of type object that can contain fields for the custom resource's status.
        - **type**: Data type for status (object).
        - **x-kubernetes-preserve-unknown-fields**: Preserves unknown fields within the status field.
    - **type**: Data type of the CRD (object).
  - **served**: Indicates whether this version should be served.
  - **storage**: Indicates whether this version should be stored.

## How the CRD Works

The "SecurityChain" CRD allows to create custom resources of type "SecurityChain" within a Kubernetes namespace. These custom resources can have two main sections:

- **spec**: The spec section is an object that can contain custom fields specific to the use case. You can define and use these fields to configure the SecurityChain resources as needed.

- **status**: The status section is an object that can contain fields to represent the current status of your SecurityChain resources. You can update these fields to reflect the current state of your resources.

USANDO QUESTA RIGA nella definizione della CRD è possibile estenderla con campi sconosciuti a Kubernetes:            x-kubernetes-preserve-unknown-fields: true
Quindi si posso aggiungere campi di un certo tipo che però devono essere poi mappati in qualcosa.

# APIs used by sfc-cli

This API provides functionality to upload JSON files, convert them to YAML, and deploy a Kubernetes operator.

## API Endpoints

### 1. Upload JSON File

- **Endpoint:** `/api/upload_json`
- **HTTP Method:** POST
- **Description:** This endpoint allows you to upload a JSON file. Basically it is needed to send the requirements written by the user thanks to the CLI to the operator The uploaded JSON file will be saved on the server, converted to YAML, and used for setting up a Kubernetes Custom Resource Definition (CRD).
- **Request Payload:** The API expects a `multipart/form-data` POST request with the JSON file attached as the `file` field.
- **Responses:**
  - 200 OK: If the file is successfully uploaded and processed, it returns a JSON response with a success message.
  - 400 Bad Request: If no file is received or the filename is missing, it returns an error message.
  - 500 Internal Server Error: If any other error occurs during processing, it returns an error message with details.

### 2. Deploy Kubernetes Operator

- **Endpoint:** `/api/deploy`
- **HTTP Method:** GET
- **Description:** This endpoint triggers the deployment of a Kubernetes operator using the previously uploaded and processed YAML file. It initiates the deployment process instantiating all the resources needed.
- **Responses:**
  - 200 OK: If the deployment is successful, it returns a JSON response with a success message.
  - 500 Internal Server Error: If any error occurs during deployment, it returns an error message with details.

## Example Usage

1. Upload a JSON file:
   ```bash
   sfc setchain  http://localhost:28900/api/upload_json
   ```
   Using the "sfc" CLI it is possible to take and send the `requirements.json` file to this API that will save it locally and will parse it, creating a new yaml file that will be the resource observed by the operator.
2. Deploy the chain:
   ```bash
   sfc deploychain http://localhost:5000/api/deploy
   ```


# USAGE
1. Clone the repository and make the installation of the requirements thanks to the `requirements.txt` file.
2. Navigate into API and run the script `api.py`.
3. Now the `sfc-cli CLI` can correctly send the information to the operator.
4. Once the user perform the `deploy` command of the CLI, the `script.py` will be executed
5. Open a new terminal and type and depending on which folder the user is located type `kubectl apply -f API/obj,yaml` or `kubectl apply -f obj,yaml`
6. Now the files are created within the `nse-kernel-composition` directory.