Skip to content
Snippets Groups Projects
Commit 77a78c72 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'develop' of https://labs.etsi.org/rep/tfs/controller into fix/tid-openconfig-acls

parents 623bf640 280a4771
No related branches found
No related tags found
2 merge requests!142Release TeraFlowSDN 2.1,!139Fixes on OpenConfig and ACLs
Showing
with 357 additions and 328 deletions
......@@ -168,5 +168,8 @@ delete_local_deployment.sh
local_docker_deployment.sh
local_k8s_deployment.sh
# asdf configuration
.tool-versions
# Other logs
**/logs/*.log.*
......@@ -42,6 +42,8 @@ spec:
value: "0.5"
- name: MONITORED_KPIS_TIME_INTERVAL_AGG
value: "60"
- name: TEST_ML_MODEL
value: "0"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:10001"]
......
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: teservice
spec:
selector:
matchLabels:
app: teservice
template:
metadata:
annotations:
config.linkerd.io/skip-inbound-ports: "4189"
labels:
app: teservice
spec:
terminationGracePeriodSeconds: 5
shareProcessNamespace: true
containers:
- name: server
image: labs.etsi.org:5050/tfs/controller/te:latest
imagePullPolicy: Always
ports:
- containerPort: 10030
env:
- name: ERLANG_LOGGER_LEVEL
value: "debug"
- name: ERLANG_COOKIE
value: "tfte-unsafe-cookie"
- name: ERLANG_NODE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ERLANG_NODE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
readinessProbe:
exec:
command: ["/tfte/bin/tfte", "status"]
livenessProbe:
exec:
command: ["/tfte/bin/tfte", "status"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 700m
memory: 1024Mi
---
apiVersion: v1
kind: Service
metadata:
name: teservice
spec:
type: ClusterIP
selector:
app: teservice
ports:
- name: grpc
protocol: TCP
port: 10030
targetPort: 10030
- name: pcep
protocol: TCP
port: 4189
targetPort: 4189
......@@ -34,6 +34,9 @@ export TFS_COMPONENTS="context device pathcomp service slice compute webui load_
# Uncomment to activate L3 CyberSecurity
#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector"
# Uncomment to activate TE
#export TFS_COMPONENTS="${TFS_COMPONENTS} te"
# Set the tag you want to use for your images.
export TFS_IMAGE_TAG="dev"
......
......@@ -3,5 +3,8 @@ src/*/*
# used to prevent breaking symbolic links from source code folders
!src/*/.gitignore
!src/python/__init__.py
!src/erlang/rebar.config
!src/erlang/rebar.lock
!src/erlang/src/tfpb.app.src
uml/generated
......@@ -273,6 +273,7 @@ enum ServiceTypeEnum {
SERVICETYPE_L3NM = 1;
SERVICETYPE_L2NM = 2;
SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
SERVICETYPE_TE = 4;
}
enum ServiceStatusEnum {
......
#!/bin/bash -eu
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e
FORCE=0
DEFAULT_ACTION="generate"
usage() {
echo "Usage: $0 [-f] [clean|generate]" 1>&2
echo "Options:"
echo " -f: Force regeneration of all protocol buffers"
exit 1;
}
while getopts "fc" o; do
case "${o}" in
f)
FORCE=1
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
ACTION=${1:-$DEFAULT_ACTION}
cd $(dirname $0)
ROOT=$(pwd)
ERLANG_PROTO_DIR="$ROOT/src/erlang"
BUILD_CHECK="$ERLANG_PROTO_DIR/.generated"
tfpb_clean() {
rm -f "$BUILD_CHECK"
rm -rf "$ERLANG_PROTO_DIR/src/"*.erl
rm -rf "$ERLANG_PROTO_DIR/src/erlang/_build"
}
tfpb_generate() {
if [[ -f "$BUILD_CHECK" && $FORCE != 1 ]]; then
echo "Protocol buffer code for Erlang already generated, use -f to force"
exit 0
fi
tfpb_clean
mkdir -p "$ERLANG_PROTO_DIR"
cd "$ERLANG_PROTO_DIR"
rebar3 compile
rebar3 grpc gen
rebar3 compile
touch "$BUILD_CHECK"
echo "Protocol buffer code for Erlang generated"
}
case "$ACTION" in
clean) tfpb_clean;;
generate) tfpb_generate;;
*) usage;;
esac
......@@ -13,15 +13,14 @@
// limitations under the License.
syntax = "proto3";
package l3_attackmitigator;
import "context.proto";
import "l3_centralizedattackdetector.proto";
service L3Attackmitigator{
// Perform Mitigation
rpc PerformMitigation (L3AttackmitigatorOutput) returns (context.Empty) {}
// Get Mitigation
rpc PerformMitigation (L3AttackmitigatorOutput) returns (l3_centralizedattackdetector.StatusMessage) {}
rpc GetMitigation (context.Empty) returns (context.Empty) {}
// Get Configured ACL Rules
rpc GetConfiguredACLRules (context.Empty) returns (ACLRules) {}
}
......
......@@ -13,18 +13,23 @@
// limitations under the License.
syntax = "proto3";
package l3_centralizedattackdetector;
import "context.proto";
service L3Centralizedattackdetector {
// Analyze single input to the ML model in the CAD component
rpc AnalyzeConnectionStatistics (L3CentralizedattackdetectorMetrics) returns (Empty) {}
rpc AnalyzeConnectionStatistics (L3CentralizedattackdetectorMetrics) returns (StatusMessage) {}
// Analyze a batch of inputs to the ML model in the CAD component
rpc AnalyzeBatchConnectionStatistics (L3CentralizedattackdetectorBatchInput) returns (Empty) {}
rpc AnalyzeBatchConnectionStatistics (L3CentralizedattackdetectorBatchInput) returns (StatusMessage) {}
// Get the list of features used by the ML model in the CAD component
rpc GetFeaturesIds (Empty) returns (AutoFeatures) {}
rpc GetFeaturesIds (context.Empty) returns (AutoFeatures) {}
// Sets the list of attack IPs in order to be used to compute the prediction accuracy of the
// ML model in the CAD component in case of testing the ML model.
rpc SetAttackIPs (AttackIPs) returns (context.Empty) {}
}
message Feature {
......@@ -63,6 +68,10 @@ message L3CentralizedattackdetectorBatchInput {
repeated L3CentralizedattackdetectorMetrics metrics = 1;
}
message Empty {
message StatusMessage {
string message = 1;
}
message AttackIPs {
repeated string attack_ips = 1;
}
\ No newline at end of file
*
!rebar.config
!rebar.lock
!src/
!src/tfpb.app.src
% Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
{erl_opts, [debug_info]}.
{deps, [grpcbox]}.
{grpc, [{protos, "../.."},
{gpb_opts, [{i, "../.."}, {strbin, true}, {descriptor, true}, {module_name_suffix, "_pb"}]}]}.
{plugins, [grpcbox_plugin]}.
{"1.2.0",
[{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},1},
{<<"chatterbox">>,{pkg,<<"ts_chatterbox">>,<<"0.12.0">>},1},
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},1},
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},1},
{<<"grpcbox">>,{pkg,<<"grpcbox">>,<<"0.15.0">>},0},
{<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.2.3">>},2}]}.
[
{pkg_hash,[
{<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>},
{<<"chatterbox">>, <<"4E54F199E15C0320B85372A24E35554A2CCFC4342E0B7CD8DAED9A04F9B8EF4A">>},
{<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>},
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
{<<"grpcbox">>, <<"97C7126296A091602D372EBF5860A04F7BC795B45B33A984CAD2B8E362774FD8">>},
{<<"hpack">>, <<"17670F83FF984AE6CD74B1C456EDDE906D27FF013740EE4D9EFAA4F1BF999633">>}]},
{pkg_hash_ext,[
{<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
{<<"chatterbox">>, <<"6478C161BC60244F41CD5847CC3ACCD26D997883E9F7FACD36FF24533B2FA579">>},
{<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>},
{<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>},
{<<"grpcbox">>, <<"161ABE9E17E7D1982EFA6488ADEAA13C3E847A07984A6E6B224E553368918647">>},
{<<"hpack">>, <<"06F580167C4B8B8A6429040DF36CC93BBA6D571FAEAEC1B28816523379CBB23A">>}]}
].
%% Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
{application, tfpb,
[{description, "Teraflow Erlang Protocol Buffers"},
{vsn, "0.1.0"},
{registered, []},
{applications, [kernel, stdlib, grpcbox]},
{env, []},
{modules, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.
......@@ -56,6 +56,7 @@ class ServiceNameEnum(Enum):
OPTICALATTACKDETECTOR = 'opticalattackdetector'
OPTICALATTACKMITIGATOR = 'opticalattackmitigator'
CACHING = 'caching'
TE = 'te'
# Used for test and debugging only
DLT_GATEWAY = 'dltgateway'
......@@ -80,6 +81,7 @@ DEFAULT_SERVICE_GRPC_PORTS = {
ServiceNameEnum.OPTICALATTACKMANAGER .value : 10005,
ServiceNameEnum.INTERDOMAIN .value : 10010,
ServiceNameEnum.PATHCOMP .value : 10020,
ServiceNameEnum.TE .value : 10030,
# Used for test and debugging only
ServiceNameEnum.DLT_GATEWAY .value : 50051,
......
......@@ -21,6 +21,7 @@ class ORM_ServiceTypeEnum(enum.Enum):
L3NM = ServiceTypeEnum.SERVICETYPE_L3NM
L2NM = ServiceTypeEnum.SERVICETYPE_L2NM
TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE
TE = ServiceTypeEnum.SERVICETYPE_TE
grpc_to_enum__service_type = functools.partial(
grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)
# l3_attackmitigator
- Receives packages and process it with TSTAT
- Functions: ReportSummarizeKpi(KpiList)
# L3 Attack Mitigator
Receives detected attacks from the Centralized Attack Detector component and performs the necessary mitigations.
## Functions:
- PerformMitigation(L3AttackmitigatorOutput) -> StatusMessage
- GetMitigation(Empty) -> Empty
- GetConfiguredACLRules(Empty) -> ACLRules
......@@ -15,17 +15,12 @@
import grpc, logging
from common.Constants import ServiceNameEnum
from common.Settings import get_service_host, get_service_port_grpc
from common.proto.context_pb2 import Empty
from common.proto.l3_attackmitigator_pb2 import L3AttackmitigatorOutput, ACLRules
from common.proto.l3_attackmitigator_pb2_grpc import L3AttackmitigatorStub
from common.proto.l3_centralizedattackdetector_pb2 import StatusMessage
from common.tools.client.RetryDecorator import retry, delay_exponential
from common.proto.l3_attackmitigator_pb2_grpc import (
L3AttackmitigatorStub,
)
from common.proto.l3_attackmitigator_pb2 import (
L3AttackmitigatorOutput, ACLRules
)
from common.proto.context_pb2 import (
Empty
)
from common.tools.grpc.Tools import grpc_message_to_json_string
LOGGER = logging.getLogger(__name__)
MAX_RETRIES = 15
......@@ -37,7 +32,7 @@ class l3_attackmitigatorClient:
if not host: host = get_service_host(ServiceNameEnum.L3_AM)
if not port: port = get_service_port_grpc(ServiceNameEnum.L3_AM)
self.endpoint = "{}:{}".format(host, port)
LOGGER.debug("Creating channel to {}...".format(self.endpoint))
LOGGER.debug("Creating channel to {:s}...".format(self.endpoint))
self.channel = None
self.stub = None
self.connect()
......@@ -54,23 +49,22 @@ class l3_attackmitigatorClient:
self.stub = None
@RETRY_DECORATOR
def PerformMitigation(self, request: L3AttackmitigatorOutput) -> Empty:
LOGGER.debug('PerformMitigation request: {}'.format(request))
def PerformMitigation(self, request: L3AttackmitigatorOutput) -> StatusMessage:
LOGGER.debug('PerformMitigation request: {:s}'.format(grpc_message_to_json_string(request)))
response = self.stub.PerformMitigation(request)
LOGGER.debug('PerformMitigation result: {}'.format(response))
LOGGER.debug('PerformMitigation result: {:s}'.format(grpc_message_to_json_string(response)))
return response
@RETRY_DECORATOR
def GetMitigation(self, request: Empty) -> Empty:
LOGGER.debug('GetMitigation request: {}'.format(request))
LOGGER.debug('GetMitigation request: {:s}'.format(grpc_message_to_json_string(request)))
response = self.stub.GetMitigation(request)
LOGGER.debug('GetMitigation result: {}'.format(response))
LOGGER.debug('GetMitigation result: {:s}'.format(grpc_message_to_json_string(response)))
return response
@RETRY_DECORATOR
def GetConfiguredACLRules(self, request: Empty) -> ACLRules:
LOGGER.debug('GetConfiguredACLRules request: {}'.format(request))
LOGGER.debug('GetConfiguredACLRules request: {:s}'.format(grpc_message_to_json_string(request)))
response = self.stub.GetConfiguredACLRules(request)
LOGGER.debug('GetConfiguredACLRules result: {}'.format(response))
LOGGER.debug('GetConfiguredACLRules result: {:s}'.format(grpc_message_to_json_string(response)))
return response
......@@ -11,5 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# no extra dependency
......@@ -13,33 +13,39 @@
# limitations under the License.
from __future__ import print_function
import grpc
import logging
import time
from common.proto.l3_centralizedattackdetector_pb2 import Empty
from common.proto.l3_attackmitigator_pb2_grpc import L3AttackmitigatorServicer
from common.proto.l3_attackmitigator_pb2 import ACLRules
from common.proto.context_pb2 import (
ServiceId,
ConfigActionEnum,
)
from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
from common.proto.acl_pb2 import AclForwardActionEnum, AclLogActionEnum, AclRuleTypeEnum
from common.proto.context_pb2 import ConfigActionEnum, Service, ServiceId, ConfigRule
from common.proto.context_pb2 import ConfigActionEnum, Empty, Service, ServiceId
from common.proto.l3_attackmitigator_pb2 import ACLRules, L3AttackmitigatorOutput
from common.proto.l3_attackmitigator_pb2_grpc import L3AttackmitigatorServicer
from common.proto.l3_centralizedattackdetector_pb2 import StatusMessage
from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient
from service.client.ServiceClient import ServiceClient
from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method
LOGGER = logging.getLogger(__name__)
METRICS_POOL = MetricsPool('l3_attackmitigator', 'RPC')
METRICS_POOL = MetricsPool("l3_attackmitigator", "RPC")
class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
def __init__(self):
LOGGER.info("Creating Attack Mitigator Service")
"""
Initializes the Attack Mitigator service.
Args:
None.
Returns:
None.
"""
LOGGER.info("Creating Attack Mitigator service")
self.last_value = -1
self.last_tag = 0
......@@ -60,6 +66,23 @@ class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
src_port: str,
dst_port: str,
) -> None:
"""
Configures an ACL rule to block undesired TCP traffic.
Args:
context_uuid (str): The UUID of the context.
service_uuid (str): The UUID of the service.
device_uuid (str): The UUID of the device.
endpoint_uuid (str): The UUID of the endpoint.
src_ip (str): The source IP address.
dst_ip (str): The destination IP address.
src_port (str): The source port.
dst_port (str): The destination port.
Returns:
None.
"""
# Create ServiceId
service_id = ServiceId()
service_id.context_id.context_uuid.uuid = context_uuid
......@@ -107,29 +130,41 @@ class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
acl_entry.action.forward_action = AclForwardActionEnum.ACLFORWARDINGACTION_DROP
acl_entry.action.log_action = AclLogActionEnum.ACLLOGACTION_NOLOG
LOGGER.info("ACL Rule Set: %s", grpc_message_to_json_string(acl_rule_set))
LOGGER.info("ACL Config Rule: %s", grpc_message_to_json_string(acl_config_rule))
LOGGER.info(f"ACL Rule Set: {grpc_message_to_json_string(acl_rule_set)}")
LOGGER.info(f"ACL Config Rule: {grpc_message_to_json_string(acl_config_rule)}")
# Add the ACLRuleSet to the list of configured ACLRuleSets
self.configured_acl_config_rules.append(acl_config_rule)
LOGGER.info(service_request)
# Update the Service with the new ACL RuleSet
service_reply: ServiceId = self.service_client.UpdateService(service_request)
service_reply = self.service_client.UpdateService(service_request)
LOGGER.info("Service reply: %s", grpc_message_to_json_string(service_reply))
LOGGER.info(f"Service reply: {grpc_message_to_json_string(service_reply)}")
if service_reply != service_request.service_id: # pylint: disable=no-member
raise Exception("Service update failed. Wrong ServiceId was returned")
@safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
def PerformMitigation(self, request, context):
def PerformMitigation(self, request : L3AttackmitigatorOutput, context : grpc.ServicerContext) -> StatusMessage:
"""
Performs mitigation on an attack by configuring an ACL rule to block undesired TCP traffic.
Args:
request (L3AttackmitigatorOutput): The request message containing the attack mitigation information.
context (Empty): The context of the request.
Returns:
StatusMessage: A response with a message indicating that the attack mitigation information
was received and processed.
"""
last_value = request.confidence
last_tag = request.tag
LOGGER.info(
"Attack Mitigator received attack mitigation information. Prediction confidence: %s, Predicted class: %s",
last_value,
last_tag,
f"Attack Mitigator received attack mitigation information. Prediction confidence: {last_value}, Predicted class: {last_tag}"
)
ip_o = request.ip_o
......@@ -141,21 +176,23 @@ class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
counter = 0
service_id = request.service_id
LOGGER.info("Service Id.:\n{}".format(grpc_message_to_json_string(service_id)))
LOGGER.info(f"Service Id.: {grpc_message_to_json_string(service_id)}")
LOGGER.info("Retrieving service from Context")
while sentinel:
try:
service = self.context_client.GetService(service_id)
sentinel = False
except Exception as e:
counter = counter + 1
LOGGER.debug("Waiting 2 seconds", counter, e)
LOGGER.debug(f"Waiting 2 seconds for service to be available (attempt: {counter})")
time.sleep(2)
LOGGER.info(f"Service with Service Id.: {grpc_message_to_json_string(service_id)}\n{grpc_message_to_json_string(service)}")
LOGGER.info(
f"Service with Service Id.: {grpc_message_to_json_string(service_id)}\n{grpc_message_to_json_string(service)}"
)
LOGGER.info("Adding new rule to the service to block the attack")
self.configure_acl_rule(
context_uuid=service_id.context_id.context_uuid.uuid,
service_uuid=service_id.service_uuid.uuid,
......@@ -167,8 +204,8 @@ class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
dst_port=port_d,
)
LOGGER.info("Service with new rule:\n{}".format(grpc_message_to_json_string(service)))
LOGGER.info("Updating service with the new rule")
self.service_client.UpdateService(service)
service = self.context_client.GetService(service_id)
......@@ -178,10 +215,21 @@ class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
)
)
return Empty(message=f"OK, received values: {last_tag} with confidence {last_value}.")
return StatusMessage(message=f"OK, received values: {last_tag} with confidence {last_value}.")
@safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
def GetConfiguredACLRules(self, request, context):
def GetConfiguredACLRules(self, request : Empty, context : grpc.ServicerContext) -> ACLRules:
"""
Returns the configured ACL rules.
Args:
request (Empty): The request message.
context (Empty): The context of the RPC call.
Returns:
acl_rules (ACLRules): The configured ACL rules.
"""
acl_rules = ACLRules()
for acl_config_rule in self.configured_acl_config_rules:
......
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import logging
from common.proto.l3_centralizedattackdetector_pb2 import (
Empty
)
from common.proto.l3_attackmitigator_pb2_grpc import (
L3AttackmitigatorServicer,
)
from common.proto.context_pb2 import (
Service, ServiceId, ServiceConfig, ServiceTypeEnum, ServiceStatusEnum, ServiceStatus, Context, ContextId, Uuid,
Timestamp, ConfigRule, ConfigRule_Custom, ConfigActionEnum, Device, DeviceId, DeviceConfig,
DeviceOperationalStatusEnum, DeviceDriverEnum, EndPoint, Link, LinkId, EndPoint, EndPointId, Topology, TopologyId
)
from common.proto.context_pb2_grpc import (
ContextServiceStub
)
from common.proto.service_pb2_grpc import (
ServiceServiceStub
)
from datetime import datetime
import grpc
LOGGER = logging.getLogger(__name__)
CONTEXT_CHANNEL = "192.168.165.78:1010"
SERVICE_CHANNEL = "192.168.165.78:3030"
class l3_attackmitigatorServiceServicerImpl(L3AttackmitigatorServicer):
def GetNewService(self, service_id):
service = Service()
service_id_obj = self.GenerateServiceId(service_id)
service.service_id.CopyFrom(service_id_obj)
service.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
service_status = ServiceStatus()
service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
service.service_status.CopyFrom(service_status)
timestamp = Timestamp()
timestamp.timestamp = datetime.timestamp(datetime.now())
service.timestamp.CopyFrom(timestamp)
return service
def GetNewContext(self, service_id):
context = Context()
context_id = ContextId()
uuid = Uuid()
uuid.uuid = service_id
context_id.context_uuid.CopyFrom(uuid)
context.context_id.CopyFrom(context_id)
return context
def GetNewDevice(self, service_id):
device = Device()
device_id = DeviceId()
uuid = Uuid()
uuid.uuid = service_id
device_id.device_uuid.CopyFrom(uuid)
device.device_type="test"
device.device_id.CopyFrom(device_id)
device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
return device
def GetNewLink(self, service_id):
link = Link()
link_id = LinkId()
uuid = Uuid()
uuid.uuid = service_id
link_id.link_uuid.CopyFrom(uuid)
link.link_id.CopyFrom(link_id)
return link
def GetNewTopology(self,context_id, device_id, link_id):
topology = Topology()
topology_id = TopologyId()
topology_id.context_id.CopyFrom(context_id)
uuid = Uuid()
uuid.uuid = "test_crypto"
topology_id.topology_uuid.CopyFrom(uuid)
topology.topology_id.CopyFrom(topology_id)
topology.device_ids.extend([device_id])
topology.link_ids.extend([link_id])
return topology
def GetNewEndpoint(self, topology_id, device_id, uuid_name):
endpoint = EndPoint()
endpoint_id = EndPointId()
endpoint_id.topology_id.CopyFrom(topology_id)
endpoint_id.device_id.CopyFrom(device_id)
uuid = Uuid()
uuid.uuid = uuid_name
endpoint_id.endpoint_uuid.CopyFrom(uuid)
endpoint.endpoint_id.CopyFrom(endpoint_id)
endpoint.endpoint_type = "test"
return endpoint
def __init__(self):
LOGGER.debug("Creating Servicer...")
self.last_value = -1
self.last_tag = 0
"""
context = self.GetNewContext("test_crypto")
print(context, flush=True)
print(self.SetContext(context))
service = self.GetNewService("test_crypto")
print("This is the new service", self.CreateService(service), flush = True)
ip_o = "127.0.0.1"
ip_d = "127.0.0.2"
port_o = "123"
port_d = "124"
service_id = self.GenerateServiceId("test_crypto")
config_rule = self.GetConfigRule(ip_o, ip_d, port_o, port_d)
service = self.GetService(service_id)
print("Service obtained from id", service, flush=True)
config_rule = self.GetConfigRule(ip_o, ip_d, port_o, port_d)
#service_config = service.service_config
#service_config.append(config_rule)
service_config = ServiceConfig()
service_config.config_rules.extend([config_rule])
service.service_config.CopyFrom(service_config)
device = self.GetNewDevice("test_crypto")
print("New device", device, flush=True)
device_id = self.SetDevice(device)
link = self.GetNewLink("test_crypto")
print("New link", link, flush=True)
link_id = self.SetLink(link)
topology = self.GetNewTopology(context.context_id, device.device_id, link.link_id)
print("New topology", topology, flush=True)
topology_id = self.SetTopology(topology)
endpoint = self.GetNewEndpoint(topology.topology_id, device.device_id, "test_crypto")
print("New endpoint", endpoint, flush=True)
link.link_endpoint_ids.extend([endpoint.endpoint_id])
self.SetLink(link)
print("Service with new rule", service, flush=True)
self.UpdateService(service)
service2 = self.GetService(service_id)
print("Service obtained from id after updating", service2, flush=True)
"""
def GenerateRuleValue(self, ip_o, ip_d, port_o, port_d):
value = {
'ipv4:source-address': ip_o,
'ipv4:destination-address': ip_d,
'transport:source-port': port_o,
'transport:destination-port': port_d,
'forwarding-action': 'DROP',
}
return value
def GetConfigRule(self, ip_o, ip_d, port_o, port_d):
config_rule = ConfigRule()
config_rule_custom = ConfigRule_Custom()
config_rule.action = ConfigActionEnum.CONFIGACTION_SET
config_rule_custom.resource_key = 'test'
config_rule_custom.resource_value = str(self.GenerateRuleValue(ip_o, ip_d, port_o, port_d))
config_rule.custom.CopyFrom(config_rule_custom)
return config_rule
def GenerateServiceId(self, service_id):
service_id_obj = ServiceId()
context_id = ContextId()
uuid = Uuid()
uuid.uuid = service_id
context_id.context_uuid.CopyFrom(uuid)
service_id_obj.context_id.CopyFrom(context_id)
service_id_obj.service_uuid.CopyFrom(uuid)
return service_id_obj
def SendOutput(self, request, context):
# SEND CONFIDENCE TO MITIGATION SERVER
print("Server received mitigation values...", request.confidence, flush=True)
last_value = request.confidence
last_tag = request.tag
ip_o = request.ip_o
ip_d = request.ip_d
port_o = request.port_o
port_d = request.port_d
service_id = self.GenerateServiceId(request.service_id)
config_rule = self.GetConfigRule(ip_o, ip_d, port_o, port_d)
service = GetService(service_id)
print(service)
#service.config_rules.append(config_rule)
#UpdateService(service)
# RETURN OK TO THE CALLER
return Empty(
message=f"OK, received values: {last_tag} with confidence {last_value}."
)
def SetDevice(self, device):
with grpc.insecure_channel(CONTEXT_CHANNEL) as channel:
stub = ContextServiceStub(channel)
return stub.SetDevice(device)
def SetLink(self, link):
with grpc.insecure_channel(CONTEXT_CHANNEL) as channel:
stub = ContextServiceStub(channel)
return stub.SetLink(link)
def SetTopology(self, link):
with grpc.insecure_channel(CONTEXT_CHANNEL) as channel:
stub = ContextServiceStub(channel)
return stub.SetTopology(link)
def GetService(self, service_id):
with grpc.insecure_channel(CONTEXT_CHANNEL) as channel:
stub = ContextServiceStub(channel)
return stub.GetService(service_id)
def SetContext(self, context):
with grpc.insecure_channel(CONTEXT_CHANNEL) as channel:
stub = ContextServiceStub(channel)
return stub.SetContext(context)
def UpdateService(self, service):
with grpc.insecure_channel(SERVICE_CHANNEL) as channel:
stub = ServiceServiceStub(channel)
stub.UpdateService(service)
def CreateService(self, service):
with grpc.insecure_channel(SERVICE_CHANNEL) as channel:
stub = ServiceServiceStub(channel)
stub.CreateService(service)
def GetMitigation(self, request, context):
# GET OR PERFORM MITIGATION STRATEGY
logging.debug("")
print("Returing mitigation strategy...")
k = self.last_value * 2
return Empty(
message=f"Mitigation with double confidence = {k}"
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment