L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Développement · SKILL.md

rhel-network-infra

rhel-network-infra

Use when configuring network infrastructure services on RHEL 9 (and AlmaLinux/Rocky 9) — BIND DNS server, dnsmasq, Kea/ISC DHCP server, chrony NTP, VLAN routing with nmcli, IP forwarding, NAT with nftables/firewalld, and network troubleshooting tools. Part of the rhel-* skill family.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: rhel-network-infra description: Use when configuring network infrastructure services on RHEL 9 (and AlmaLinux/Rocky 9) — BIND DNS server, dnsmasq, Kea/ISC DHCP server, chrony NTP, VLAN routing with nmcli, IP forwarding, NAT with nftables/firewalld, and network troubleshooting tools. Part of the rhel-* skill family. family: rhel applies_when: os_family == rhel

Red Hat Enterprise Linux 9 — Network Infrastructure Services

Companion skill for DNS, DHCP, NTP, routing, and network diagnostics on RHEL 9.x (and compatible: AlmaLinux 9, Rocky Linux 9). For base system administration, see parent skill rhel-server-admin.


1. BIND DNS Server

Installation

sudo dnf install bind bind-utils
sudo systemctl enable --now named
sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --reload

Main Configuration — /etc/named.conf

options {
    listen-on port 53 { 127.0.0.1; 10.0.1.0/24; };
    listen-on-v6 port 53 { ::1; };
    directory       "/var/named";
    dump-file       "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    allow-query     { localhost; 10.0.0.0/8; 192.168.0.0/16; };
    allow-transfer  { none; };
    recursion yes;
    allow-recursion { localhost; 10.0.0.0/8; };

    forwarders {
        1.1.1.1;
        8.8.8.8;
    };
    forward only;

    dnssec-validation auto;

    managed-keys-directory "/var/named/dynamic";
    pid-file "/run/named/named.pid";
    session-keyfile "/run/named/session.key";
};

logging {
    channel default_log {
        file "/var/named/data/named.log" versions 3 size 5m;
        severity info;
        print-time yes;
        print-severity yes;
        print-category yes;
    };
    category default { default_log; };
    category queries { default_log; };
};

# ACLs
acl "trusted" {
    10.0.1.0/24;
    10.0.2.0/24;
    localhost;
};

zone "home.lab" IN {
    type master;
    file "home.lab.zone";
    allow-update { none; };
};

zone "1.0.10.in-addr.arpa" IN {
    type master;
    file "10.0.1.rev";
    allow-update { none; };
};

Forward Zone File — /var/named/home.lab.zone

$TTL 86400
@   IN  SOA ns1.home.lab. admin.home.lab. (
            2026032301  ; Serial (YYYYMMDDNN)
            3600        ; Refresh
            1800        ; Retry
            604800      ; Expire
            86400 )     ; Minimum TTL

    IN  NS  ns1.home.lab.

ns1         IN  A   10.0.1.10
gateway     IN  A   10.0.1.1
server01    IN  A   10.0.1.50
server02    IN  A   10.0.1.51
nas         IN  A   10.0.1.100
www         IN  CNAME server01.home.lab.

Reverse Zone File — /var/named/10.0.1.rev

$TTL 86400
@   IN  SOA ns1.home.lab. admin.home.lab. (
            2026032301  ; Serial
            3600
            1800
            604800
            86400 )

    IN  NS  ns1.home.lab.

10  IN  PTR ns1.home.lab.
1   IN  PTR gateway.home.lab.
50  IN  PTR server01.home.lab.
51  IN  PTR server02.home.lab.
100 IN  PTR nas.home.lab.

SELinux for BIND

# Check named SELinux booleans
getsebool -a | grep named

# Allow named to write master zones (for dynamic updates)
sudo setsebool -P named_write_master_zones 1

# Restore context on zone files
sudo restorecon -Rv /var/named/

# If using a custom log directory
sudo semanage fcontext -a -t named_log_t "/var/named/data(/.*)?"
sudo restorecon -Rv /var/named/data/

Validate and Test

# Check config syntax
sudo named-checkconf
sudo named-checkzone home.lab /var/named/home.lab.zone
sudo named-checkzone 1.0.10.in-addr.arpa /var/named/10.0.1.rev

