diff --git a/util-scripts/external-entities/demo/Dockerfile b/util-scripts/external-entities/demo/Dockerfile new file mode 100644 index 0000000..1a280e0 --- /dev/null +++ b/util-scripts/external-entities/demo/Dockerfile @@ -0,0 +1,5 @@ +FROM registry.fedoraproject.org/fedora:41 + +RUN dnf install -y which iproute bpftool procps iptables nc + +COPY prepare-tap.sh /scripts/ diff --git a/util-scripts/external-entities/demo/Makefile b/util-scripts/external-entities/demo/Makefile new file mode 100644 index 0000000..3b3d390 --- /dev/null +++ b/util-scripts/external-entities/demo/Makefile @@ -0,0 +1,9 @@ +ifeq ($(TAG),) +TAG=$(shell git describe --tags --abbrev=10 --dirty) +endif + +.PHONY: +build: + docker build -t external-connection . + docker tag external-connection quay.io/$(REPOSITORY)/external-connection:$(TAG) + docker push quay.io/$(REPOSITORY)/external-connection:$(TAG) diff --git a/util-scripts/external-entities/demo/collector-config-disabled.yml b/util-scripts/external-entities/demo/collector-config-disabled.yml new file mode 100644 index 0000000..7a7be4e --- /dev/null +++ b/util-scripts/external-entities/demo/collector-config-disabled.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: collector-config + namespace: stackrox +data: + runtime_config.yaml: | + networking: + externalIps: + enabled: DISABLED diff --git a/util-scripts/external-entities/demo/collector-config-enabled.yml b/util-scripts/external-entities/demo/collector-config-enabled.yml new file mode 100644 index 0000000..7a34d94 --- /dev/null +++ b/util-scripts/external-entities/demo/collector-config-enabled.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: collector-config + namespace: stackrox +data: + runtime_config.yaml: | + networking: + externalIps: + enabled: ENABLED diff --git a/util-scripts/external-entities/demo/create-cidr-block.sh b/util-scripts/external-entities/demo/create-cidr-block.sh new file mode 100755 index 0000000..314cd59 --- /dev/null +++ b/util-scripts/external-entities/demo/create-cidr-block.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -eou pipefail + +ROX_ENDPOINT=${1:-localhost:8000} +cidr_block=${2:-8.8.8.0/24} +cidr_name=${3:-"testCIDR"} + +clusters_json="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/clusters" -k --header "Authorization: Bearer $ROX_API_TOKEN")" + +cluster_id="$(echo "$clusters_json" | jq -r '.clusters[0].id')" + +cidr_json='{"entity": {"cidr": "'"$cidr_block"'", "name": "'"$cidr_name"'", "id": ""}}' + + +create_cidr_block_response_json="$(curl --location --silent --request POST --data "$cidr_json" "https://${ROX_ENDPOINT}/v1/networkgraph/cluster/$cluster_id/externalentities" -k --header "Authorization: Bearer $ROX_API_TOKEN")" + +echo "$create_cidr_block_response_json" | jq diff --git a/util-scripts/external-entities/demo/create-deployment-with-ext-ip.sh b/util-scripts/external-entities/demo/create-deployment-with-ext-ip.sh new file mode 100755 index 0000000..dfa8ace --- /dev/null +++ b/util-scripts/external-entities/demo/create-deployment-with-ext-ip.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -eou pipefail + +export TARGET_IP=$1 +export PORT=$2 +export NAME=$3 + +envsubst < external-destination-source-stable-template.yml > deployment.yml +kubectl apply -f deployment.yml diff --git a/util-scripts/external-entities/demo/create-secret-for-qa.sh b/util-scripts/external-entities/demo/create-secret-for-qa.sh new file mode 100755 index 0000000..8b464fb --- /dev/null +++ b/util-scripts/external-entities/demo/create-secret-for-qa.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -eou pipefail + +kubectl -n stackrox get secret stackrox -o yaml > stackrox-secret.yml +sed 's|stackrox|qa|' stackrox-secret.yml > qa-secret.yml +kubectl create -f qa-secret.yml + +rm stackrox-secret.yml +rm qa-secret.yml diff --git a/util-scripts/external-entities/demo/dynamic-connector/Dockerfile b/util-scripts/external-entities/demo/dynamic-connector/Dockerfile new file mode 100644 index 0000000..4615627 --- /dev/null +++ b/util-scripts/external-entities/demo/dynamic-connector/Dockerfile @@ -0,0 +1,9 @@ +FROM registry.fedoraproject.org/fedora:41 + +RUN dnf install -y python pip + +RUN pip install flask + +COPY dynamic-connector.py /dynamic-connector.py + +CMD python /dynamic-connector.py diff --git a/util-scripts/external-entities/demo/dynamic-connector/Makefile b/util-scripts/external-entities/demo/dynamic-connector/Makefile new file mode 100644 index 0000000..ef6725c --- /dev/null +++ b/util-scripts/external-entities/demo/dynamic-connector/Makefile @@ -0,0 +1,9 @@ +ifeq ($(TAG),) +TAG=$(shell git describe --tags --abbrev=10 --dirty) +endif + +.PHONY: +build: + docker build -t dynamic-connector . + docker tag dynamic-connector quay.io/$(REPOSITORY)/dynamic-connector:$(TAG) + docker push quay.io/$(REPOSITORY)/dynamic-connector:$(TAG) diff --git a/util-scripts/external-entities/demo/dynamic-connector/demo.sh b/util-scripts/external-entities/demo/dynamic-connector/demo.sh new file mode 100755 index 0000000..48e4817 --- /dev/null +++ b/util-scripts/external-entities/demo/dynamic-connector/demo.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -eou pipefail + +curl "http://127.0.0.1:8181/?action=open&ip=8.8.8.8&port=53" + +# Check network graph + +# Lock baseline + +curl "http://127.0.0.1:8181/?action=open&ip=142.250.72.238&port=80" + +# Check network graph and violations + +curl "http://127.0.0.1:8181/?action=open&ip=1.1.1.1&port=53" + +# Check network graph diff --git a/util-scripts/external-entities/demo/dynamic-connector/dynamic-connector.py b/util-scripts/external-entities/demo/dynamic-connector/dynamic-connector.py new file mode 100644 index 0000000..8abab41 --- /dev/null +++ b/util-scripts/external-entities/demo/dynamic-connector/dynamic-connector.py @@ -0,0 +1,54 @@ +import threading +import time +from flask import Flask, request +import socket + +app = Flask(__name__) + +# Set of active targets (tuple of IP and port) +targets = set() +targets_lock = threading.Lock() + +def connect_to_target(ip, port, timeout=1): + """Connect to target via TCP socket""" + try: + with socket.create_connection((ip, int(port)), timeout=timeout): + print(f"[✓] Created connection {ip}:{port}") + except Exception as e: + print(f"[✗] Failed to connect {ip}:{port} - {e}") + +def connector(): + """Background thread to continuously connect to targets""" + while True: + with targets_lock: + current_targets = list(targets) + for ip, port in current_targets: + connect_to_target(ip, port) + time.sleep(2) + +@app.route('/') +def handle_request(): + action = request.args.get('action') + ip = request.args.get('ip') + port = request.args.get('port') + + if not all([action, ip, port]): + return "Missing required parameters: action, ip, port", 400 + + target = (ip, int(port)) + + with targets_lock: + if action == 'open': + targets.add(target) + return f"Opened {ip}:{port}", 200 + elif action == 'close': + targets.discard(target) + return f"Closed {ip}:{port}", 200 + else: + return f"Invalid action '{action}'", 400 + +if __name__ == '__main__': + threading.Thread(target=connector, daemon=True).start() + # Start the Flask server + app.run(host='127.0.0.1', port=8181) + diff --git a/util-scripts/external-entities/demo/dynamic-connector/dynamic-connector.yml b/util-scripts/external-entities/demo/dynamic-connector/dynamic-connector.yml new file mode 100644 index 0000000..662be36 --- /dev/null +++ b/util-scripts/external-entities/demo/dynamic-connector/dynamic-connector.yml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + generation: 1 + labels: + app: dynamic-connector + name: dynamic-connector + name: dynamic-connector + namespace: qa +spec: + minReadySeconds: 15 + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: dynamic-connector + name: dynamic-connector + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: dynamic-connector + deployment: dynamic-connector + name: dynamic-connector + name: dynamic-connector + namespace: qa + spec: + imagePullSecrets: + - name: qa + containers: + - image: quay.io/jvirtane/dynamic-connector:4.8.x-909-gd5216e5572 + imagePullPolicy: IfNotPresent + name: dynamic-connector + resources: {} + securityContext: + capabilities: {} + privileged: true + readOnlyRootFilesystem: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/util-scripts/external-entities/demo/dynamic-connector/pre-demo.sh b/util-scripts/external-entities/demo/dynamic-connector/pre-demo.sh new file mode 100755 index 0000000..d8f21a7 --- /dev/null +++ b/util-scripts/external-entities/demo/dynamic-connector/pre-demo.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -eou pipefail + +kubectl delete ns qa || true + +kubectl create ns qa + +kubectl create -f dynamic-connector.yml + +sleep 15 + +kubectl -n qa port-forward deploy/dynamic-connector 8181 > /dev/null 2>&1 & diff --git a/util-scripts/external-entities/demo/enable-collector-external-ips.sh b/util-scripts/external-entities/demo/enable-collector-external-ips.sh new file mode 100755 index 0000000..e8d9d9b --- /dev/null +++ b/util-scripts/external-entities/demo/enable-collector-external-ips.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eou pipefail + +kubectl create -f collector-config-enabled.yml diff --git a/util-scripts/external-entities/demo/external-destination-source-stable-template.yml b/util-scripts/external-entities/demo/external-destination-source-stable-template.yml new file mode 100644 index 0000000..b5df529 --- /dev/null +++ b/util-scripts/external-entities/demo/external-destination-source-stable-template.yml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + generation: 1 + labels: + app: external-destination-source-${NAME} + name: external-destination-source-${NAME} + name: external-destination-source-${NAME} + namespace: qa +spec: + minReadySeconds: 15 + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: external-destination-source-${NAME} + name: external-destination-source-${NAME} + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: external-destination-source-${NAME} + deployment: external-destination-source-${NAME} + name: external-destination-source-${NAME} + name: external-destination-source-${NAME} + namespace: qa + spec: + imagePullSecrets: + - name: qa + containers: + - args: + - | + /scripts/prepare-tap.sh -a "${TARGET_IP}/32" -o + nc -lk "${TARGET_IP}" "${PORT}" & + sleep 2 + while sleep 30; do nc -zv "${TARGET_IP}" "${PORT}"; done + command: + - /bin/bash + - -c + image: quay.io/${REPOSITORY}/external-connection:${TAG} + imagePullPolicy: IfNotPresent + name: external-destination-source + resources: {} + securityContext: + capabilities: {} + privileged: true + readOnlyRootFilesystem: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/util-scripts/external-entities/demo/external-destination-source.yml b/util-scripts/external-entities/demo/external-destination-source.yml new file mode 100644 index 0000000..690adb4 --- /dev/null +++ b/util-scripts/external-entities/demo/external-destination-source.yml @@ -0,0 +1,58 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + generation: 1 + labels: + app: external-destination-source + name: external-destination-source + name: external-destination-source + namespace: qa +spec: + minReadySeconds: 15 + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: external-destination-source + name: external-destination-source + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + creationTimestamp: null + labels: + app: external-destination-source + deployment: external-destination-source + name: external-destination-source + name: external-destination-source + namespace: qa + spec: + imagePullSecrets: + - name: qa + containers: + - args: + - while sleep 30; do wget -S -T 2 http://www.google.com; done + command: + - /bin/sh + - -c + image: quay.io/rhacs-eng/qa-multi-arch:nginx-1-15-4-alpine + imagePullPolicy: IfNotPresent + name: external-destination-source + resources: {} + securityContext: + capabilities: {} + privileged: false + readOnlyRootFilesystem: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/util-scripts/external-entities/demo/get-network-policy.sh b/util-scripts/external-entities/demo/get-network-policy.sh new file mode 100755 index 0000000..40a8a41 --- /dev/null +++ b/util-scripts/external-entities/demo/get-network-policy.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -eou pipefail + +ROX_ENDPOINT=${1:-localhost:8000} + +clusters_json="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/clusters" -k --header "Authorization: Bearer $ROX_API_TOKEN")" + +cluster_id="$(echo "$clusters_json" | jq -r '.clusters[0].id')" + +query="Cluster%3Aremote%2BNamespace%3Aqa&includePorts=true" +network_policy_json="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkpolicies/generate/${cluster_id}?deleteExisting=NONE&query=$query" -k --header "Authorization: Bearer $ROX_API_TOKEN")" + +network_policy=$(echo "$network_policy_json" | jq -r '.modification.applyYaml') + +printf "%b\n" "$network_policy" diff --git a/util-scripts/external-entities/demo/lock-baseline.sh b/util-scripts/external-entities/demo/lock-baseline.sh new file mode 100755 index 0000000..08298a5 --- /dev/null +++ b/util-scripts/external-entities/demo/lock-baseline.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -eou pipefail + +ROX_ENDPOINT=${1:-localhost:8000} + +deploymentname=${2:-external-destination-source-1} + +json_deployments="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/deployments" -k -H "Authorization: Bearer $ROX_API_TOKEN")" + +json_deployments="$(echo "$json_deployments" | jq --arg deploymentname "$deploymentname" '{deployments: [.deployments[] | select(.name == $deploymentname)]}')" +deployment="$(echo "$json_deployments" | jq --arg deploymentname "$deploymentname" '{deployments: [.deployments[] | select(.name == $deploymentname)]}' | jq -r .deployments[0].id)" + +echo "json_deployments= $deployment" + +json_status="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/status/external" -k -H "Authorization: Bearer $ROX_API_TOKEN")" + +echo "$json_status" | jq + + +json_status="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/lock" -k -H "Authorization: Bearer $ROX_API_TOKEN")" diff --git a/util-scripts/external-entities/demo/mark-as-anomalous.sh b/util-scripts/external-entities/demo/mark-as-anomalous.sh new file mode 100755 index 0000000..29f58c3 --- /dev/null +++ b/util-scripts/external-entities/demo/mark-as-anomalous.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -eoux pipefail + +ROX_ENDPOINT=${1:-localhost:8000} + +deploymentname=${2:-external-destination-source-1} + +json_deployments="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/deployments" -k -H "Authorization: Bearer $ROX_API_TOKEN")" + +json_deployments="$(echo "$json_deployments" | jq --arg deploymentname "$deploymentname" '{deployments: [.deployments[] | select(.name == $deploymentname)]}')" +deployment="$(echo "$json_deployments" | jq --arg deploymentname "$deploymentname" '{deployments: [.deployments[] | select(.name == $deploymentname)]}' | jq -r .deployments[0].id)" + +echo "json_deployments= $deployment" + +json_status="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/status/external" -k -H "Authorization: Bearer $ROX_API_TOKEN")" + +echo "$json_status" | jq + +echo +echo +echo +echo + +json_new_status="$(echo "$json_status" | jq -c '.anomalous |= map(.status = (if .status == "ANOMALOUS" then "BASELINE" else .status end))')" + + +echo "$json_new_status" | jq + +#cidr_json='{"entity": {"cidr": "'"$cidr_block"'", "name": "'"$cidr_name"'", "id": ""}}' + +#create_cidr_block_response_json="$(curl --location --silent --request POST --data "$cidr_json" "https://${ROX_ENDPOINT}/v1/networkgraph/cluster/$cluster_id/externalentities" -k --header "Authorization: Bearer $ROX_API_TOKEN")" + +echo +echo +echo +echo +echo "Setting new status" +curl --location --silent --request POST --data "$json_new_status" "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/peers" -k --header "Authorization: Bearer $ROX_API_TOKEN" + +echo +echo +echo +echo + +echo "Checking the new status" +json_updated_status="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/status/external" -k -H "Authorization: Bearer $ROX_API_TOKEN")" + + +echo "$json_updated_status" | jq diff --git a/util-scripts/external-entities/demo/prepare-tap.sh b/util-scripts/external-entities/demo/prepare-tap.sh new file mode 100755 index 0000000..e538725 --- /dev/null +++ b/util-scripts/external-entities/demo/prepare-tap.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -eou pipefail + +# This script helps to prepare an environment for developing berserker network +# workload. It has the following preparatory steps: +# * Create and start up a new tun device for berserker to use +# * Optionally prepare iptables for the device to be visible +# +# The last step is optional, because iptables configuration could be different +# between development environments. Meaning it's not guaranteed that this part of +# the script is suitable for every case. + +stop() { echo "$*" 1>&2 ; exit 1; } + +which ip &>/dev/null || stop "Don't have the ip tool" +which whoami &>/dev/null || stop "Don't have the whoami tool" +which sysctl &>/dev/null || stop "Don't have the sysctl tool" + +ADDRESS="10.0.0.1/16" +NAME="berserker0" +USER="$(whoami)" +CONFIGURE_IPTABLE="false" +CONFIGURE_FIREWALLD="false" +CONFIGURE_TUNTAP_IF_EXISTS="false" + +while getopts ":a:t:u:i:fo" opt; do + case $opt in + a) ADDRESS="${OPTARG}" + ;; + t) NAME="${OPTARG}" + ;; + u) USER="${OPTARG}" + ;; + i) CONFIGURE_IPTABLE="true" + ;; + f) CONFIGURE_FIREWALLD="true" + ;; + o) CONFIGURE_TUNTAP_IF_EXISTS="true" + ;; + \?) echo "Invalid option -$OPTARG" >&2 + exit 1 + ;; + esac +done + +echo "Verifying if device ${NAME} is already created..." +if ip tuntap | grep "${NAME}" &> /dev/null; +then + echo "The devince ${NAME} already exists!" + if [[ "${CONFIGURE_TUNTAP_IF_EXISTS}" != "true" ]] + then + exit 1; + fi + + ip link delete "${NAME}" +fi + +echo "Creating tun device ${NAME} for user ${USER}..." +ip tuntap add name "${NAME}" mode tun user "${USER}" +ip link set "${NAME}" up + +echo "Assigning address ${ADDRESS} to device ${NAME}..." +ip addr add "${ADDRESS}" dev "${NAME}" + +if [[ "${CONFIGURE_FIREWALLD}" == "true" ]]; +then + which firewall-cmd &>/dev/null || stop "Don't have the firewal-cmd tool" + + echo "Adding to the trusted zone..." + firewall-cmd --zone=trusted --add-interface="${NAME}" +fi + +if [[ "${CONFIGURE_IPTABLE}" == "true" ]]; +then + which iptables &>/dev/null || stop "Don't have the iptables tool" + + echo "Enabling ip forward..." + sysctl net.ipv4.ip_forward=1 + + echo "Preparing iptable..." + iptables -t nat -A POSTROUTING -s "${ADDRESS}" -j MASQUERADE + iptables -A FORWARD -i "${NAME}" -s "${ADDRESS}" -j ACCEPT + iptables -A FORWARD -o "${NAME}" -d "${ADDRESS}" -j ACCEPT + + RULE_NR=$(iptables -t filter -L INPUT --line-numbers |\ + grep "REJECT all" |\ + awk '{print $1}') + + # Excempt tun device from potentiall reject all rule + if [[ $RULE_NR == "" ]]; then + iptables -I INPUT -i "${NAME}" -s "${ADDRESS}" -j ACCEPT + else + iptables -I INPUT $((RULE_NR - 1)) -i "${NAME}" -s "${ADDRESS}" -j ACCEPT + fi +fi diff --git a/util-scripts/external-entities/demo/scenario.sh b/util-scripts/external-entities/demo/scenario.sh new file mode 100755 index 0000000..c6c2fcf --- /dev/null +++ b/util-scripts/external-entities/demo/scenario.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -eou pipefail + +# Running these commands one by one is recommended instead of running this script. +# Check the UI after each command. +# This assumes that ACS has been deployed with ROX_EXTERNAL_IPS and ROX_NETWORK_GRAPH_EXTERNAL_IPS + +# Cleanup from previous runs +kubectl delete ns qa || true +kubectl -n stackrox delete configmap collector-config || true + +kubectl create ns qa + +# Create the image pull secret +./create-secret-for-qa.sh + +# Enable collection of external IPs by collector +./enable-collector-external-ips.sh + +#sleep 60 + +# Create a deployment that reaches out to google in the qa namespace +kubectl create -f external-destination-source.yml + +# Create a deployment that reaches out to 8.8.8.8 +./create-deployment-with-ext-ip.sh 8.8.8.8 53 1 + +# Remove comments before merging +# Create a CIDR block that matches the above deployment +#./create-cidr-block.sh 8.8.8.0/24 testCIDR + + +# Create a deployment that reaches out to 1.1.1.1 +./create-deployment-with-ext-ip.sh 1.1.1.1 53 2 + +# Get a network policy based on the network graph +# and apply it +./get-network-policy.sh > net-pol.yml +kubectl create -f net-pol.yml + +# Create a deployment that reaches out to 2.2.2.2 +./create-deployment-with-ext-ip.sh 2.2.2.2 53 3 + +# Remove comments before merging +# Try with different ports +# Mark as anom +# Alert on violations diff --git a/util-scripts/external-entities/demo/setup-env-var.sh b/util-scripts/external-entities/demo/setup-env-var.sh new file mode 100644 index 0000000..839a397 --- /dev/null +++ b/util-scripts/external-entities/demo/setup-env-var.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +export ROX_EXTERNAL_IPS=true +export ROX_NETWORK_GRAPH_EXTERNAL_IPS=true