Aller au contenu

Integration

Le DNS interne interagit avec de nombreux services de l'infrastructure. Ce chapitre detaille les integrations cles.

Integration avec IAM (LDAP SRV records)

Le protocole LDAP utilise les enregistrements SRV pour la découverte automatique des serveurs d'annuaire. Les clients LDAP (PAM, SSSD, Keycloak) résolvent ces enregistrements pour trouver les serveurs IAM.

Enregistrements SRV pour LDAP/Kerberos

; Zone enterprise.internal.company.io
; LDAP over TLS (LDAPS)
_ldaps._tcp.enterprise.internal.company.io.  300  IN  SRV  10  60  636  iam-1.enterprise.internal.company.io.
_ldaps._tcp.enterprise.internal.company.io.  300  IN  SRV  10  40  636  iam-2.enterprise.internal.company.io.

; Kerberos (si utilise)
_kerberos._udp.enterprise.internal.company.io.  300  IN  SRV  10  0  88  iam-1.enterprise.internal.company.io.
_kerberos._tcp.enterprise.internal.company.io.  300  IN  SRV  10  0  88  iam-1.enterprise.internal.company.io.

; OIDC discovery (enregistrement A/CNAME pour le well-known endpoint)
iam.enterprise.internal.company.io.  300  IN  A  10.20.1.10

Configuration SSSD

Le client SSSD decouvre automatiquement les serveurs LDAP via DNS :

# /etc/sssd/sssd.conf
[domain/company]
id_provider = ldap
auth_provider = ldap
ldap_uri = _srv_
ldap_search_base = dc=company,dc=io
dns_discovery_domain = enterprise.internal.company.io

Vérification

# Verifier la resolution SRV
dig @10.30.2.10 _ldaps._tcp.enterprise.internal.company.io SRV +short
# Attendu : 10 60 636 iam-1.enterprise.internal.company.io.
#           10 40 636 iam-2.enterprise.internal.company.io.

# Tester la decouverte depuis un client
ldapsearch -H ldap:///dc=company,dc=io??base -s base -b "" supportedSASLMechanisms

Integration avec le service mesh

Dans une architecture avec service mesh (Istio, Linkerd), le DNS joue un rôle central dans le routage du trafic.

DNS-based service discovery

graph LR
    A["Service A<br/>(envoy)"] -->|DNS| CoreDNS
    CoreDNS -->|IP pods| A
    A -->|mTLS| B["Service B<br/>(envoy)"]

Headless services pour le mesh

Les headless services Kubernetes (sans ClusterIP) retournent directement les IP des pods, ce qui permet au service mesh de gérer le load balancing :

apiVersion: v1
kind: Service
metadata:
  name: app-api
  namespace: production
spec:
  clusterIP: None  # Headless : CoreDNS retourne les IP des pods
  selector:
    app: app-api
  ports:
    - port: 8080
      targetPort: 8080
# Resolution d'un headless service
dig @10.96.0.10 app-api.production.svc.cluster.local A +short
# Retourne les IP de tous les pods :
# 10.244.1.15
# 10.244.2.23
# 10.244.3.31

Service entries pour les services externes au mesh

# Istio ServiceEntry : rendre un service externe au cluster accessible via DNS
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: external-iam
  namespace: production
spec:
  hosts:
    - iam.enterprise.internal.company.io
  location: MESH_EXTERNAL
  ports:
    - number: 636
      name: ldaps
      protocol: TLS
  resolution: DNS
  endpoints:
    - address: 10.20.1.10
    - address: 10.20.1.11

Integration avec le VPN (split-DNS)

Les clients VPN doivent résoudre les noms internes sans perdre la résolution des noms publics. Le split-DNS configure le client pour envoyer uniquement les requêtes internes vers le DNS interne.

Configuration WireGuard

# /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <cle_privee>
Address = 10.50.0.42/24
DNS = 10.30.2.10, 10.30.2.11  # DNS internes

[Peer]
PublicKey = <cle_publique_serveur>
Endpoint = vpn.company.io:51820
AllowedIPs = 10.0.0.0/8       # Trafic interne via VPN
# 0.0.0.0/0 si full tunnel

Configuration OpenVPN

# server.conf
push "dhcp-option DNS 10.30.2.10"
push "dhcp-option DNS 10.30.2.11"
push "dhcp-option DOMAIN internal.company.io"
push "dhcp-option DOMAIN-SEARCH production.internal.company.io"
push "dhcp-option DOMAIN-SEARCH enterprise.internal.company.io"

Split-DNS avec systemd-resolved

Pour les clients Linux utilisant systemd-resolved :

# Configurer le split-DNS pour l'interface VPN
resolvectl dns wg0 10.30.2.10 10.30.2.11
resolvectl domain wg0 ~internal.company.io
# Le prefixe ~ indique que seules les requetes *.internal.company.io
# passent par le DNS interne via wg0

# Verification
resolvectl status wg0
resolvectl query app-api.production.internal.company.io

Pourquoi le split-DNS est important

Sans split-DNS, toutes les requêtes DNS passent par le VPN, ce qui ajoute de la latence pour les sites publics et surcharge le DNS interne. Le split-DNS envoie uniquement les requêtes *.internal.company.io vers le DNS interne.

Integration avec Let's Encrypt (DNS-01 challenge)

