Skip to content

Commit 8209ba8

Browse files
authored
fix: add docker dns for ipv6 (#1115)
1 parent 5537f02 commit 8209ba8

File tree

9 files changed

+29
-7
lines changed

9 files changed

+29
-7
lines changed

docker_compose/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ TRAPS_CONFIG_FILE_ABSOLUTE_PATH=
66
INVENTORY_FILE_ABSOLUTE_PATH=
77
COREFILE_ABS_PATH=
88
COREDNS_ADDRESS=172.28.0.255
9+
COREDNS_ADDRESS_IPv6=fd02:0:0:0:7fff:ffff:ffff:ffff
910
SC4SNMP_VERSION="1.12.1-beta.2"
1011
IPv6_ENABLED=false
1112

docker_compose/Corefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
errors
44
auto
55
reload
6-
forward . 8.8.8.8
6+
forward . 8.8.8.8 2001:4860:4860::8888
77
}

docker_compose/docker-compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ x-dns_and_networks: &dns_and_networks
4747
- sc4snmp_network
4848
dns:
4949
- ${COREDNS_ADDRESS}
50+
- ${COREDNS_ADDRESS_IPv6}
5051

5152
x-dependency_and_restart_policy: &dependency_and_restart_policy
5253
depends_on:
@@ -86,6 +87,7 @@ services:
8687
networks:
8788
sc4snmp_network:
8889
ipv4_address: ${COREDNS_ADDRESS}
90+
ipv6_address: ${COREDNS_ADDRESS_IPv6}
8991
snmp-mibserver:
9092
<<: [*dns_and_networks, *dependend_on_core_dns]
9193
image: ${MIBSERVER_IMAGE}:${MIBSERVER_TAG:-latest}

docs/dockercompose/6-env-file-configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Inside the directory with the docker compose files, there is a `.env`. Variables
1313
| `INVENTORY_FILE_ABSOLUTE_PATH` | Absolute path to [inventory.csv](./3-inventory-configuration.md) file |
1414
| `COREFILE_ABS_PATH` | Absolute path to Corefile used by coreDNS. Default Corefile can be found inside the `docker_compose` |
1515
| `COREDNS_ADDRESS` | IP address of the coredns inside docker network. Should not be changed |
16+
| `COREDNS_ADDRESS_IPv6` | IPv6 address of the coredns inside docker network. Should not be changed |
1617
| `SC4SNMP_VERSION` | Version of SC4SNMP |
1718
| `IPv6_ENABLED` | Enable receiving traps and polling from IPv6 devices |
1819

docs/microk8s/configuration/poller-configuration.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ poller:
3131
!!! info
3232
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.
3333