# Restart after changes
sudo systemctl restart named

# Test resolution
dig @127.0.0.1 server01.home.lab
dig @127.0.0.1 -x 10.0.1.50
dig @127.0.0.1 home.lab AXFR     # zone transfer (should be refused)

Split-Horizon DNS

Add views in /etc/named.conf to serve different answers for internal vs external clients:

view "internal" {
    match-clients { 10.0.0.0/8; 192.168.0.0/16; localhost; };
    recursion yes;

    zone "example.com" IN {
        type master;
        file "example.com.internal.zone";
    };
};

view "external" {
    match-clients { any; };
    recursion no;

    zone "example.com" IN {
        type master;
        file "example.com.external.zone";
    };
};

DNSSEC Basics

# Generate zone-signing key (ZSK) and key-signing key (KSK)
cd /var/named
sudo dnssec-keygen -a ECDSAP256SHA256 home.lab
sudo dnssec-keygen -a ECDSAP256SHA256 -f KSK home.lab

# Sign the zone
sudo dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) \
  -N INCREMENT -o home.lab -t home.lab.zone

# Update named.conf to use the signed zone file
# file "home.lab.zone.signed";

sudo restorecon -Rv /var/named/
sudo systemctl restart named

2. dnsmasq — Lightweight DNS/DHCP

Installation and Basic Config

sudo dnf install dnsmasq
sudo systemctl enable --now dnsmasq
sudo firewall-cmd --permanent --add-service=dns --add-service=dhcp
sudo firewall-cmd --reload

Configuration — /etc/dnsmasq.conf

# Interface binding
interface=ens18
bind-interfaces

# DNS settings
domain=home.lab
local=/home.lab/
expand-hosts

# Upstream DNS
server=1.1.1.1
server=8.8.8.8

# DNS cache
cache-size=1000

# DHCP range
dhcp-range=10.0.1.100,10.0.1.200,255.255.255.0,12h

# Default gateway and DNS for DHCP clients
dhcp-option=option:router,10.0.1.1
dhcp-option=option:dns-server,10.0.1.10

# Static leases
dhcp-host=aa:bb:cc:dd:ee:01,nas,10.0.1.100
dhcp-host=aa:bb:cc:dd:ee:02,printer,10.0.1.101

# Additional hosts (acts like /etc/hosts entries)
addn-hosts=/etc/dnsmasq.hosts

# Logging
log-queries
log-dhcp
log-facility=/var/log/dnsmasq.log

Coexistence with systemd-resolved

On some RHEL 9 minimal installs, systemd-resolved may be present:

# Check if resolved is running
systemctl is-active systemd-resolved

# If dnsmasq should be the sole DNS, disable resolved
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo rm -f /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf

# Or configure NetworkManager to skip resolved
# /etc/NetworkManager/conf.d/no-resolved.conf
# [main]
# dns=none
# Validate and restart
sudo dnsmasq --test
sudo systemctl restart dnsmasq
journalctl -u dnsmasq -f

3. Kea DHCP Server (Modern Replacement)

Installation from EPEL

sudo dnf install epel-release
sudo dnf install kea

# Kea installs multiple services
# kea-dhcp4 — DHCPv4 server
# kea-dhcp6 — DHCPv6 server
# kea-dhcp-ddns — Dynamic DNS updates
# kea-ctrl-agent — REST API

sudo systemctl enable --now kea-dhcp4
sudo firewall-cmd --permanent --add-service=dhcp
sudo firewall-cmd --reload

DHCPv4 Config — /etc/kea/kea-dhcp4.conf

