Skip to content

Commit

Permalink
fix: add docker dns for ipv6 (#1115)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajasnosz authored Nov 5, 2024
1 parent 5537f02 commit 8209ba8
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 7 deletions.
1 change: 1 addition & 0 deletions docker_compose/.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ TRAPS_CONFIG_FILE_ABSOLUTE_PATH=
INVENTORY_FILE_ABSOLUTE_PATH=
COREFILE_ABS_PATH=
COREDNS_ADDRESS=172.28.0.255
COREDNS_ADDRESS_IPv6=fd02:0:0:0:7fff:ffff:ffff:ffff
SC4SNMP_VERSION="1.12.1-beta.2"
IPv6_ENABLED=false

Expand Down
2 changes: 1 addition & 1 deletion docker_compose/Corefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
errors
auto
reload
forward . 8.8.8.8
forward . 8.8.8.8 2001:4860:4860::8888
}
2 changes: 2 additions & 0 deletions docker_compose/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ x-dns_and_networks: &dns_and_networks
- sc4snmp_network
dns:
- ${COREDNS_ADDRESS}
- ${COREDNS_ADDRESS_IPv6}

x-dependency_and_restart_policy: &dependency_and_restart_policy
depends_on:
Expand Down Expand Up @@ -86,6 +87,7 @@ services:
networks:
sc4snmp_network:
ipv4_address: ${COREDNS_ADDRESS}
ipv6_address: ${COREDNS_ADDRESS_IPv6}
snmp-mibserver:
<<: [*dns_and_networks, *dependend_on_core_dns]
image: ${MIBSERVER_IMAGE}:${MIBSERVER_TAG:-latest}
Expand Down
1 change: 1 addition & 0 deletions docs/dockercompose/6-env-file-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Inside the directory with the docker compose files, there is a `.env`. Variables
| `INVENTORY_FILE_ABSOLUTE_PATH` | Absolute path to [inventory.csv](./3-inventory-configuration.md) file |
| `COREFILE_ABS_PATH` | Absolute path to Corefile used by coreDNS. Default Corefile can be found inside the `docker_compose` |
| `COREDNS_ADDRESS` | IP address of the coredns inside docker network. Should not be changed |
| `COREDNS_ADDRESS_IPv6` | IPv6 address of the coredns inside docker network. Should not be changed |
| `SC4SNMP_VERSION` | Version of SC4SNMP |
| `IPv6_ENABLED` | Enable receiving traps and polling from IPv6 devices |

Expand Down
3 changes: 3 additions & 0 deletions docs/microk8s/configuration/poller-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ poller:
!!! info
The header's line (`address,port,version,community,secret,security_engine,walk_interval,profiles,smart_profiles,delete`) is necessary for the correct execution of SC4SNMP. Do not remove it.

### IPv6 hostname resolution
When IPv6 is enabled and device is dual stack, the hostname resolution will try to resolve the name to the IPv6 address first, then to the IPv4 address.

### Define log level
The log level for poller can be set by changing the value for the key `logLevel`. The allowed values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` or `FATAL`.
The default value is `INFO`.
Expand Down
6 changes: 4 additions & 2 deletions integration_tests/.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ TRAPS_CONFIG_FILE_ABSOLUTE_PATH=
INVENTORY_FILE_ABSOLUTE_PATH=
COREFILE_ABS_PATH=
COREDNS_ADDRESS=172.28.0.255
SC4SNMP_VERSION="1.11.0-beta.9"

COREDNS_ADDRESS_IPv6=fd02:0:0:0:7fff:ffff:ffff:ffff
SC4SNMP_VERSION=latest
IPv6_ENABLED=false

# Dependencies images
COREDNS_IMAGE=coredns/coredns
Expand Down Expand Up @@ -81,6 +82,7 @@ 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
Expand Down
1 change: 1 addition & 0 deletions integration_tests/automatic_setup_compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ deploy_poetry() {
}

wait_for_containers_to_be_up() {
echo $(sudo docker ps)
while true; do
CONTAINERS_SC4SNMP=$(sudo docker ps | grep "sc4snmp\|worker-poller\|worker-sender\|worker-trap" | grep -v "Name" | wc -l)
if [ "$CONTAINERS_SC4SNMP" -gt 0 ]; then
Expand Down
6 changes: 3 additions & 3 deletions splunk_connect_for_snmp/common/inventory_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@


class InventoryRecord(BaseModel):
address: InventoryStr
port: InventoryInt = 161
address: InventoryStr
version: InventoryStr
community: InventoryStr
secret: InventoryStr
Expand All @@ -53,7 +53,7 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

@validator("address", pre=True)
def address_validator(cls, value):
def address_validator(cls, value, values):
if value is None:
raise ValueError("field address cannot be null")
if value.startswith("#"):
Expand All @@ -63,7 +63,7 @@ def address_validator(cls, value):
ip_address(value)
except ValueError:
try:
socket.gethostbyname_ex(value)
socket.getaddrinfo(value, values["port"])
except socket.gaierror:
raise ValueError(
f"field address must be an IP or a resolvable hostname {value}"
Expand Down
14 changes: 13 additions & 1 deletion splunk_connect_for_snmp/snmp/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# limitations under the License.
#
import os
import socket
from ipaddress import ip_address
from typing import Any, Dict, Union

from pysnmp.hlapi import (
Expand All @@ -28,11 +30,13 @@
from pysnmp.proto.api.v2c import OctetString
from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType

from splunk_connect_for_snmp.common.hummanbool import human_bool
from splunk_connect_for_snmp.common.inventory_record import InventoryRecord
from splunk_connect_for_snmp.snmp.const import AuthProtocolMap, PrivProtocolMap
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))


def get_secret_value(
Expand Down Expand Up @@ -87,7 +91,8 @@ def get_security_engine_id(logger, ir: InventoryRecord, snmp_engine: SnmpEngine)


def setup_transport_target(ir):
if ":" in ir.address:
ip = get_ip_from_socket(ir) if IPv6_ENABLED else ir.address
if ip_address(ip).version == 6:
transport = Udp6TransportTarget(
(ir.address, ir.port), timeout=UDP_CONNECTION_TIMEOUT
)
Expand All @@ -98,6 +103,13 @@ def setup_transport_target(ir):
return transport


def get_ip_from_socket(ir):
# Example of response from getaddrinfo
# [(< AddressFamily.AF_INET6: 10 >, < SocketKind.SOCK_STREAM: 1 >, 6, '', ('2607:f8b0:4004:c09::64', 161, 0, 0)),
# (< AddressFamily.AF_INET: 2 >, < SocketKind.SOCK_STREAM: 1 >, 6, '', ('142.251.16.139', 161))]
return socket.getaddrinfo(ir.address, ir.port)[0][4][0]


def fetch_security_engine_id(observer_context, error_indication, ipaddress):
if "securityEngineId" in observer_context:
return observer_context["securityEngineId"]
Expand Down

0 comments on commit 8209ba8

Please sign in to comment.