34+
### IPv6 hostname resolution
35+
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.
36+
3437
### Define log level
3538
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`.
3639
The default value is `INFO`.

integration_tests/.env

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ TRAPS_CONFIG_FILE_ABSOLUTE_PATH=
66
INVENTORY_FILE_ABSOLUTE_PATH=
77
COREFILE_ABS_PATH=
88
COREDNS_ADDRESS=172.28.0.255
9-
SC4SNMP_VERSION="1.11.0-beta.9"
10-
9+
COREDNS_ADDRESS_IPv6=fd02:0:0:0:7fff:ffff:ffff:ffff
10+
SC4SNMP_VERSION=latest
11+
IPv6_ENABLED=false
1112

1213
# Dependencies images
1314
COREDNS_IMAGE=coredns/coredns
@@ -81,6 +82,7 @@ CHAIN_OF_TASKS_EXPIRY_TIME=500
8182
# Traps configuration
8283
SNMP_V3_SECURITY_ENGINE_ID=80003a8c04
8384
TRAPS_PORT=162
85+
IPv6_TRAPS_PORT=2163
8486
TRAP_LOG_LEVEL=INFO
8587

8688
# Scheduler configuration

integration_tests/automatic_setup_compose.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ deploy_poetry() {
4848
}
4949

5050
wait_for_containers_to_be_up() {
51+
echo $(sudo docker ps)
5152
while true; do
5253
CONTAINERS_SC4SNMP=$(sudo docker ps | grep "sc4snmp\|worker-poller\|worker-sender\|worker-trap" | grep -v "Name" | wc -l)
5354
if [ "$CONTAINERS_SC4SNMP" -gt 0 ]; then

splunk_connect_for_snmp/common/inventory_record.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333

3434

3535
class InventoryRecord(BaseModel):
36-
address: InventoryStr
3736
port: InventoryInt = 161
37+
address: InventoryStr
3838
version: InventoryStr
3939
community: InventoryStr
4040
secret: InventoryStr
@@ -53,7 +53,7 @@ def __init__(self, *args, **kwargs):
5353
super().__init__(*args, **kwargs)
5454

5555
@validator("address", pre=True)
56-
def address_validator(cls, value):
56+
def address_validator(cls, value, values):
5757
if value is None:
5858
raise ValueError("field address cannot be null")
5959
if value.startswith("#"):
@@ -63,7 +63,7 @@ def address_validator(cls, value):
6363
ip_address(value)
6464
except ValueError:
6565
try:
66-
socket.gethostbyname_ex(value)
66+
socket.getaddrinfo(value, values["port"])
6767
except socket.gaierror:
6868
raise ValueError(
6969
f"field address must be an IP or a resolvable hostname {value}"

splunk_connect_for_snmp/snmp/auth.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
# limitations under the License.
1515
#
1616
import os
17+
import socket
18+
from ipaddress import ip_address
1719
from typing import Any, Dict, Union
1820

1921
from pysnmp.hlapi import (
@@ -28,11 +30,13 @@
2830
from pysnmp.proto.api.v2c import OctetString
2931
from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType
3032

33+
from splunk_connect_for_snmp.common.hummanbool import human_bool
3134
from splunk_connect_for_snmp.common.inventory_record import InventoryRecord
3235
from splunk_connect_for_snmp.snmp.const import AuthProtocolMap, PrivProtocolMap
3336
from splunk_connect_for_snmp.snmp.exceptions import SnmpActionError
3437

3538
UDP_CONNECTION_TIMEOUT = int(os.getenv("UDP_CONNECTION_TIMEOUT", 1))
39+
IPv6_ENABLED = human_bool(os.getenv("IPv6_ENABLED", False))
3640

3741

3842
def get_secret_value(
@@ -87,7 +91,8 @@ def get_security_engine_id(logger, ir: InventoryRecord, snmp_engine: SnmpEngine)
8791

8892

8993
def setup_transport_target(ir):
90-
if ":" in ir.address:
94+
ip = get_ip_from_socket(ir) if IPv6_ENABLED else ir.address
95+
if ip_address(ip).version == 6:
9196
transport = Udp6TransportTarget(
9297
(ir.address, ir.port), timeout=UDP_CONNECTION_TIMEOUT
9398
)
@@ -98,6 +103,13 @@ def setup_transport_target(ir):
98103
return transport
99104

100105

106+
def get_ip_from_socket(ir):
107+
# Example of response from getaddrinfo
108+
# [(< AddressFamily.AF_INET6: 10 >, < SocketKind.SOCK_STREAM: 1 >, 6, '', ('2607:f8b0:4004:c09::64', 161, 0, 0)),
109+
# (< AddressFamily.AF_INET: 2 >, < SocketKind.SOCK_STREAM: 1 >, 6, '', ('142.251.16.139', 161))]
110+
return socket.getaddrinfo(ir.address, ir.port)[0][4][0]
111+
112+
101113
def fetch_security_engine_id(observer_context, error_indication, ipaddress):
102114
if "securityEngineId" in observer_context:
103115
return observer_context["securityEngineId"]

0 commit comments

Comments
 (0)