From 6d28498338250d5d42e2b742b44ab27515c04ac4 Mon Sep 17 00:00:00 2001 From: ajasnosz Date: Wed, 18 Dec 2024 14:03:38 +0100 Subject: [PATCH 1/2] fix: same ports for ipv4, ipv6 traps --- .../templates/traps/service.yaml | 11 +------- .../values.schema.json | 6 ----- charts/splunk-connect-for-snmp/values.yaml | 2 -- docker_compose/.env | 1 - docker_compose/docker-compose.yaml | 4 --- docs/dockercompose/10-enable-ipv6.md | 3 --- .../dockercompose/6-env-file-configuration.md | 2 -- .../values-params-description.md | 4 +-- docs/microk8s/enable-ipv6.md | 2 -- integration_tests/.env | 1 - splunk_connect_for_snmp/snmp/auth.py | 2 +- splunk_connect_for_snmp/snmp/tasks.py | 11 ++++++++ splunk_connect_for_snmp/traps.py | 17 +++++++------ test/snmp/test_tasks.py | 25 +++++++++++++++++++ 14 files changed, 48 insertions(+), 43 deletions(-) diff --git a/charts/splunk-connect-for-snmp/templates/traps/service.yaml b/charts/splunk-connect-for-snmp/templates/traps/service.yaml index 967e0c646..2b0ab1f8d 100644 --- a/charts/splunk-connect-for-snmp/templates/traps/service.yaml +++ b/charts/splunk-connect-for-snmp/templates/traps/service.yaml @@ -26,21 +26,12 @@ spec: {{- end }} ports: - port: {{ .Values.traps.service.port }} - {{- if and .Values.traps.service.nodePort (eq .Values.traps.service.type "NodePort")}} + {{- if and .Values.traps.service.nodePort (eq .Values.traps.service.type "NodePort") }} nodePort: {{ .Values.traps.service.nodePort | default 30000 }} {{- end }} targetPort: 2162 protocol: UDP name: snmp-udp - {{- if has "IPv6" .Values.traps.ipFamilies}} - - port: {{ .Values.traps.service.ipv6Port | default 2163}} - {{- if and .Values.traps.service.nodePort (eq .Values.traps.service.type "NodePort")}} - nodePort: {{ .Values.traps.service.ipv6NodePort | default 30003 }} - {{- end }} - targetPort: 2163 - protocol: UDP - name: snmp-udp6 - {{- end }} selector: {{- include "splunk-connect-for-snmp.traps.selectorLabels" . | nindent 4 }} {{- end -}} \ No newline at end of file diff --git a/charts/splunk-connect-for-snmp/values.schema.json b/charts/splunk-connect-for-snmp/values.schema.json index 8a3eac876..478856e4a 100644 --- a/charts/splunk-connect-for-snmp/values.schema.json +++ b/charts/splunk-connect-for-snmp/values.schema.json @@ -743,12 +743,6 @@ }, "nodePort": { "type": "integer" - }, - "ipv6Port": { - "type": "integer" - }, - "ipv6NodePort": { - "type": "integer" } } }, diff --git a/charts/splunk-connect-for-snmp/values.yaml b/charts/splunk-connect-for-snmp/values.yaml index 6edb801c6..19e1026b5 100644 --- a/charts/splunk-connect-for-snmp/values.yaml +++ b/charts/splunk-connect-for-snmp/values.yaml @@ -434,11 +434,9 @@ traps: # on a multi-node it's better to set this as NodePort and configure traps.service.nodePort type: LoadBalancer port: 162 - # ipv6Port: 2163 # nodePort will be set only when type of service is a NodePort #nodePort: 30000 - #ipv6NodePort: 30003 #loadBalancerIP must be set to the IP address in the metallb pool. #It is required when service type is set to LoadBalancer. diff --git a/docker_compose/.env b/docker_compose/.env index 43e1184c6..6aedf906f 100644 --- a/docker_compose/.env +++ b/docker_compose/.env @@ -89,7 +89,6 @@ CHAIN_OF_TASKS_EXPIRY_TIME=500 # Traps configuration SNMP_V3_SECURITY_ENGINE_ID=80003a8c04 TRAPS_PORT=162 -IPv6_TRAPS_PORT=2163 TRAP_LOG_LEVEL=INFO # Scheduler configuration diff --git a/docker_compose/docker-compose.yaml b/docker_compose/docker-compose.yaml index 2b578c5f2..2c99025cd 100644 --- a/docker_compose/docker-compose.yaml +++ b/docker_compose/docker-compose.yaml @@ -148,10 +148,6 @@ services: protocol: udp published: ${TRAPS_PORT} target: 2162 - - mode: host - protocol: udp - published: ${IPv6_TRAPS_PORT} - target: 2163 volumes: - ${TRAPS_CONFIG_FILE_ABSOLUTE_PATH}:/app/config/config.yaml:ro - traps-pysnmp-cache-volume:/.pysnmp/:rw diff --git a/docs/dockercompose/10-enable-ipv6.md b/docs/dockercompose/10-enable-ipv6.md index 488820d8b..b0e1a6886 100644 --- a/docs/dockercompose/10-enable-ipv6.md +++ b/docs/dockercompose/10-enable-ipv6.md @@ -12,7 +12,4 @@ To enable IPv6 for SC4SNMP, set `IPv6_ENABLED` variable to `true` in `.env` file The default subnet used for SC4SNMP network in docker is `fd02::/64`, this configuration can be changed in `.env` file under `Network configuration` section. In case of configuring more than one IPv4 and IPv6 subnet in IPAM, `networks` section of `docker-compose.yaml` should be edited. -Default trap port for notifications for IPv6 is `2163`. You can change it to any other port if needed with `IPv6_TRAPS_PORT` parameter in `.env` file. -The IPv6 port and IPv4 port cannot be the same. - For more information about IPv6 networking in docker, you can check the [official Docker documentation](https://docs.docker.com/engine/daemon/ipv6/). \ No newline at end of file diff --git a/docs/dockercompose/6-env-file-configuration.md b/docs/dockercompose/6-env-file-configuration.md index ca61a77ea..d9a4f7977 100644 --- a/docs/dockercompose/6-env-file-configuration.md +++ b/docs/dockercompose/6-env-file-configuration.md @@ -125,8 +125,6 @@ Inside the directory with the docker compose files, there is a `.env`. Variables |------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `SNMP_V3_SECURITY_ENGINE_ID` | SNMPv3 TRAPs require the configuration SNMP Engine ID of the TRAP sending application for the USM users table of the TRAP receiving application for each USM user, for example: SNMP_V3_SECURITY_ENGINE_ID=80003a8c04,aab123456 | | `TRAPS_PORT` | External port exposed for traps server | -| `IPv6_TRAPS_PORT` | External port exposed for traps server for IPv6 | - ## Scheduler | Variable | Description | diff --git a/docs/microk8s/configuration/values-params-description.md b/docs/microk8s/configuration/values-params-description.md index 49fc0c2b0..6c3940e4e 100644 --- a/docs/microk8s/configuration/values-params-description.md +++ b/docs/microk8s/configuration/values-params-description.md @@ -166,11 +166,9 @@ Detailed documentation about configuring traps can be found in [Traps](trap-conf | `service.usemetallb` | Enables using metallb | `true` | | `service.metallbsharingkey` | Sets metallb.universe.tf/allow-shared-ip annotation in trap service | `splunk-connect` | | `service.type` | [Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) | `LoadBalancer` | -| `service.port` | Port of the service to use for IPv4 | `162` | +| `service.port` | Port of the service to use for IPv4 and IPv6 | `162` | | `service.nodePort` | Port when the `service.type` is `nodePort` | `30000` | | `service.externalTrafficPolicy` | Controls how Kubernetes routes traffic | `Local` | -| `service.ipv6Port` | Port of the service to use for IPv6 | `162` | -| `service.ipv6NodePort` | Port when the `service.type` is `nodePort` and IPv6 is enabled | `2163` | | `loadBalancerIP` | Sets loadBalancer IP address in the metallb pool | `` | | `ipFamilyPolicy` | Specifies if the service is dual stack or single stack | `SingleStack` | | `ipFamilies` | Defines the address families used for chosen `ipFamilyPolicy` | `IPv4` | diff --git a/docs/microk8s/enable-ipv6.md b/docs/microk8s/enable-ipv6.md index cd9a5f5f3..c189c7862 100644 --- a/docs/microk8s/enable-ipv6.md +++ b/docs/microk8s/enable-ipv6.md @@ -63,5 +63,3 @@ traps: ipFamilyPolicy: RequireDualStack ipFamilies: ["IPv4", "IPv6"] ``` -Default trap port for notifications for IPv6 is `2163`. You can change it to any other port if needed with `traps.service.ipv6Port` parameter. -The IPv6 port and IPv4 port cannot be the same. \ No newline at end of file diff --git a/integration_tests/.env b/integration_tests/.env index 8cabcf4d9..e522a32b0 100644 --- a/integration_tests/.env +++ b/integration_tests/.env @@ -82,7 +82,6 @@ CHAIN_OF_TASKS_EXPIRY_TIME=500 # Traps configuration SNMP_V3_SECURITY_ENGINE_ID=80003a8c04 TRAPS_PORT=162 -IPv6_TRAPS_PORT=2163 TRAP_LOG_LEVEL=INFO # Scheduler configuration diff --git a/splunk_connect_for_snmp/snmp/auth.py b/splunk_connect_for_snmp/snmp/auth.py index 96ee4d7f9..aa5cff1b0 100644 --- a/splunk_connect_for_snmp/snmp/auth.py +++ b/splunk_connect_for_snmp/snmp/auth.py @@ -36,7 +36,7 @@ from splunk_connect_for_snmp.snmp.exceptions import SnmpActionError UDP_CONNECTION_TIMEOUT = int(os.getenv("UDP_CONNECTION_TIMEOUT", 1)) -IPv6_ENABLED = human_bool(os.getenv("IPv6_ENABLED", False)) +IPv6_ENABLED = human_bool(os.getenv("IPv6_ENABLED", "false").lower()) def get_secret_value( diff --git a/splunk_connect_for_snmp/snmp/tasks.py b/splunk_connect_for_snmp/snmp/tasks.py index b7c852613..d80647263 100644 --- a/splunk_connect_for_snmp/snmp/tasks.py +++ b/splunk_connect_for_snmp/snmp/tasks.py @@ -51,6 +51,7 @@ RESOLVE_TRAP_ADDRESS = os.getenv("RESOLVE_TRAP_ADDRESS", "false") MAX_DNS_CACHE_SIZE_TRAPS = int(os.getenv("MAX_DNS_CACHE_SIZE_TRAPS", "100")) TTL_DNS_CACHE_TRAPS = int(os.getenv("TTL_DNS_CACHE_TRAPS", "1800")) +IPv6_ENABLED = human_bool(os.getenv("IPv6_ENABLED", "false").lower()) @shared_task( @@ -152,6 +153,9 @@ def trap(self, work): remaining_oids = [] remotemibs = set() metrics = {} + + work["host"] = format_ipv4_address(work["host"]) + for w in work["data"]: if OID_VALIDATOR.match(w[1]): @@ -201,3 +205,10 @@ def trap(self, work): "detectchange": False, "sourcetype": SPLUNK_SOURCETYPE_TRAPS, } + + +def format_ipv4_address(host: str) -> str: + # IPv4 addresses from IPv6 socket have added ::ffff: prefix, which is removed + if IPv6_ENABLED and "." in host: + return host.split(":")[-1] + return host diff --git a/splunk_connect_for_snmp/traps.py b/splunk_connect_for_snmp/traps.py index 6a0000704..9e169430b 100644 --- a/splunk_connect_for_snmp/traps.py +++ b/splunk_connect_for_snmp/traps.py @@ -174,18 +174,19 @@ def main(): cbCtx=observer_context, ) - # UDP over IPv4, first listening interface/port - config.addTransport( - snmp_engine, - udp.domainName, - udp.UdpTransport().openServerMode(("0.0.0.0", 2162)), - ) - + # UDP socket over IPv6 listens also for IPv4 if IPv6_ENABLED: config.addTransport( snmp_engine, udp6.domainName, - udp6.Udp6Transport().openServerMode(("::", 2163)), + udp6.Udp6Transport().openServerMode(("::", 2162)), + ) + else: + # UDP over IPv4, first listening interface/port + config.addTransport( + snmp_engine, + udp.domainName, + udp.UdpTransport().openServerMode(("0.0.0.0", 2162)), ) with open(CONFIG_PATH, encoding="utf-8") as file: diff --git a/test/snmp/test_tasks.py b/test/snmp/test_tasks.py index 321a11a89..a516a3692 100644 --- a/test/snmp/test_tasks.py +++ b/test/snmp/test_tasks.py @@ -289,3 +289,28 @@ def test_trap_reverse_dns_lookup( }, result, ) + + +class TestHelpers(TestCase): + @patch("splunk_connect_for_snmp.snmp.tasks.IPv6_ENABLED") + def test_format_ipv4_address(self, ipv6_enabled): + from splunk_connect_for_snmp.snmp.tasks import format_ipv4_address + + ipv6_enabled.return_value = True + ip_address = "::ffff:172.31.20.76" + host = format_ipv4_address(ip_address) + self.assertEqual(host, "172.31.20.76") + + def test_format_ipv4_address_disabled(self): + from splunk_connect_for_snmp.snmp.tasks import format_ipv4_address + + ip_address = "::ffff:172.31.20.76" + host = format_ipv4_address(ip_address) + self.assertEqual(host, "::ffff:172.31.20.76") + + def test_format_ipv4_address_ipv6(self): + from splunk_connect_for_snmp.snmp.tasks import format_ipv4_address + + ip_address = "fd02::b24a:409e:a35e:b580" + host = format_ipv4_address(ip_address) + self.assertEqual(host, "fd02::b24a:409e:a35e:b580") From 7c136b5e8eeb45b60527b490684f4b93521f7bac Mon Sep 17 00:00:00 2001 From: ajasnosz Date: Thu, 19 Dec 2024 14:24:29 +0100 Subject: [PATCH 2/2] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2be0d2003..2cb68d6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - add IF-MIB.ifOperStatus to baseIF profile - allow to set subnets for docker network configuration from .env file +- update ipv4 and ipv6 traps to be sent on the same port ### Fixed - add communities for v1 traps