Le challenge DNS-01 permet d'obtenir des certificats wildcard Let's Encrypt en prouvant le contrôle d'une zone DNS. C'est la seule méthode pour les certificats wildcard et pour les serveurs non exposes sur Internet.

Principe

sequenceDiagram
    participant CM as cert-manager
    participant LE as Let's Encrypt (ACME)
    CM->>LE: 1. Demande certificat
    LE->>CM: 2. Challenge (TXT record needed)
    CM->>CM: 3. Cree TXT record via DNS API
    CM->>LE: 4. Validation
    LE->>CM: 5. Certificat

Configuration avec cert-manager et CoreDNS

Pour un DNS interne, le challenge DNS-01 necessite un webhook cert-manager qui met a jour les enregistrements via l'API du serveur DNS :

# ClusterIssuer avec DNS-01 via RFC2136 (mise a jour dynamique DNS)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@company.io
    privateKeySecretRef:
      name: letsencrypt-dns-key
    solvers:
      - dns01:
          rfc2136:
            nameserver: 10.30.2.10:53
            tsigKeyName: cert-manager-key
            tsigAlgorithm: HMAC-SHA256
            tsigSecretSecretRef:
              name: tsig-secret
              key: tsig-secret-key

Activation des mises a jour dynamiques dans CoreDNS

# Corefile — activer le plugin "transfer" pour les mises a jour dynamiques
company.io {
    file /etc/coredns/zones/db.company.io {
        transfer to *
    }
    # Note : CoreDNS n'a pas de support RFC2136 natif.
    # Alternative : utiliser PowerDNS API ou un webhook cert-manager custom.
    log
    errors
}

CoreDNS et RFC2136

CoreDNS ne supporte pas nativement les mises a jour dynamiques RFC2136. Pour le challenge DNS-01, deux alternatives :

  • Utiliser PowerDNS avec son API REST comme serveur autoritatif de la zone publique
  • Utiliser un webhook cert-manager spécifique au provider DNS public (Cloudflare, Route53, etc.) pour la zone publique, tout en gardant CoreDNS pour les zones internes

Certificat wildcard interne

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-internal
  namespace: production
spec:
  secretName: wildcard-internal-tls
  issuerRef:
    name: letsencrypt-dns
    kind: ClusterIssuer
  dnsNames:
    - "*.production.internal.company.io"
    - "*.enterprise.internal.company.io"
  duration: 2160h    # 90 jours
  renewBefore: 720h  # Renouveler 30 jours avant expiration

Integration avec Ansible et OpenTofu

Enregistrement DNS dynamique avec Ansible

# playbook: register-dns.yml
# Enregistre un nouveau serveur dans la zone DNS interne
---
- name: Enregistrer le serveur dans le DNS interne
  hosts: localhost
  vars:
    dns_server: 10.30.2.10
    zone: production.internal.company.io
    hostname: "{{ new_server_name }}"
    ip_address: "{{ new_server_ip }}"
  tasks:
    - name: Ajouter l'enregistrement A dans le fichier de zone
      ansible.builtin.lineinfile:
        path: /opt/coredns/zones/db.production.internal
        line: "{{ hostname }}    IN  A   {{ ip_address }}"
        insertafter: "; Services de production"
      delegate_to: dns-server

    - name: Incrementer le serial de la zone
      ansible.builtin.shell: |
        SERIAL=$(date +%Y%m%d%H)
        sed -i "s/[0-9]\{10\}\(\s*;\s*Serial\)/${SERIAL}\1/" \
          /opt/coredns/zones/db.production.internal
      delegate_to: dns-server

    - name: Attendre le rechargement CoreDNS
      ansible.builtin.pause:
        seconds: 35  # CoreDNS reload interval = 30s

    - name: Verifier la resolution
      ansible.builtin.command: >
        dig @{{ dns_server }} {{ hostname }}.{{ zone }} A +short
      register: dig_result
      failed_when: ip_address not in dig_result.stdout

Enregistrement DNS avec OpenTofu

# Utilisation du provider DNS pour les mises a jour dynamiques
terraform {
  required_providers {
    dns = {
      source  = "hashicorp/dns"
      version = "~> 3.4"
    }
  }
}

provider "dns" {
  update {
    server        = "10.30.2.10"
    key_name      = "opentofu-key."
    key_algorithm = "hmac-sha256"
    key_secret    = var.tsig_key_secret
  }
}

# Enregistrement A pour un nouveau service
resource "dns_a_record_set" "app_api" {
  zone      = "production.internal.company.io."
  name      = "app-api"
  addresses = ["10.30.1.10", "10.30.1.11"]
  ttl       = 300
}

# Enregistrement SRV pour le service discovery
resource "dns_srv_record_set" "app_api_http" {
  zone = "production.internal.company.io."
  name = "_http._tcp.app-api"
  srv {
    priority = 10
    weight   = 50
    target   = "app-api-1.production.internal.company.io."
    port     = 8080
  }
  srv {
    priority = 10
    weight   = 50
    target   = "app-api-2.production.internal.company.io."
    port     = 8080
  }
  ttl = 300
}

Approche GitOps pour les zones DNS

Une alternative aux mises a jour dynamiques est de gérer les fichiers de zone dans Git et de les déployer via CI/CD. Cela offre un historique complet des changements, une revue par les pairs et un rollback facile. CoreDNS avec le plugin file et reload détecte automatiquement les modifications.