{
    "Dhcp4": {
        "interfaces-config": {
            "interfaces": [ "ens18" ]
        },
        "lease-database": {
            "type": "memfile",
            "persist": true,
            "name": "/var/lib/kea/dhcp4.leases"
        },
        "valid-lifetime": 43200,
        "renew-timer": 21600,
        "rebind-timer": 37800,

        "subnet4": [
            {
                "subnet": "10.0.1.0/24",
                "pools": [ { "pool": "10.0.1.100 - 10.0.1.200" } ],
                "option-data": [
                    { "name": "routers", "data": "10.0.1.1" },
                    { "name": "domain-name-servers", "data": "10.0.1.10" },
                    { "name": "domain-name", "data": "home.lab" },
                    { "name": "domain-search", "data": "home.lab" }
                ],
                "reservations": [
                    {
                        "hw-address": "aa:bb:cc:dd:ee:01",
                        "ip-address": "10.0.1.100",
                        "hostname": "nas"
                    },
                    {
                        "hw-address": "aa:bb:cc:dd:ee:02",
                        "ip-address": "10.0.1.101",
                        "hostname": "printer"
                    }
                ]
            }
        ],

        "loggers": [
            {
                "name": "kea-dhcp4",
                "output-options": [
                    { "output": "/var/log/kea/kea-dhcp4.log" }
                ],
                "severity": "INFO"
            }
        ]
    }
}

Validate and Monitor

# Syntax check
kea-dhcp4 -t /etc/kea/kea-dhcp4.conf

sudo systemctl restart kea-dhcp4
journalctl -u kea-dhcp4 -f

# View leases
cat /var/lib/kea/dhcp4.leases

Kea HA (Hot Standby)

Add to kea-dhcp4.conf on both nodes:

"hooks-libraries": [
    {
        "library": "/usr/lib64/kea/hooks/libdhcp_lease_cmds.so"
    },
    {
        "library": "/usr/lib64/kea/hooks/libdhcp_ha.so",
        "parameters": {
            "high-availability": [{
                "this-server-name": "server1",
                "mode": "hot-standby",
                "peers": [
                    { "name": "server1", "url": "http://10.0.1.50:8000/", "role": "primary" },
                    { "name": "server2", "url": "http://10.0.1.51:8000/", "role": "standby" }
                ]
            }]
        }
    }
]

4. ISC DHCP Server (Legacy)

Installation

sudo dnf install dhcp-server
sudo systemctl enable --now dhcpd
sudo firewall-cmd --permanent --add-service=dhcp
sudo firewall-cmd --reload

Configuration — /etc/dhcp/dhcpd.conf

authoritative;
default-lease-time 43200;
max-lease-time 86400;

option domain-name "home.lab";
option domain-name-servers 10.0.1.10;

subnet 10.0.1.0 netmask 255.255.255.0 {
    range 10.0.1.100 10.0.1.200;
    option routers 10.0.1.1;
    option broadcast-address 10.0.1.255;

    host nas {
        hardware ethernet aa:bb:cc:dd:ee:01;
        fixed-address 10.0.1.100;
    }
}

SELinux for DHCP

# dhcpd runs as dhcpd_t
getsebool -a | grep dhcp
# Lease file context
ls -Z /var/lib/dhcpd/dhcpd.leases

sudo systemctl restart dhcpd
journalctl -u dhcpd -f

# View leases
cat /var/lib/dhcpd/dhcpd.leases

Migration Path: ISC DHCP to Kea

  1. Export current leases and reservations from /etc/dhcp/dhcpd.conf
  2. Translate subnet/pool/host declarations to Kea JSON format (see Section 3)
  3. Install Kea, test with -t flag, run both in parallel briefly
  4. Stop and disable dhcpd, enable kea-dhcp4
  5. Verify clients receive leases from Kea

5. NTP with chrony

Configuration — /etc/chrony.conf

# Public NTP pools
pool 2.rhel.pool.ntp.org iburst

# Or specific servers
server time1.google.com iburst
server time2.google.com iburst

# Allow LAN clients to sync from this server
allow 10.0.1.0/24
allow 192.168.0.0/16

# Serve time even when not synchronized (stratum 10 fallback)
local stratum 10

# Record rate of drift
driftfile /var/lib/chrony/drift

# Enable kernel RTC sync
rtcsync

# Log
logdir /var/log/chrony
log measurements statistics tracking

# Security: step clock only on first 3 updates
makestep 1.0 3

Service Management

sudo systemctl enable --now chronyd
sudo firewall-cmd --permanent --add-service=ntp
sudo firewall-cmd --reload

Monitoring with chronyc

# Check sync status
chronyc tracking

# List sources with detail
chronyc sources -v
chronyc sourcestats

# Check NTP clients connected to this server
chronyc clients

