From 0fc65cb8a157e1347e572354233009947680c3df Mon Sep 17 00:00:00 2001 From: denverwilliams Date: Wed, 16 Aug 2023 21:54:23 +0000 Subject: [PATCH] Update 5G auth test to use templated configuration to setup ueransim cncf/cnf-testsuite#1803 --- embedded_files/ue.yaml | 84 ++++++++ embedded_files/ues-values.yml | 19 -- sample-cnfs/sample_open5gs/cnf-testsuite.yml | 2 + src/tasks/constants.cr | 2 +- src/tasks/utils/config.cr | 5 + src/tasks/utils/embedded_file_manager.cr | 4 +- src/tasks/utils/task.cr | 1 + src/tasks/utils/ueransim.cr | 28 +++ src/tasks/workload/5g.cr | 209 ++++++++++++------- src/templates/ues-values-template.yml.ecr | 38 ++++ 10 files changed, 300 insertions(+), 92 deletions(-) create mode 100644 embedded_files/ue.yaml delete mode 100644 embedded_files/ues-values.yml create mode 100644 src/templates/ues-values-template.yml.ecr diff --git a/embedded_files/ue.yaml b/embedded_files/ue.yaml new file mode 100644 index 000000000..de93f6869 --- /dev/null +++ b/embedded_files/ue.yaml @@ -0,0 +1,84 @@ +# IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits) + +supi: 'imsi-{{ .Values.mcc }}{{ .Values.mnc }}{{ .Values.ues.initialMSISDN }}' +mcc: '{{ .Values.mcc }}' +mnc: '{{ .Values.mnc }}' + +# SUCI Protection Config +{{ if .Values.protectionScheme }} +protectionScheme: '{{ .Values.protectionScheme }}' +{{ end }} +{{ if .Values.publicKey }} +homeNetworkPublicKey: '{{ .Values.publicKey }}' +{{ end }} +{{ if .Values.publicKeyId }} +homeNetworkPublicKeyId: '{{ .Values.publicKeyId }}' +{{ end }} +{{ if .Values.routingIndicator }} +routingIndicator: '{{ .Values.routingIndicator }}' +{{ end }} + + +# Permanent subscription key +key: '{{ .Values.ues.key }}' +# Operator code (OP or OPC) of the UE +op: '{{ .Values.ues.op }}' +# This value specifies the OP type and it can be either 'OP' or 'OPC' +opType: '{{ .Values.ues.opType }}' +# Authentication Management Field (AMF) value +amf: '8000' +# IMEI number of the device. It is used if no SUPI is provided +imei: '356938035643803' +# IMEISV number of the device. It is used if no SUPI and IMEI is provided +imeiSv: '4370816125816151' + +# List of gNB IP addresses for Radio Link Simulation +gnbSearchList: + - ${GNB_IP} + + # UAC Access Identities Configuration +uacAic: + mps: false + mcs: false + +# UAC Access Control Class +uacAcc: + normalClass: 0 + class11: false + class12: false + class13: false + class14: false + class15: false + +# Initial PDU sessions to be established +sessions: + {{- range .Values.ues.apnList }} + - {{- toYaml . | nindent 4 }} + {{- end }} + +# Configured NSSAI for this UE by HPLMN +configured-nssai: + - sst: {{ .Values.sst }} + sd: {{ .Values.sd }} + +# Default Configured NSSAI for this UE +default-nssai: + - sst: {{ .Values.sst }} + sd: {{ .Values.sd }} + +# Supported encryption algorithms by this UE +integrity: + IA1: true + IA2: true + IA3: true + +# Supported integrity algorithms by this UE +ciphering: + EA1: true + EA2: true + EA3: true + +# Integrity protection maximum data rate for user plane +integrityMaxRate: + uplink: 'full' + downlink: 'full' diff --git a/embedded_files/ues-values.yml b/embedded_files/ues-values.yml deleted file mode 100644 index adec414f9..000000000 --- a/embedded_files/ues-values.yml +++ /dev/null @@ -1,19 +0,0 @@ -amf: - hostname: open5gs-amf-ngap - -mcc: '999' -mnc: '70' -sst: 1 -sd: "0x111111" -tac: '0001' - -ues: - enabled: true - count: 1 - initialMSISDN: '0000000001' - -image: - registry: docker.io - repository: conformance/ueransim - tag: latest - diff --git a/sample-cnfs/sample_open5gs/cnf-testsuite.yml b/sample-cnfs/sample_open5gs/cnf-testsuite.yml index b0e405f5f..6c6af182f 100644 --- a/sample-cnfs/sample_open5gs/cnf-testsuite.yml +++ b/sample-cnfs/sample_open5gs/cnf-testsuite.yml @@ -2,3 +2,5 @@ helm_directory: open5gs release_name: open5gs allowlist_helm_chart_container_names: [] +#optional 5gcore tag +core: app.kubernetes.io/name=amf diff --git a/src/tasks/constants.cr b/src/tasks/constants.cr index c0a38a8c8..82c6b6295 100644 --- a/src/tasks/constants.cr +++ b/src/tasks/constants.cr @@ -38,7 +38,7 @@ EmbeddedFileManager.constraint_template EmbeddedFileManager.disable_cni EmbeddedFileManager.fluentd_values EmbeddedFileManager.fluentbit_values -EmbeddedFileManager.ues_values +EmbeddedFileManager.ueransim_helmconfig EXCLUDE_NAMESPACES = [ "kube-system", diff --git a/src/tasks/utils/config.cr b/src/tasks/utils/config.cr index 75876489c..f9dcccc0a 100644 --- a/src/tasks/utils/config.cr +++ b/src/tasks/utils/config.cr @@ -13,6 +13,7 @@ module CNFManager @cnf_config = cnf_config @airgapped = airgapped end + #when addeding to this you must add to task.cr's CNFManager::Config.new( property cnf_config : NamedTuple(destination_cnf_dir: String, source_cnf_file: String, source_cnf_dir: String, @@ -33,6 +34,8 @@ module CNFManager container_names: Array(Hash(String, String )) | Nil, white_list_container_names: Array(String), docker_insecure_registries: Array(String) | Nil, + #todo change this to an array of labels that capture all of 5g core nodes + core: String, image_registry_fqdns: Hash(String, String ) | Nil) def self.parse_config_yml(config_yml_path : String, airgapped=false, generate_tar_mode=false) : CNFManager::Config @@ -70,6 +73,7 @@ module CNFManager helm_directory = optional_key_as_string(config, "helm_directory") source_helm_directory = optional_key_as_string(config, "helm_directory") helm_install_namespace = optional_key_as_string(config, "helm_install_namespace") + core = optional_key_as_string(config, "core") if helm_directory.empty? working_chart_directory = "exported_chart" Log.info { "USING EXPORTED CHART PATH" } @@ -147,6 +151,7 @@ module CNFManager container_names: container_names, white_list_container_names: white_list_container_names, docker_insecure_registries: docker_insecure_registries, + core: core, image_registry_fqdns: image_registry_fqdns,}) end diff --git a/src/tasks/utils/embedded_file_manager.cr b/src/tasks/utils/embedded_file_manager.cr index b8ed29d54..e067cab4d 100644 --- a/src/tasks/utils/embedded_file_manager.cr +++ b/src/tasks/utils/embedded_file_manager.cr @@ -40,8 +40,8 @@ module EmbeddedFileManager macro fluentbit_values FLUENTBIT_VALUES = Base64.decode_string("{{ `cat ./embedded_files/fluentbit-config.yml | base64`}}") end - macro ues_values - UES_VALUES = Base64.decode_string("{{ `cat ./embedded_files/ues-values.yml | base64`}}") + macro ueransim_helmconfig + UERANSIM_HELMCONFIG = Base64.decode_string("{{ `cat ./embedded_files/ue.yaml | base64`}}") end def self.points_yml_write_file File.write("points.yml", POINTSFILE) diff --git a/src/tasks/utils/task.cr b/src/tasks/utils/task.cr index a619248bb..529a6ecc9 100644 --- a/src/tasks/utils/task.cr +++ b/src/tasks/utils/task.cr @@ -82,6 +82,7 @@ module CNFManager container_names: [{"name" => "", "rolling_update_test_tag" => ""}], white_list_container_names: [""], docker_insecure_registries: [] of String, + core: "", image_registry_fqdns: Hash(String, String).new} ) end ret = yield args, config diff --git a/src/tasks/utils/ueransim.cr b/src/tasks/utils/ueransim.cr index 23e8012e2..c083cb0c7 100644 --- a/src/tasks/utils/ueransim.cr +++ b/src/tasks/utils/ueransim.cr @@ -17,6 +17,34 @@ module UERANSIM KubectlClient::Get.resource_wait_for_install("Pod", "ueransim") end + class Template + # The argument for insecure_registries is a string + # because the template only writes the content + # and expects a list of comma separated strings. + def initialize(@amf_pod_name : String, + @mmc : String, + @mnc : String, + @sst : String, + @sd : String, + @tac : String, + @protectionScheme : String, + @publicKey : String, + @publicKeyId : String, + @routingIndicator : String, + @enabled : String, + @count : String, + @initialMSISDN : String, + @key : String, + @op : String, + @opType : String, + @type : String, + @apn : String, + @emergency : String + ) + end + ECR.def_to_s("src/templates/ues-values-template.yml.ecr") + end + end diff --git a/src/tasks/workload/5g.cr b/src/tasks/workload/5g.cr index 4d869e2fb..9131c9e4b 100644 --- a/src/tasks/workload/5g.cr +++ b/src/tasks/workload/5g.cr @@ -10,83 +10,152 @@ task "suci_enabled" do |_, args| test_name = "specialized_init_system" CNFManager::Task.task_runner(args) do |args, config| Log.info { "Running #{test_name} test" } - - - #TODO cluster_tools exec tshark command: tshark -ni any -Y nas_5gs.mm.type_id -T json > test.file - #todo use sane defaults (i.e. search for amf, upf, etc in pod names) if no 5gcore labels are present - #todo get 5gcore pods - all_pods = KubectlClient::Get.pods_by_nodes(KubectlClient::Get.schedulable_nodes_list) - pods = KubectlClient::Get.pods_by_label(all_pods, "app.kubernetes.io/instance", "open5gs") - fivegpod = pods[0]? - Log.info { "fivegpod: #{fivegpod}" } - if fivegpod && fivegpod.dig?("metadata", "name") - Log.info { "fivegpod #{fivegpod} metadata name: #{fivegpod.dig?("metadata", "name")}" } - fivegcore_pod_name = fivegpod.dig("metadata", "name") - Log.info { "fivegcore_pod_name: #{fivegcore_pod_name}" } - # nodes = KubectlClient::Get.nodes_by_pod(fivegcore_pod_name) - nodes = KubectlClient::Get.nodes_by_pod(fivegpod) - node = nodes.first - #todo get node for 5gcore - #todo deploy ueransim to same node as the 5gcore - #TODO look for connection text (sanity check) - # ClusterTools.exec("tshark -ni any -Y nas_5gs.mm.type_id -T json > test.log") - #todo name_id = random number - rnd = Random.new - name_id = rnd.next_int - tshark_log_name = "/tmp/tshark-#{name_id}.json" - Log.info { "tshark_log_name #{tshark_log_name}" } - ClusterTools.exec_by_node_bg("tshark -ni any -Y nas_5gs.mm.type_id -T json 2>&1 | tee #{tshark_log_name}", node) - Log.info { "after exec by node bg" } - - #todo put in prereq - - ueran_pods = KubectlClient::Get.pods_by_label(all_pods, "app.kubernetes.io/name", "ueransim-gnb") - - Log.info { "ueran_pods: #{ueran_pods}" } - if ueran_pods[0]? == nil - Helm.fetch("openverso/ueransim-gnb --version 0.2.5 --untar") - File.write("gnb-ues-values.yaml", UES_VALUES) - Helm.install("ueransim #{Dir.current}/ueransim-gnb --values ./gnb-ues-values.yaml") - Log.info { "after helm install" } - else - Helm.delete("ueransim") - Helm.fetch("openverso/ueransim-gnb --version 0.2.5 --untar") - File.write("gnb-ues-values.yaml", UES_VALUES) - Helm.install("ueransim #{Dir.current}/ueransim-gnb --values ./gnb-ues-values.yaml") - Log.info { "after helm install" } - end - - # pid_log_names << pid_log_name - - - # todo save off all directory/filenames into a hash - #strace: Process 94273 attached - # ---SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=1, si_uid=0} --- - # --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=0, si_uid=0} --- - #todo 2.2 wait for 30 seconds - - # ClusterTools.exec_by_node("bash -c 'sleep 10 && kill #{pid} && sleep 5 && kill -9 #{pid}'", node) - sleep 20.0 - Log.info { "tshark_log_name: #{tshark_log_name}" } - resp = File.read("#{tshark_log_name}") - Log.info { "tshark_log_name resp: #{resp}" } - ans : Bool - if resp - Log.info { "resp: #{resp}" } - if resp =~ /"nas_5gs.mm.type_id": "1"/ - ans = true + Log.debug { "cnf_config: #{config}" } + core = config.cnf_config[:core]? + Log.info { "core: #{core}" } + core_key : String = "" + core_value : String = "" + core_key = config.cnf_config[:core].split("=").first if core + core_value = config.cnf_config[:core].split("=").last if core + if core + + + + #TODO cluster_tools exec tshark command: tshark -ni any -Y nas_5gs.mm.type_id -T json > test.file + #todo use sane defaults (i.e. search for amf, upf, etc in pod names) if no 5gcore labels are present + #todo get 5gcore pods + all_pods = KubectlClient::Get.pods_by_nodes(KubectlClient::Get.schedulable_nodes_list) + # pods = KubectlClient::Get.pods_by_label(all_pods, "app.kubernetes.io/instance", "open5gs") + pods = KubectlClient::Get.pods_by_label(all_pods, core_key, core_value) + fivegpod = pods[0]? + Log.info { "fivegpod: #{fivegpod}" } + if fivegpod && fivegpod.dig?("metadata", "name") + Log.info { "fivegpod #{fivegpod} metadata name: #{fivegpod.dig?("metadata", "name")}" } + fivegcore_pod_name = fivegpod.dig("metadata", "name") + Log.info { "fivegcore_pod_name: #{fivegcore_pod_name}" } + # nodes = KubectlClient::Get.nodes_by_pod(fivegcore_pod_name) + nodes = KubectlClient::Get.nodes_by_pod(fivegpod) + node = nodes.first + #todo get node for 5gcore + #todo deploy ueransim to same node as the 5gcore + #TODO look for connection text (sanity check) + # ClusterTools.exec("tshark -ni any -Y nas_5gs.mm.type_id -T json > test.log") + #todo name_id = random number + rnd = Random.new + name_id = rnd.next_int + tshark_log_name = "/tmp/tshark-#{name_id}.json" + Log.info { "tshark_log_name #{tshark_log_name}" } + ClusterTools.exec_by_node_bg("tshark -ni any -Y nas_5gs.mm.type_id -T json 2>&1 | tee #{tshark_log_name}", node) + Log.info { "after exec by node bg" } + + #todo put in prereq + + ueran_pods = KubectlClient::Get.pods_by_label(all_pods, "app.kubernetes.io/name", "ueransim-gnb") + + Log.info { "ueran_pods: #{ueran_pods}" } + if ueran_pods[0]? == nil + # Helm.fetch("openverso/ueransim-gnb --version 0.2.5 --untar") + # #todo get variables from the cnf-testsuite.yml + # ue_values = UERANSIM::Template.new("open5gs-amf-ngap", + # "999", + # "70", + # "1", + # "0x111111", + # "0001", + # "", + # "", + # "", + # "", + # "true", + # "1", + # "0000000001", + # "465B5CE8B199B49FAA5F0A2EE238A6BC", + # "E8ED289DEBA952E4283B54E88E6183CA", + # "OPC", + # "IPv4", + # "internet", + # "false" + # ).to_s + # Log.info { "ue_values: #{ue_values}" } + # File.write("gnb-ues-values.yaml", ue_values) + # # File.write("gnb-ues-values.yaml", UES_VALUES) + # File.write("#{Dir.current}/ueransim-gnb/resources/ue.yaml", UERANSIM_HELMCONFIG) + # Helm.install("ueransim #{Dir.current}/ueransim-gnb --values ./gnb-ues-values.yaml") + # Log.info { "after helm install" } else + Helm.delete("ueransim") + # Helm.fetch("openverso/ueransim-gnb --version 0.2.5 --untar") + # # File.write("gnb-ues-values.yaml", UES_VALUES) + # File.write("#{Dir.current}/ueransim-gnb/resources/ue.yaml", UERANSIM_HELMCONFIG) + # Helm.install("ueransim #{Dir.current}/ueransim-gnb --values ./gnb-ues-values.yaml") + # Log.info { "after helm install" } + end + Helm.fetch("openverso/ueransim-gnb --version 0.2.5 --untar") + #todo get variables from the cnf-testsuite.yml + ue_values = UERANSIM::Template.new("open5gs-amf-ngap", + "999", + "70", + "1", + "0x111111", + "0001", + "protectionScheme: 1", + "publicKey: '0ac95ceeb93308df01be82ff9994d8330e38804ece1700ee4b972d8028796275'", + "publicKeyId: 1", + "routingIndicator: '0000'", + "true", + "1", + "0000000001", + "465B5CE8B199B49FAA5F0A2EE238A6BC", + "E8ED289DEBA952E4283B54E88E6183CA", + "OPC", + "IPv4", + "internet", + "false" + ).to_s + Log.info { "ue_values: #{ue_values}" } + File.write("gnb-ues-values.yaml", ue_values) + # File.write("gnb-ues-values.yaml", UES_VALUES) + File.write("#{Dir.current}/ueransim-gnb/resources/ue.yaml", UERANSIM_HELMCONFIG) + Helm.install("ueransim #{Dir.current}/ueransim-gnb --values ./gnb-ues-values.yaml") + Log.info { "after helm install" } + + # pid_log_names << pid_log_name + + + # todo save off all directory/filenames into a hash + #strace: Process 94273 attached + # ---SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=1, si_uid=0} --- + # --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=0, si_uid=0} --- + #todo 2.2 wait for 30 seconds + + # ClusterTools.exec_by_node("bash -c 'sleep 10 && kill #{pid} && sleep 5 && kill -9 #{pid}'", node) + sleep 20.0 + Log.info { "tshark_log_name: #{tshark_log_name}" } + resp = File.read("#{tshark_log_name}") + Log.info { "tshark_log_name resp: #{resp}" } + ans : Bool + if resp Log.info { "resp: #{resp}" } + # use suci encyption but don't use a null encryption key + if resp =~ /"nas_5gs.mm.type_id": "1"/ && + (resp =~ /"nas_5gs.mm.suci.scheme_id": "0"/) == nil && + (resp =~ /"nas_5gs.mm.suci.pki": "0"/) == nil + ans = true + else + Log.info { "resp: #{resp}" } + ans = false + end + else ans = false end + Log.info { "found nas_5gs.mm.type_id: 1: #{ans}" } + + #todo delete log file else - ans = false + puts "no 5g labels" end - Log.info { "found nas_5gs.mm.type_id: 1: #{ans}" } - - #todo delete log file else - puts "no 5g labels" + puts "You must set the core label for you AMF node" end #todo cluster_tools exec get text-.file diff --git a/src/templates/ues-values-template.yml.ecr b/src/templates/ues-values-template.yml.ecr new file mode 100644 index 000000000..ca4fe5937 --- /dev/null +++ b/src/templates/ues-values-template.yml.ecr @@ -0,0 +1,38 @@ +amf: + hostname: <%= @amf_pod_name %> + +mcc: '<%= @mmc %>' +mnc: '<%= @mnc %>' +sst: <%= @sst %> +sd: "<%= @sd %>" +tac: '<%= @tac %>' + +<%= @protectionScheme %> +<%= @publicKey %> +<%= @publicKeyId %> +<%= @routingIndicator %> +# protectionScheme: 0 +# publicKey: +# publicKeyId: 1 +# routingIndicator: '0000' + +ues: + enabled: <%= @enabled %> + count: <%= @count %> + initialMSISDN: '<%= @initialMSISDN %>' + key: <%= @key %> + op: <%= @op %> + opType: <%= @opType %> + apnList: + - type: '<%= @type %>' + apn: '<%= @apn %>' + slice: + sst: <%= @sst %> + sd: "<%= @sd %>" + emergency: <%= @emergency %> + +image: + registry: docker.io + repository: conformance/ueransim + tag: latest +