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.