# Force immediate sync
sudo chronyc makestep

# Check if chrony is serving time
chronyc activity

# Verify time accuracy
timedatectl status
timedatectl timesources     # RHEL 9.2+

6. Routing, NAT, and VLANs

Enable IP Forwarding

# Temporary
sudo sysctl -w net.ipv4.ip_forward=1

# Permanent — create /etc/sysctl.d/99-ip-forward.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
sudo sysctl --system
sysctl net.ipv4.ip_forward     # verify

Static Routes via nmcli

# Add a static route
sudo nmcli connection modify "ens18" +ipv4.routes "10.0.2.0/24 10.0.1.254"
sudo nmcli connection modify "ens18" +ipv4.routes "10.0.3.0/24 10.0.1.254 100"  # metric 100
sudo nmcli connection up "ens18"

# View routes
ip route show
ip route get 10.0.2.50

# Remove a static route
sudo nmcli connection modify "ens18" -ipv4.routes "10.0.2.0/24 10.0.1.254"
sudo nmcli connection up "ens18"

NAT / Masquerade with firewalld

# Enable masquerade on external zone
sudo firewall-cmd --permanent --zone=public --add-masquerade

# Port forwarding (DNAT)
sudo firewall-cmd --permanent --zone=public \
  --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=10.0.1.50

# Forward all traffic for an internal subnet
sudo firewall-cmd --permanent --zone=internal --add-source=10.0.1.0/24
sudo firewall-cmd --permanent --zone=public --add-masquerade

sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --query-masquerade

Direct nftables NAT (Advanced)

# /etc/nftables/nat.nft
table ip nat {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        tcp dport 8080 dnat to 10.0.1.50:80
    }
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        oifname "ens18" masquerade
    }
}
sudo nft -f /etc/nftables/nat.nft
sudo nft list ruleset

VLAN Routing

# Create VLAN interfaces on the router host
sudo nmcli connection add type vlan con-name vlan10 ifname ens18.10 dev ens18 id 10 \
  ipv4.addresses 10.0.10.1/24 ipv4.method manual

sudo nmcli connection add type vlan con-name vlan20 ifname ens18.20 dev ens18 id 20 \
  ipv4.addresses 10.0.20.1/24 ipv4.method manual

sudo nmcli connection up vlan10
sudo nmcli connection up vlan20

# With IP forwarding enabled, the host now routes between VLANs
# Add firewall rules to control inter-VLAN traffic
sudo firewall-cmd --permanent --zone=internal --add-interface=ens18.10
sudo firewall-cmd --permanent --zone=internal --add-interface=ens18.20
sudo firewall-cmd --reload

Policy Routing (Source-Based Routing)

Use when different source subnets should use different gateways:

# Create a custom routing table
echo "100 isp2" | sudo tee -a /etc/iproute2/rt_tables

# Add rules and routes via nmcli
sudo nmcli connection modify "ens19" ipv4.routing-rules "priority 100 from 10.0.2.0/24 table 100"
sudo nmcli connection modify "ens19" ipv4.routes "0.0.0.0/0 10.0.2.1 table=100"
sudo nmcli connection up "ens19"

# Verify
ip rule show
ip route show table 100

7. Network Troubleshooting

DNS Diagnostics — dig and nslookup

# Forward lookup
dig server01.home.lab @10.0.1.10
dig +short server01.home.lab

# Reverse lookup
dig -x 10.0.1.50

# Trace delegation path
dig +trace example.com

# Query specific record types
dig home.lab MX
dig home.lab NS
dig home.lab SOA
dig home.lab AXFR @10.0.1.10    # zone transfer

# Check DNSSEC
dig +dnssec example.com

Socket Statistics — ss

ss -tlnp                         # TCP listeners with process names
ss -ulnp                         # UDP listeners
ss -s                            # summary statistics
ss -tnp state established        # active connections
ss -tnp dst 10.0.1.50            # connections to a specific host
ss -tnp sport = :443             # connections from port 443

Packet Capture — tcpdump

# Capture DNS traffic
sudo tcpdump -i ens18 port 53 -nn

# Capture DHCP traffic
sudo tcpdump -i ens18 port 67 or port 68 -nn -v

# Save to file for Wireshark analysis
sudo tcpdump -i ens18 -w /tmp/capture.pcap -c 1000

# Filter by host
sudo tcpdump -i ens18 host 10.0.1.50 -nn

# Capture with human-readable output
sudo tcpdump -i ens18 -A port 80 -c 50

Routing Diagnostics

# View routing table
ip route show
ip -6 route show

# Test path to destination
ip route get 10.0.2.50

# Traceroute
traceroute 10.0.2.50
traceroute -n -T -p 443 example.com    # TCP traceroute

# mtr (combined ping + traceroute)
sudo dnf install mtr
mtr -rw -c 10 example.com              # report mode, wide output
mtr -rw -c 10 --tcp -P 443 example.com # TCP mode

Port Scanning and Service Discovery — nmap

sudo dnf install nmap

# Scan common ports on a host
nmap -sT 10.0.1.50

# Scan specific ports
nmap -p 22,53,80,443 10.0.1.50

# Scan a subnet
nmap -sn 10.0.1.0/24              # ping sweep (host discovery)

# Service version detection
nmap -sV -p 22,53,80 10.0.1.50

# UDP scan (requires root)
sudo nmap -sU -p 53,67,123 10.0.1.50

Connectivity Basics

# Ping with count and interval
ping -c 4 10.0.1.1
ping -c 4 -i 0.2 10.0.1.1        # fast ping

# ARP / neighbor table
ip neigh show

# Check interface details
ip addr show ens18
ip link show ens18
ethtool ens18                     # link speed, duplex

# DNS resolution check
resolvectl status
resolvectl query server01.home.lab

Quick Reference: Ports and Firewall Services

ServicePort(s)firewall-cmd service
DNS53/tcp, 53/udpdns
DHCP67/udp, 68/udpdhcp
NTP123/udpntp
Kea Control Agent8000/tcp(add port manually)
# Open all infra services at once
sudo firewall-cmd --permanent --add-service={dns,dhcp,ntp}
sudo firewall-cmd --reload

SELinux Quick Reference for Network Services

ServiceSELinux TypeKey Booleans
BIND (named)named_tnamed_write_master_zones
ISC DHCP (dhcpd)dhcpd_t—
Kea DHCPunconfined_service_t (EPEL)—
chronychronyd_t—
dnsmasqdnsmasq_tdnsmasq_disable_trans
# Troubleshoot any SELinux denial
sudo ausearch -m AVC --start recent -ts recent
sudo sealert -a /var/log/audit/audit.log


Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Editing /etc/resolv.conf manually on systems using NetworkManagerNetworkManager overwrites manual changes on next connection event; DNS configuration reverts silentlyConfigure DNS through nmcli (nmcli con mod ... ipv4.dns) or connection profile files; let NM manage resolv.conf
Running BIND DNS without DNSSEC validationVulnerable to DNS poisoning and man-in-the-middle attacks; users can be redirected to malicious sitesEnable DNSSEC validation in named.conf (dnssec-validation auto); test with dig +dnssec
No NTP sync monitoringClock drift causes Kerberos authentication failures, log timestamp mismatches, and certificate validation errorsMonitor chrony sync with chronyc tracking; alert when offset exceeds 100ms; verify NTP source availability
Configuring IP forwarding without firewall rulesServer becomes an open router; any network traffic can traverse through it; bypasses network security controlsEnable ip_forward only when needed; restrict with nftables/firewalld zone policies; log forwarded traffic
Using static routes instead of proper VLAN routingStatic routes break when network topology changes; maintenance nightmare with 10+ subnetsUse VLAN interfaces (nmcli con add type vlan) with proper gateway configuration; document VLAN assignments

Related Skills

WorkloadSkill
Core RHEL admin (parent skill)rhel-server-admin
Web servers (Nginx, Apache, Caddy)rhel-web-servers
Databases (PostgreSQL, MySQL, Redis)rhel-databases
Docker / Podman containersrhel-docker-host
File sharing (NFS, Samba)rhel-file-storage
Prometheus, Grafana, loggingrhel-monitoring
NVIDIA GPU, Ollama, CUDArhel-ollama-nvidia
Skills enregistrées