Red Hat Enterprise Linux and Oracle Linux Networking Cheat Sheet and Guide

General Description of Linux Networking

Linux networking is the combination of kernel protocol stacks, network-device drivers, interface objects, routing tables, packet filters, user-space services, configuration profiles, and diagnostic utilities that allow a Red Hat Enterprise Linux or Oracle Linux system to communicate on local and remote networks.

A reliable administrator works from the lowest layer upward. First confirm that the adapter and driver exist. Then confirm carrier, speed, duplex, MTU, MAC address, VLAN and bond state. Only after the data-link layer is sound should you investigate IP addressing, neighbours, routes, DNS, transport ports, firewall policy, and application behaviour.

Typical administration tasks include:

  • Discovering wired, wireless, physical, virtual, bridge, VLAN, and bond interfaces.
  • Assigning static or DHCP-provided IPv4 and IPv6 addresses.
  • Configuring gateways, static routes, routing rules, DNS servers, and search domains.
  • Creating VLANs, virtual interfaces, active-backup bonds, and IEEE 802.3ad LACP bonds.
  • Managing host naming, time synchronisation, LDAP identity lookups, and NFS mounts.
  • Controlling traffic with firewalld, native nftables, SELinux network policy, and Linux traffic control.
  • Monitoring link counters, sockets, packet flows, latency, loss, retransmissions, and throughput.
  • Collecting logs, state snapshots, and packet captures for repeatable troubleshooting.

NetworkManager is the normal persistent network configuration service on current Red Hat Enterprise Linux and Oracle Linux releases. The nmcli command is the primary command-line interface; nmtui, Cockpit, the Nmstate API, and configuration automation are alternative front ends. The kernel-facing ip, ss, bridge, tc, ethtool, iw, and nft utilities remain essential because they display or change the actual running state.

This guide focuses on Red Hat Enterprise Linux 8, 9, and 10 and Oracle Linux 8, 9, and 10. It explicitly marks legacy ifcfg examples that are appropriate only for older or transitional systems. RHEL 10 and Oracle Linux 10 use NetworkManager keyfile profiles and do not support legacy ifcfg profiles.

Oracle Linux can run the Unbreakable Enterprise Kernel or the Red Hat Compatible Kernel. User-space tools and NetworkManager workflows are largely the same, but driver capabilities, offloads, queue counts, and performance counters can differ by kernel and hardware.

Safety, Version Scope, Conventions, and Example Addresses

Warning: Changing an interface, address, default route, VLAN, bond, DNS setting, or firewall zone over the same SSH session can disconnect you. Keep console, hypervisor console, serial console, or other out-of-band access available. Record the working configuration before changing it and keep a second privileged session open while testing.

Command prompts used in this guide:

$ command       # Run as an ordinary user
# command       # Run as root, or prefix the command with sudo

Documentation-only example values are used throughout:

Purpose

Example

Primary IPv4 LAN

192.0.2.0/24

Second IPv4 network

198.51.100.0/24

Third IPv4 network

203.0.113.0/24

IPv6 documentation prefix

2001:db8::/32

Wired interfaces

enp1s0 and enp2s0

Wireless interface

wlp2s0

Bond interface

bond0

VLAN interface

vlan100

Replace every interface name, connection profile name, address, gateway, DNS server, route, VLAN identifier, firewall zone, and service port with values appropriate to the system being managed.

Before a remote change, capture the current state:

# stamp=$(date +%F-%H%M%S)
# mkdir -p /root/network-backups/$stamp
# nmcli –terse –fields all connection show > /root/network-backups/$stamp/nmcli-connections.txt
# ip -details address show > /root/network-backups/$stamp/ip-address.txt
# ip -4 route show table all > /root/network-backups/$stamp/ip4-routes.txt
# ip -6 route show table all > /root/network-backups/$stamp/ip6-routes.txt
# ip rule show > /root/network-backups/$stamp/ip-rules.txt
# firewall-cmd –list-all-zones > /root/network-backups/$stamp/firewalld.txt 2>&1

Prefer changing a single NetworkManager profile and reapplying it instead of restarting all networking:

# nmcli connection show
# nmcli connection modify LAN ipv4.route-metric 100
# nmcli device reapply enp1s0
# nmcli connection up LAN

nmcli device reapply applies many changed properties without a full disconnect, but not every property is re-applicable. If activation is required, use a console or schedule an automatic rollback command before bringing the profile up.

Contents

  1. Built-in utilities and commonly installed tools
  2. Networking layers and layer-specific commands
  3. NetworkManager and networking service management
  4. Networking configuration files and version differences
  5. Errors, logs, and event monitoring
  6. Interface discovery and link management
  7. Static and DHCP IP addressing
  8. VLANs and IEEE 802.1Q tagging
  9. Failover IP addressing with active-backup bonding
  10. LACP / IEEE 802.3ad aggregation
  11. Routing and policy routing
  12. Host naming and name service switch configuration
  13. DNS client configuration and management
  14. NTP client configuration and management
  15. LDAP client configuration and management
  16. NFS client configuration and management
  17. firewalld, nftables, SELinux, and network security
  18. Traffic flow, bandwidth, and resource control
  19. Traffic monitoring and performance metrics
  20. Troubleshooting tools and layered workflows
  21. Command reference and authoritative references

Built-in Utilities and Commonly Installed Tools

Minimal installations contain the kernel and essential management tools, but some diagnostic programs are separate packages. Prefer the modern iproute family over ifconfig, route, arp, and netstat; install net-tools only when a legacy workflow or script requires those commands.

Core Utilities Normally Available

Utility

Primary purpose

Example

ip

Links, addresses, neighbours, routes, rules, tunnels, VRFs, and namespaces

ip -br address

ss

Listening and established TCP, UDP, and UNIX sockets

ss -lntup

systemctl

Start, stop, enable, and inspect networking services

systemctl status NetworkManager

journalctl

Kernel and service logs

journalctl -u NetworkManager -b

nmcli

NetworkManager devices, profiles, DNS, routes, bonds, VLANs, and Wi-Fi

nmcli device status

hostnamectl

Display and set the static host name

hostnamectl status

sysctl

Inspect and persist kernel network settings

sysctl net.ipv4.ip_forward

rpm / dnf

Identify and install packages

dnf provides ‘*/traceroute’

curl

Application-layer HTTP, TLS, proxy, and timing tests

curl -v https://example.com/

Practical Administration Package Set

Install a broad troubleshooting set from enabled base and application repositories:

# dnf install -y iproute iputils ethtool NetworkManager NetworkManager-tui \
  bind-utils traceroute nmap-ncat tcpdump nftables firewalld \
  pciutils usbutils lshw iw sysstat iperf3 mtr net-tools lsof

Optional declarative, performance, and advanced tracing tools:

# dnf install -y nmstate pcp pcp-system-tools conntrack-tools
# dnf install -y bcc-tools        # Availability depends on release and enabled repositories

Important package-to-command relationships:

Package

Important commands

Use

iproute

ip, ss, bridge, tc, nstat

Core modern networking administration

iputils

ping, arping, tracepath

ICMP reachability, neighbour and path-MTU testing

ethtool

ethtool

Link negotiation, driver, offload, ring, channel, and statistics data

NetworkManager

nmcli, nm-online

Persistent profiles and device management

NetworkManager-tui

nmtui

Text user interface for NetworkManager

nmstate

nmstatectl

Declarative state display and application

bind-utils

dig, host, nslookup, nsupdate

DNS queries and response analysis

traceroute

traceroute

Hop-by-hop path discovery using UDP, ICMP, or TCP probes

nmap-ncat

nc / ncat

TCP and UDP listener and connection testing

tcpdump

tcpdump

Packet capture and filtering

firewalld

firewall-cmd, firewall-offline-cmd

Zone, service, port, rich-rule, NAT, and policy management

nftables

nft

Native netfilter ruleset management

sysstat

sar, sadc, mpstat

Historical and periodic network and CPU metrics

iperf3

iperf3

Active TCP and UDP throughput testing

pcp

pmstat, pminfo, pmrep, pmlogger

Performance Co-Pilot live and archived metrics

net-tools

ifconfig, route, arp, netstat

Legacy compatibility only

Check whether a command is installed and which package provides it:

$ command -v nmcli ip ss ethtool dig traceroute nc tcpdump
$ rpm -q NetworkManager iproute ethtool bind-utils tcpdump
$ dnf provides ‘*/nc’
$ dnf provides ‘*/arp’

Modern Replacements for Legacy Commands

Legacy command

Preferred command

Example

ifconfig -a

ip address show or ip -br address

ip -br address

ifconfig enp1s0 up

ip link set dev enp1s0 up

ip link set dev enp1s0 up

route -n

ip route show

ip -4 route show

route add default gw 192.0.2.1

ip route add default via 192.0.2.1

ip route add default via 192.0.2.1 dev enp1s0

arp -n

ip neighbour show

ip neigh show

netstat -lntup

ss -lntup

ss -lntup

netstat -s

nstat and ss -s

nstat -az; ss -s

Legacy commands are still useful when reading old procedures, but they often omit modern attributes such as multiple routing tables, interface alternatives, namespaces, advanced queueing, and protocol-specific socket state.

Networking Layers and Layer-Specific Commands

The practical Linux networking stack can be viewed as a sequence of dependent layers. A name-resolution failure should not be investigated before confirming that the interface, address, neighbour entry, and route are valid. Likewise, an application timeout cannot be assigned to a firewall until packet flow and listening sockets are checked.

Layer

Questions to answer

Main interrogation tools

Main configuration tools

Physical

Is the adapter detected? Is the driver loaded? Is the cable, optic, radio, carrier, speed, and duplex correct?

lspci, lsusb, lshw, ethtool, iw, rfkill, journalctl -k

ethtool, driver/module options, firmware, NetworkManager link settings

Data link

Is the interface up? What are the MAC, MTU, VLAN, bridge, bond, and neighbour states?

ip -d -s link, bridge, ip neigh, ethtool, iw

ip link, nmcli, nmstatectl, bridge, bond and VLAN profiles

IP and routing

Does the host have the correct prefix, gateway, source address, route, and policy rule?

ip address, ip route, ip rule, ping, tracepath, arping

ip address/route/rule, nmcli, nmstatectl, keyfiles

Transport

Is TCP or UDP bound and reachable? Are there resets, retransmissions, or queue pressure?

ss, nstat, tcpdump, nc, iperf3

Service configuration, firewalld/nftables, sysctl, tc

Application and naming

Does DNS, HTTP, SSH, LDAP, NTP, or NFS complete its protocol exchange?

dig, getent, curl, openssl, ldapsearch, chronyc, rpcinfo

Service client files, NetworkManager DNS, SSSD, chrony, fstab

Physical Layer

The physical layer includes the network adapter, bus, driver, firmware, cable or fibre, transceiver, radio, signal, negotiated speed, and carrier. Linux creates an interface only after a driver successfully binds to detected hardware.

List PCI and USB network hardware and the driver in use:

$ lspci -nnk | grep -A3 -Ei ‘ethernet|network’
$ lsusb
# lshw -class network
$ udevadm info -q property -p /sys/class/net/enp1s0

Inspect driver, firmware, permanent bus path, and kernel version:

$ ethtool -i enp1s0
$ readlink -f /sys/class/net/enp1s0/device/driver
$ udevadm info /sys/class/net/enp1s0 | grep -E ‘ID_PATH=|ID_NET_DRIVER=’
$ uname -r

On Oracle Linux, identify the running kernel before comparing driver behaviour:

$ uname -r
$ grubby –default-kernel
$ rpm -q kernel-core kernel-uek-core 2>/dev/null

Check carrier, negotiation, and relevant kernel messages:

$ ethtool enp1s0
$ cat /sys/class/net/enp1s0/carrier
$ cat /sys/class/net/enp1s0/operstate
# journalctl -k -b | grep -Ei ‘enp1s0|link|firmware|carrier|renamed|reset|timeout’

Interpretation: carrier value 1 normally means a physical signal is detected; 0 means no usable carrier. Administrative state and physical carrier are separate: an interface can be administratively down while a cable remains connected.

Data-Link Layer

The data-link layer covers Ethernet or Wi-Fi frames, MAC addresses, MTU, VLAN tags, bridges, bonds, and ARP or IPv6 neighbour discovery. UP means administratively enabled. LOWER_UP means the lower layer reports carrier. NO-CARRIER means the device is enabled but the link is unavailable.

$ ip -br link
$ ip -details -statistics link show dev enp1s0
$ ethtool -S enp1s0
$ bridge link show
$ bridge vlan show
$ ip neighbour show

Temporarily enable an interface and set its MTU:

# ip link set dev enp1s0 up
# ip link set dev enp1s0 mtu 1500
# ip link set dev enp1s0 down

Warning: Bringing down the interface carrying the administrative session disconnects it. An MTU change can also stall existing connections when the path does not support the new size.

IP, ICMP, and Routing Layer

The IP layer assigns IPv4 and IPv6 addresses, maintains routing tables and policy rules, selects a source address, resolves local neighbours, and reports network conditions through ICMP or ICMPv6.

$ ip -br address
$ ip -4 address show scope global
$ ip -6 address show scope global
$ ip -4 route show table all
$ ip -6 route show table all
$ ip rule show
$ ip route get 198.51.100.25
$ ip -6 route get 2001:db8:2::25

Test the local gateway and a routed destination using an explicit source interface:

$ ping -c 4 192.0.2.1
$ ping -c 4 -I enp1s0 198.51.100.25
$ tracepath 198.51.100.25
$ arping -I enp1s0 -c 3 192.0.2.1

TCP and UDP Transport Layer

TCP is connection-oriented and includes a handshake, sequencing, acknowledgements, retransmission, congestion control, and orderly close. UDP sends independent datagrams and has no transport-layer handshake, so an apparently successful UDP probe does not always prove that the application replied.

$ ss -lntup
$ ss -tnp state established
$ ss -tan state syn-sent
$ ss -ti dst 198.51.100.20
$ ss -s
$ nstat -az | grep -E ‘TcpRetransSegs|UdpInErrors|IpInDiscards’

Test a TCP port and send a UDP probe:

$ nc -vz -w 3 192.0.2.20 443
$ nc -vzu -w 3 192.0.2.53 53
$ dig @192.0.2.53 example.com A +time=2 +tries=1

A Layered Test Sequence

  1. Confirm hardware detection, driver binding, and firmware.
  2. Confirm administrative state, carrier, speed, duplex, MTU, VLAN, bridge, and bond membership.
  3. Confirm expected IPv4 or IPv6 addresses and prefix lengths.
  4. Confirm ARP or IPv6 neighbour discovery to the local gateway.
  5. Confirm the selected route and any policy-routing rule.
  6. Test by numeric address before testing DNS.
  7. Confirm a local or remote socket is listening on the expected protocol and port.
  8. Confirm firewalld zone assignment, nftables policy, and SELinux service permissions.
  9. Capture packets and correlate timestamps with NetworkManager, kernel, and application logs.

$ ip -br link
$ ethtool enp1s0
$ ip -br address
$ ip neigh show dev enp1s0
$ ip route get 198.51.100.25
$ ping -c 3 198.51.100.25
$ getent ahosts app.example.com
$ nc -vz app.example.com 443
# tcpdump -ni enp1s0 host 198.51.100.25 and port 443

Management of Network and Networking Services

Current RHEL and Oracle Linux systems use NetworkManager as the normal owner of persistent interface configuration. A device can still be changed with ip or ethtool, but those changes are runtime-only unless written into a NetworkManager profile or another persistent mechanism.

Identify the Active Network Owner

$ systemctl is-active NetworkManager
$ systemctl is-enabled NetworkManager
$ nmcli general status
$ nmcli device status
$ nmcli connection show –active
$ nmcli -f GENERAL.DEVICE,GENERAL.STATE,GENERAL.CONNECTION device show enp1s0

Check whether NetworkManager deliberately ignores a device:

$ nmcli -f GENERAL.DEVICE,GENERAL.STATE,GENERAL.REASON device show enp1s0
$ nmcli device status
$ grep -R “unmanaged” /etc/NetworkManager /usr/lib/NetworkManager 2>/dev/null

A device shown as unmanaged may be excluded by a configuration rule, an installation or cloud tool, or a plugin. Do not create a second manager for the same interface until the reason is understood.

systemd Service Management

$ systemctl status NetworkManager
# systemctl enable –now NetworkManager
# systemctl reload NetworkManager
# systemctl restart NetworkManager
$ systemctl status NetworkManager-dispatcher
$ systemctl status NetworkManager-wait-online

Warning: Restarting NetworkManager can interrupt every profile it controls. Prefer nmcli connection reload, nmcli device reapply, or activation of one profile.

Understand online targets:

$ systemctl status network.target network-online.target
$ systemctl list-dependencies network-online.target
$ systemctl is-enabled NetworkManager-wait-online.service
$ nm-online -s -q –timeout=30; echo $?

network.target means the networking service has started, not that a usable route or DNS service exists. Services that truly require configured connectivity should order themselves after network-online.target, with a suitable wait-online implementation enabled.

NetworkManager Device and Profile Management

A NetworkManager connection profile is a saved configuration. A device is the current kernel interface. Multiple profiles can exist for one device, but normally only one profile is active on it.

$ nmcli general status
$ nmcli device status
$ nmcli connection show
$ nmcli connection show –active
$ nmcli connection show LAN
$ nmcli -f NAME,UUID,TYPE,DEVICE,FILENAME connection show

Activate, deactivate, reload, reapply, or delete a profile:

# nmcli connection up LAN
# nmcli connection down LAN
# nmcli connection reload
# nmcli device reapply enp1s0
# nmcli connection delete OLD-LAN

Change only one setting and verify before activation:

# nmcli connection modify LAN connection.autoconnect yes
# nmcli connection modify LAN ipv4.route-metric 100
$ nmcli -f connection.id,connection.interface-name,ipv4.method,ipv4.addresses,ipv4.gateway connection show LAN

Temporarily disconnect or reconnect a device:

# nmcli device disconnect enp1s0
# nmcli device connect enp1s0

This differs from nmcli connection down: the device command acts on the device, while the connection command acts on a profile. Both are dangerous over the active management path.

nmtui and Cockpit

Use the text interface on a console or terminal:

# nmtui
# nmtui-edit
# nmtui-connect
# nmtui-hostname

The Cockpit web console can manage interfaces, bonds, bridges, VLANs, routes, and firewalld when the required Cockpit packages are installed:

# dnf install -y cockpit cockpit-networkmanager
# systemctl enable –now cockpit.socket
$ ss -lntp | grep 9090

Expose Cockpit only to trusted management networks and permit TCP 9090 through firewalld only where required.

Nmstate Declarative Management

Nmstate represents desired network state in YAML. It is useful for repeatable configuration, automation, and transactional application.

$ nmstatectl show
$ nmstatectl show enp1s0
$ nmstatectl show –json

Example state file for a static interface:


interfaces:
  – name: enp1s0
    type: ethernet
    state: up
    ipv4:
      enabled: true
      dhcp: false
      address:
        – ip: 192.0.2.10
          prefix-length: 24
    ipv6:
      enabled: true
      autoconf: true
routes:
  config:
    – destination: 0.0.0.0/0
      next-hop-address: 192.0.2.1
      next-hop-interface: enp1s0

Apply and verify it:

# nmstatectl apply /root/enp1s0.yml
$ nmstatectl show enp1s0
$ ip address show dev enp1s0
$ ip route get 198.51.100.1

Nmstate checks the resulting state and attempts rollback if application fails, but console access is still required for high-risk remote changes.

NetworkManager Dispatcher Scripts

Dispatcher scripts run on device or connectivity events and are useful for route adjustments, monitoring hooks, or compatibility with old DHCP scripts.

# install -m 700 /dev/null /etc/NetworkManager/dispatcher.d/90-example
# cat > /etc/NetworkManager/dispatcher.d/90-example <<‘SCRIPT’
#!/bin/bash
iface=$1
state=$2
logger -t nm-dispatcher-example “interface=$iface state=$state”
SCRIPT
# restorecon -v /etc/NetworkManager/dispatcher.d/90-example

Keep scripts fast, non-interactive, idempotent, and secure. A hanging dispatcher script can delay profile activation.

Management of Networking Configuration Files

Persistent state can originate from several locations. Use nmcli, Nmstate, Cockpit, or automation wherever possible rather than editing generated files by hand.

Path

Owner or purpose

Important notes

/etc/NetworkManager/system-connections/*.nmconnection

User-created persistent NetworkManager keyfiles

Root-owned, mode 600; reload after external edits

/run/NetworkManager/system-connections/

Runtime-only profiles

Removed at reboot

/usr/lib/NetworkManager/system-connections/

Vendor or predeployed profiles

Local API changes are copied to /etc or /run

/etc/NetworkManager/NetworkManager.conf

Main NetworkManager configuration

Prefer local drop-ins for isolated changes

/etc/NetworkManager/conf.d/*.conf

Local NetworkManager drop-ins

Read in lexical order

/etc/NetworkManager/dispatcher.d/

Event scripts

Must be executable, secure, and SELinux-labelled

/etc/sysconfig/network-scripts/ifcfg-*

Legacy ifcfg profiles

Older or transitional releases only; unsupported on RHEL 10 and Oracle Linux 10

/etc/sysconfig/network-scripts/route-* and rule-*

Legacy routes and rules

Older releases only

/etc/resolv.conf

Resolver configuration normally generated by NetworkManager

Inspect ownership before editing

/etc/hosts and /etc/nsswitch.conf

Static names and name-service lookup order

Syntax errors affect all local lookups

/etc/chrony.conf

Chrony NTP client/server configuration

Restart or reload chronyd after changes

/etc/sssd/sssd.conf and /etc/sssd/conf.d/*.conf

SSSD identity and authentication

Sensitive; mode 600 and correct SELinux context

/etc/openldap/ldap.conf

OpenLDAP client defaults

URI, base DN, and CA trust

/etc/fstab

Persistent mounts including NFS

Test with mount -a before reboot

/etc/firewalld/

Persistent firewalld configuration

Normally manage with firewall-cmd

/etc/nftables/ or distribution nftables include file

Native nftables rules

Use only when firewalld is not the selected manager

/etc/sysctl.conf and /etc/sysctl.d/*.conf

Persistent kernel network parameters

Validate with sysctl –system

Keyfile Profiles

RHEL 10 and Oracle Linux 10 use keyfile profiles exclusively. RHEL 9 and Oracle Linux 9 also use keyfiles as the normal format. A simplified keyfile looks like this:

[connection]
id=LAN
uuid=11111111-2222-3333-4444-555555555555
type=ethernet
interface-name=enp1s0
autoconnect=true

[ethernet]

[ipv4]
method=manual
address1=192.0.2.10/24,192.0.2.1
dns=192.0.2.53;198.51.100.53;
dns-search=example.com;

[ipv6]
method=auto

Do not invent UUIDs or manually edit profiles as the normal workflow. Generate or change them with NetworkManager:

# nmcli connection add type ethernet con-name LAN ifname enp1s0 \
  ipv4.method manual ipv4.addresses 192.0.2.10/24 \
  ipv4.gateway 192.0.2.1 ipv4.dns “192.0.2.53 198.51.100.53”
# chmod 600 /etc/NetworkManager/system-connections/*.nmconnection
# nmcli connection reload

Create a keyfile offline for image building or a chroot:

# nmcli –offline connection add type ethernet con-name LAN \
  ifname enp1s0 ipv4.method manual ipv4.addresses 192.0.2.10/24 \
  ipv4.gateway 192.0.2.1 > /etc/NetworkManager/system-connections/LAN.nmconnection
# chown root:root /etc/NetworkManager/system-connections/LAN.nmconnection
# chmod 600 /etc/NetworkManager/system-connections/LAN.nmconnection
# nmcli connection reload

Legacy ifcfg Profiles

Use these only on releases that still support them, primarily RHEL/Oracle Linux 8 and some transitional 9 deployments. Do not use them on RHEL 10 or Oracle Linux 10.

# /etc/sysconfig/network-scripts/ifcfg-enp1s0
TYPE=Ethernet
NAME=LAN
DEVICE=enp1s0
ONBOOT=yes
BOOTPROTO=none
IPADDR=192.0.2.10
PREFIX=24
GATEWAY=192.0.2.1
DNS1=192.0.2.53
DNS2=198.51.100.53

After an external file edit:

# nmcli connection reload
# nmcli connection up LAN

Do not run the removed legacy network service on a modern system. NetworkManager can read supported legacy profiles without network.service.

Safe Editing and Validation

# install -d -m 700 /root/network-backups
# cp -a /etc/NetworkManager/system-connections /root/network-backups/system-connections.$(date +%F-%H%M%S)
# nmcli connection show LAN
# nmcli connection reload
# nmcli connection up LAN
# nmcli -f GENERAL.STATE,IP4.ADDRESS,IP4.GATEWAY,IP4.DNS device show enp1s0

Validate related files before rebooting:

# sysctl –system
# mount -av
# sssctl config-check
# chronyd -Q -t 3 ‘server 192.0.2.123 iburst’ 2>/dev/null
# firewall-cmd –check-config

Errors, Logs, and Event Monitoring

Network failures are easier to diagnose when runtime state, logs, and packets are examined with the same timestamps. Begin with the current boot, then widen the time range only when needed.

General and Kernel Logs

# journalctl -b -p warning
# journalctl -k -b
# journalctl -k -b | grep -Ei ‘link|carrier|firmware|reset|timeout|drop|mtu|bond|vlan’
# dmesg -T | tail -100

Driver resets, transmit timeouts, firmware load failures, PCI errors, renamed interfaces, and carrier transitions normally appear in the kernel journal.

NetworkManager Logs

# journalctl -u NetworkManager -b
# journalctl -u NetworkManager -b –since ‘-15 minutes’
# journalctl -fu NetworkManager
$ nmcli general logging

Temporarily increase logging while reproducing a problem:

# nmcli general logging level DEBUG domains ALL
# journalctl -fu NetworkManager
# nmcli general logging level INFO domains DEFAULT

Use TRACE only for a short controlled window because it can be very verbose and may expose network metadata.

Related service logs:

# journalctl -u firewalld -b
# journalctl -u chronyd -b
# journalctl -u sssd -b
# journalctl -u rpc-statd -b
# journalctl -u NetworkManager-dispatcher -b

Live Link, Address, Route, and Profile Events

$ ip monitor all
$ ip monitor link address route neigh
$ nmcli monitor
$ nmcli device monitor enp1s0
$ udevadm monitor –kernel –udev –property –subsystem-match=net

Run these commands in one terminal while changing cables, activating profiles, renewing DHCP, or reproducing failover in another.

Common Messages and Their Likely Layer

Message or symptom

Likely layer

First checks

NO-CARRIER or carrier 0

Physical/data link

Cable, optic, radio, switch port, ethtool, rfkill, driver logs

device is strictly unmanaged

Management

NetworkManager unmanaged rules and device reason

RTNETLINK answers: File exists

IP/routing

Existing address, route, rule, or duplicate configuration

Network is unreachable

Routing

Address/prefix, connected route, default route, policy rules

Nexthop has invalid gateway

Routing

Gateway must normally be reachable on-link or use explicit onlink semantics

Destination Host Unreachable

Neighbour/routing

ARP/NDP, VLAN, prefix, peer state, local route

Connection refused

Transport/application

Listener absent, wrong bind address, TCP reset, reject rule

Connection timed out

Path/filtering

Route, silent firewall drop, server down, return path

Temporary failure in name resolution

DNS/NSS

/etc/resolv.conf, nmcli DNS, DNS reachability, nsswitch

activation failed: IP configuration could not be reserved

DHCP/IP

DHCP server, pool, duplicate address, VLAN, timeout

duplicate address detected

IP

arping, duplicate-address detection, stale profile, cloned VM

martian source / rp_filter drop

Routing/security

Asymmetric path, policy routing, reverse-path filtering

Collect a concise failure snapshot before restarting anything:

# date -Ins
# nmcli general status
# nmcli device status
# nmcli connection show –active
# ip -details -statistics link
# ip -details address
# ip route show table all
# ip rule show
# ip neigh show
# ss -s
# firewall-cmd –get-active-zones
# journalctl -u NetworkManager -b –since ‘-10 minutes’

Interface Discovery and Link Management

Discover All Interfaces

Display concise link and address summaries:

$ ip -br link
$ ip -br address
$ nmcli device status
$ ls -1 /sys/class/net

Show all details for one interface:

$ ip -details -statistics link show dev enp1s0
$ ip -details address show dev enp1s0
$ nmcli device show enp1s0

Useful state terms:

State or flag

Meaning

UP

The interface is administratively enabled.

DOWN

The interface is administratively disabled.

LOWER_UP

The lower layer reports a working carrier.

NO-CARRIER

The device is up but no usable physical or virtual carrier exists.

UNKNOWN

The driver or virtual device does not expose a normal carrier state.

unmanaged

NetworkManager is not controlling the device.

disconnected

NetworkManager controls the device but no profile is active.

connected

A NetworkManager profile is active.

Show only interfaces that are operationally up:

$ ip -br link | awk ‘$2 ~ /UP/ {print}’
$ nmcli -f DEVICE,TYPE,STATE,CONNECTION device status

Predictable names such as enp1s0, eno1, and ens3 describe firmware, onboard, slot, or bus topology. Legacy names such as eth0 can still appear when predictable naming is disabled, overridden, or inherited from an older installation.

Distinguish Physical, Virtual, and Hardware-Backed Interfaces

A hardware-backed interface normally has a sysfs device path:

$ test -e /sys/class/net/enp1s0/device && echo hardware-backed
$ readlink -f /sys/class/net/enp1s0/device
$ udevadm info -q property -p /sys/class/net/enp1s0
$ ethtool -i enp1s0

List likely interface type and driver information:

$ for path in /sys/class/net/*; do
>   iface=${path##*/}
>   printf ‘\n== %s ==\n’ “$iface”
>   ip -d link show dev “$iface” | head -1
>   udevadm info -q property -p “$path” 2>/dev/null |
>     grep -E ‘^ID_BUS=|^ID_NET_DRIVER=|^ID_PATH=’ || true
> done

Common virtual types include lo, bond, bridge, vlan, dummy, veth, tun, tap, macvlan, ipvlan, vrf, and container-created interfaces. Use the detailed link output to expose the kind and parent relationship:

$ ip -d link show
$ ip -d link show type vlan
$ ip -d link show type bond
$ ip -d link show type bridge
$ bridge link show

Discover Wireless Interfaces

Install iw if the minimal image does not contain it:

# dnf install -y iw wireless-regdb

List radios, wireless interfaces, and association state:

$ iw phy
$ iw dev
$ iw dev wlp2s0 info
$ iw dev wlp2s0 link
$ iw dev wlp2s0 station dump

Check radio blocks and NetworkManager Wi-Fi state:

$ rfkill list
# rfkill unblock wifi
$ nmcli radio
$ nmcli radio wifi on
$ nmcli device wifi list ifname wlp2s0

Connect interactively so the password is not placed in shell history:

# nmcli –ask device wifi connect “ExampleSSID” ifname wlp2s0
$ nmcli connection show –active
$ nmcli -f GENERAL,IP4,IP6 device show wlp2s0

Create a WPA-PSK profile non-interactively only in controlled automation:

# nmcli connection add type wifi ifname wlp2s0 con-name office-wifi ssid ExampleSSID
# nmcli connection modify office-wifi wifi-sec.key-mgmt wpa-psk
# nmcli connection modify office-wifi wifi-sec.psk ‘replace-with-real-secret’
# nmcli connection modify office-wifi ipv4.method auto ipv6.method auto
# nmcli connection up office-wifi

Warning: A secret supplied on the command line can be captured in shell history, audit records, or process inspection. Prefer nmcli –ask, a protected keyfile, or an enterprise secret-management workflow.

Find the MAC Address

Display the current MAC address:

$ ip link show dev enp1s0
$ cat /sys/class/net/enp1s0/address
$ nmcli -g GENERAL.HWADDR device show enp1s0

Display the permanent hardware address when the driver supports it:

$ ethtool -P enp1s0
$ nmcli -g GENERAL.PERM-HWADDR device show enp1s0

Temporarily change the MAC address:

# ip link set dev enp1s0 down
# ip link set dev enp1s0 address 02:00:00:00:01:10
# ip link set dev enp1s0 up
$ ip link show dev enp1s0

Persist a cloned MAC in a NetworkManager profile:

# nmcli connection modify LAN 802-3-ethernet.cloned-mac-address 02:00:00:00:01:10
# nmcli connection up LAN

Restore the permanent address:

# nmcli connection modify LAN 802-3-ethernet.cloned-mac-address permanent
# nmcli connection up LAN

A MAC change can invalidate switch-port security, DHCP reservations, neighbour caches, virtualisation policy, and licensing. Use a locally administered address; a first octet such as 02 sets the local bit without setting the multicast bit.

Find Advanced Interface Properties

$ ip -details -statistics link show dev enp1s0
$ ethtool enp1s0
$ ethtool -i enp1s0        # Driver, firmware, bus and expansion-ROM information
$ ethtool -k enp1s0        # Offload features
$ ethtool -g enp1s0        # Receive and transmit ring parameters
$ ethtool -c enp1s0        # Interrupt coalescing
$ ethtool -l enp1s0        # Channel and queue counts
$ ethtool -a enp1s0        # Pause-frame settings
$ ethtool -S enp1s0        # Driver and hardware statistics
$ ethtool -m enp1s0        # SFP/QSFP module data, when supported
$ nmcli –fields GENERAL,CAPABILITIES,WIRED-PROPERTIES device show enp1s0

Inspect selected sysfs properties:

$ grep . /sys/class/net/enp1s0/{operstate,carrier,mtu,tx_queue_len,address} 2>/dev/null
$ ls -1 /sys/class/net/enp1s0/queues/
$ cat /proc/interrupts | grep -i enp1s0

Identify the active profile and its persistent properties:

$ nmcli -g GENERAL.CONNECTION device show enp1s0
$ nmcli connection show LAN
$ nmcli -f connection.id,connection.interface-name,802-3-ethernet.mtu,\
802-3-ethernet.auto-negotiate,802-3-ethernet.speed,802-3-ethernet.duplex \
  connection show LAN

Find Link Speed and Duplex

ethtool provides the most direct Ethernet view:

$ ethtool enp1s0 | grep -E ‘Supported link modes:|Advertised link modes:|Speed:|Duplex:|Auto-negotiation:|Link detected:’

Alternative script-friendly views:

$ cat /sys/class/net/enp1s0/speed 2>/dev/null
$ cat /sys/class/net/enp1s0/duplex 2>/dev/null
$ nmcli -g GENERAL.SPEED device show enp1s0

The sysfs speed is normally reported in megabits per second. -1, unknown, or an input/output error usually means the link is down or the driver does not expose the property. Virtual interfaces often have no meaningful physical link speed.

Configure Fixed or Automatic Link Speed

Set 100 Mbit/s full duplex with autonegotiation disabled until the next device reset, profile reactivation, or reboot:

# ethtool -s enp1s0 autoneg off speed 100 duplex full
$ ethtool enp1s0

Return to automatic negotiation:

# ethtool -s enp1s0 autoneg on
$ ethtool enp1s0

Persist fixed speed and duplex in a NetworkManager profile:

# nmcli connection modify LAN \
  802-3-ethernet.auto-negotiate no \
  802-3-ethernet.speed 100 \
  802-3-ethernet.duplex full
# nmcli connection up LAN

For a 1 Gbit/s copper link, keep autonegotiation enabled and advertise the intended mode:

# nmcli connection modify LAN \
  802-3-ethernet.auto-negotiate yes \
  802-3-ethernet.speed 1000 \
  802-3-ethernet.duplex full
# nmcli connection up LAN

Restore unrestricted autonegotiation:

# nmcli connection modify LAN \
  802-3-ethernet.auto-negotiate yes \
  802-3-ethernet.speed 0 \
  802-3-ethernet.duplex “”
# nmcli connection up LAN

Warning: Both link partners must use compatible settings. A duplex mismatch can produce high CRC errors, late collisions, retransmissions, and very poor throughput. Copper 1000BASE-T normally requires autonegotiation; do not disable it merely to force a nominal 1 Gbit/s speed.

Verify after every change:

$ ethtool enp1s0
$ ip -s link show dev enp1s0
$ ethtool -S enp1s0 | grep -Ei ‘crc|error|drop|collision|miss|timeout’

Administrative State, MTU, Offloads, Rings, and Channels

Temporary administrative and MTU changes:

# ip link set dev enp1s0 up
# ip link set dev enp1s0 mtu 9000
$ ip -d link show dev enp1s0
# ip link set dev enp1s0 down

Persist MTU through the profile:

# nmcli connection modify LAN 802-3-ethernet.mtu 9000
# nmcli connection up LAN
$ nmcli -g 802-3-ethernet.mtu connection show LAN

Jumbo frames require the host, VLAN path, switches, routers, hypervisors, and destination to support the larger frame. Probe a 1500-byte IPv4 path with 1472 bytes of ICMP payload:

$ ping -c 3 -M do -s 1472 198.51.100.25
$ tracepath 198.51.100.25

Temporarily alter selected offloads:

$ ethtool -k enp1s0
# ethtool -K enp1s0 gro off gso off tso off
$ ethtool -k enp1s0

Offload changes are useful for diagnosis but can significantly increase CPU load. Record the original state and restore it after testing:

# ethtool -K enp1s0 gro on gso on tso on

Inspect and tune rings or channels only when supported by the driver:

$ ethtool -g enp1s0
# ethtool -G enp1s0 rx 2048 tx 2048
$ ethtool -l enp1s0
# ethtool -L enp1s0 combined 8

Persistent ethtool settings can be stored as NetworkManager properties on releases that expose the corresponding ethtool.* keys. List available settings before relying on a particular property:

$ nmcli –fields all connection show LAN | grep -i ethtool
$ nmcli connection modify LAN ethtool.feature-gro off ethtool.feature-tso off
# nmcli connection up LAN

Driver and NetworkManager property support varies by release and adapter. Treat an unknown property error as a capability/version issue rather than silently assuming the setting persisted.

Configure Virtual Interfaces

Linux virtual interfaces are useful for service addresses, virtual machines, containers, routing, tests, and segmentation. Objects created with ip are temporary unless NetworkManager, a systemd unit, container runtime, or orchestration system recreates them.

Dummy Interface

Temporary dummy interface:

# ip link add dummy0 type dummy
# ip address add 192.0.2.200/32 dev dummy0
# ip link set dummy0 up
$ ip -br address show dummy0
# ip link delete dummy0

Persistent NetworkManager dummy profile:

# nmcli connection add type dummy ifname dummy0 con-name dummy0 \
  ipv4.method manual ipv4.addresses 192.0.2.200/32 \
  ipv4.never-default yes ipv6.method disabled
# nmcli connection up dummy0

Dummy addresses are useful for loopback-style service endpoints, routing daemons, and stable source addresses. Ensure routes and firewall rules intentionally handle the address.

Virtual Ethernet Pair

A veth pair behaves like a virtual patch cable. Frames entering one end exit the peer:

# ip link add veth-a type veth peer name veth-b
# ip link set veth-a up
# ip link set veth-b up
$ ip -d link show veth-a
$ ip -d link show veth-b
# ip link delete veth-a

Move one end into a namespace:

# ip netns add testns
# ip link set veth-b netns testns
# ip address add 192.0.2.1/30 dev veth-a
# ip link set veth-a up
# ip -n testns address add 192.0.2.2/30 dev veth-b
# ip -n testns link set lo up
# ip -n testns link set veth-b up
$ ping -c 2 192.0.2.2
# ip netns delete testns
# ip link delete veth-a 2>/dev/null || true

Bridge Interface

A bridge forwards Ethernet frames among member ports and is frequently used by KVM/libvirt and container hosts.

Temporary bridge:

# ip link add br0 type bridge
# ip link set enp2s0 master br0
# ip link set enp2s0 up
# ip link set br0 up
$ bridge link show
$ bridge fdb show br br0

Place the host address on br0, not on the enslaved physical port:

# ip address flush dev enp2s0
# ip address add 198.51.100.10/24 dev br0

Persistent NetworkManager bridge:

# nmcli connection add type bridge ifname br0 con-name br0 \
  ipv4.method manual ipv4.addresses 198.51.100.10/24 \
  ipv4.gateway 198.51.100.1 ipv4.dns “198.51.100.53 198.51.100.54” \
  bridge.stp yes
# nmcli connection add type ethernet port-type bridge ifname enp2s0 \
  con-name br0-port1 controller br0
# nmcli connection up br0

Older nmcli versions accept the equivalent port syntax master br0 slave-type bridge.

Verify bridge state:

$ nmcli connection show –active
$ ip -d link show br0
$ bridge link show
$ bridge fdb show br br0
$ bridge vlan show

Macvlan and Ipvlan Interfaces

A macvlan interface has its own MAC address on a parent. In bridge mode, macvlan peers can communicate through the parent, but direct host-to-macvlan communication requires additional design.

# ip link add macvlan0 link enp1s0 type macvlan mode bridge
# ip address add 192.0.2.210/24 dev macvlan0
# ip link set macvlan0 up
$ ip -d link show macvlan0
# ip link delete macvlan0

Persistent NetworkManager macvlan profile:

# nmcli connection add type macvlan con-name macvlan0 ifname macvlan0 \
  macvlan.parent enp1s0 macvlan.mode bridge \
  ipv4.method manual ipv4.addresses 192.0.2.210/24 \
  ipv4.never-default yes ipv6.method disabled
# nmcli connection up macvlan0

Ipvlan shares the parent MAC and separates traffic by IP. A temporary L2-mode example:

# ip link add link enp1s0 name ipvlan0 type ipvlan mode l2
# ip address add 192.0.2.211/24 dev ipvlan0
# ip link set ipvlan0 up
$ ip -d link show ipvlan0
# ip link delete ipvlan0

Static and DHCP IP Addressing

An address contains an IP and prefix, such as 192.0.2.10/24 or 2001:db8:1::10/64. The prefix defines the directly connected network. Temporary ip commands change only the running kernel state. Persistent settings belong in the NetworkManager connection profile.

Inspect Current Addresses and Address Metadata

$ ip -br address
$ ip -4 address show dev enp1s0
$ ip -6 address show dev enp1s0
$ ip -details address show dev enp1s0
$ nmcli -f GENERAL,IP4,IP6,DHCP4,DHCP6 device show enp1s0

Important flags include dynamic, secondary, temporary, tentative, deprecated, noprefixroute, valid_lft, and preferred_lft. A tentative IPv6 address is still undergoing duplicate-address detection.

Temporary Static IPv4 Address – Add, Change, and Delete

Add an address without removing existing addresses:

# ip address add 192.0.2.10/24 dev enp1s0
# ip link set dev enp1s0 up
$ ip -br address show dev enp1s0

Replace or delete an exact entry:

# ip address replace 192.0.2.10/24 dev enp1s0
# ip address del 192.0.2.10/24 dev enp1s0

Flush all global IPv4 addresses only when this destructive action is intended:

# ip -4 address flush dev enp1s0 scope global

Warning: Flushing can remove both static and DHCP-derived addresses and disconnect every session using the device. Prefer deleting one exact prefix.

Temporary Static IPv6 Address

# ip -6 address add 2001:db8:1::10/64 dev enp1s0
$ ip -6 address show dev enp1s0
# ip -6 address del 2001:db8:1::10/64 dev enp1s0

An IPv6 default gateway is commonly a link-local address and therefore requires an interface:

# ip -6 route add default via fe80::1 dev enp1s0 metric 100

Persistent Static Address with NetworkManager

Create a new static dual-stack profile:

# nmcli connection add type ethernet ifname enp1s0 con-name LAN \
  ipv4.method manual \
  ipv4.addresses 192.0.2.10/24 \
  ipv4.gateway 192.0.2.1 \
  ipv4.dns “192.0.2.53 192.0.2.54” \
  ipv4.dns-search example.com \
  ipv6.method manual \
  ipv6.addresses 2001:db8:1::10/64 \
  ipv6.gateway 2001:db8:1::1 \
  ipv6.dns “2001:db8:1::53”
# nmcli connection up LAN

Modify the primary address:

# nmcli connection modify LAN ipv4.addresses 192.0.2.20/24
# nmcli connection up LAN

Add and remove a secondary address without replacing the primary:

# nmcli connection modify LAN +ipv4.addresses 192.0.2.21/24
# nmcli device reapply enp1s0
# nmcli connection modify LAN -ipv4.addresses 192.0.2.21/24
# nmcli device reapply enp1s0

Disable a protocol family when it is deliberately unused:

# nmcli connection modify LAN ipv6.method disabled
# nmcli connection up LAN

Using ipv6.method disabled is a policy choice. Do not disable IPv6 merely to hide a DNS or routing problem; local applications and infrastructure may depend on it.

Inspect the saved profile and active state:

$ nmcli connection show LAN
$ nmcli -f GENERAL,IP4,IP6 device show enp1s0
$ ip address show dev enp1s0
$ ip route show
$ ip -6 route show

Persistent Static Address with Nmstate

Create /root/lan-static.yml:

interfaces:
  – name: enp1s0
    type: ethernet
    state: up
    ipv4:
      enabled: true
      dhcp: false
      address:
        – ip: 192.0.2.10
          prefix-length: 24
    ipv6:
      enabled: true
      dhcp: false
      autoconf: false
      address:
        – ip: 2001:db8:1::10
          prefix-length: 64
routes:
  config:
    – destination: 0.0.0.0/0
      next-hop-interface: enp1s0
      next-hop-address: 192.0.2.1
    – destination: ::/0
      next-hop-interface: enp1s0
      next-hop-address: 2001:db8:1::1
dns-resolver:
  config:
    server:
      – 192.0.2.53
      – 192.0.2.54
      – 2001:db8:1::53
    search:
      – example.com

Preview, apply, and verify:

# nmstatectl show
# nmstatectl apply –no-commit /root/lan-static.yml
# nmstatectl commit
$ nmstatectl show enp1s0

When supported, the no-commit transaction automatically rolls back unless committed. Confirm the local nmstatectl –help options because transaction behaviour differs across package versions.

Legacy ifcfg Static Address – RHEL/Oracle Linux 8 Only

Version note: RHEL 9 and Oracle Linux 9 default to keyfiles. RHEL 10 and Oracle Linux 10 do not support ifcfg profiles. Use this only for an older system that already relies on /etc/sysconfig/network-scripts/ifcfg-*.

Example /etc/sysconfig/network-scripts/ifcfg-enp1s0:

TYPE=Ethernet
DEVICE=enp1s0
NAME=LAN
ONBOOT=yes
BOOTPROTO=none
IPADDR=192.0.2.10
PREFIX=24
GATEWAY=192.0.2.1
DNS1=192.0.2.53
DNS2=192.0.2.54
DOMAIN=example.com
IPV6INIT=yes
IPV6ADDR=2001:db8:1::10/64
IPV6_DEFAULTGW=2001:db8:1::1

Reload and activate through NetworkManager rather than invoking removed network scripts:

# nmcli connection reload
# nmcli connection up LAN

Migrate an existing ifcfg profile to a keyfile before a major-version upgrade where possible:

$ nmcli connection show
# nmcli connection migrate LAN
$ ls -l /etc/NetworkManager/system-connections/

The availability and behaviour of nmcli connection migrate depend on NetworkManager version. Back up both profile directories and inspect the result before deleting the old file.

Configure DHCP with NetworkManager

Create a DHCP profile:

# nmcli connection add type ethernet ifname enp1s0 con-name LAN-DHCP \
  ipv4.method auto ipv6.method auto
# nmcli connection up LAN-DHCP

Convert an existing static profile to DHCP and clear manual IPv4 fields:

# nmcli connection modify LAN \
  ipv4.method auto \
  ipv4.addresses “” \
  ipv4.gateway “” \
  ipv4.routes “”
# nmcli connection up LAN

Use DHCP for address and routes but ignore DHCP-provided DNS:

# nmcli connection modify LAN \
  ipv4.method auto \
  ipv4.ignore-auto-dns yes \
  ipv4.dns “192.0.2.53 192.0.2.54” \
  ipv4.dns-search example.com
# nmcli connection up LAN

Ignore DHCP-provided default routes while retaining the address:

# nmcli connection modify LAN ipv4.never-default yes
# nmcli connection up LAN

Set route priority for a DHCP profile:

# nmcli connection modify LAN ipv4.route-metric 100 ipv6.route-metric 100
# nmcli connection up LAN

Renewing through NetworkManager generally requires profile reactivation:

# nmcli connection down LAN && nmcli connection up LAN

This interrupts traffic. On a remote system, use console access or arrange rollback. RHEL 10 removed the standalone dhclient utility; NetworkManager’s internal DHCP client is the supported path. Older releases may still contain dhclient, but mixing it with a NetworkManager-managed interface can create conflicting leases and addresses.

DHCP with Nmstate

interfaces:
  – name: enp1s0
    type: ethernet
    state: up
    ipv4:
      enabled: true
      dhcp: true
      auto-dns: false
      auto-routes: true
      auto-gateway: true
    ipv6:
      enabled: true
      dhcp: true
      autoconf: true
dns-resolver:
  config:
    server:
      – 192.0.2.53
      – 192.0.2.54

Apply and inspect:

# nmstatectl apply /root/lan-dhcp.yml
$ nmstatectl show enp1s0
$ nmcli -f GENERAL,IP4,IP6,DHCP4,DHCP6 device show enp1s0

Legacy ifcfg DHCP – RHEL/Oracle Linux 8 Only

TYPE=Ethernet
DEVICE=enp1s0
NAME=LAN-DHCP
ONBOOT=yes
BOOTPROTO=dhcp
PEERDNS=yes
DEFROUTE=yes
IPV6INIT=yes
IPV6_AUTOCONF=yes

Apply through NetworkManager:

# nmcli connection reload
# nmcli connection up LAN-DHCP

Verify a DHCP Lease

$ ip -br address show dev enp1s0
$ ip route show dev enp1s0
$ ip -6 route show dev enp1s0
$ nmcli -f GENERAL,IP4,IP6,DHCP4,DHCP6 device show enp1s0
$ journalctl -b -u NetworkManager | grep -Ei ‘dhcp|lease|bound|renew’

A valid lease can supply an address and prefix, lease lifetime, default and classless routes, DNS servers, search domains, NTP servers, and MTU. Missing DNS does not prove that the address lease failed; inspect each field independently.

Duplicate-Address Checks

Probe an intended IPv4 address before assigning it:

# arping -D -I enp1s0 -c 3 192.0.2.10

After assignment, announce it to update nearby ARP caches:

# arping -A -I enp1s0 -c 3 192.0.2.10

Watch duplicate-address detection and neighbour messages:

# journalctl -k -b | grep -Ei ‘duplicate|dad|address conflict’
$ ip -6 address show dev enp1s0 tentative

No ARP reply does not prove an address is free when VLANs, filtering, sleeping systems, proxy ARP, or network isolation are involved. Confirm with IP address management or DHCP reservation records.

VLANs and IEEE 802.1Q Tagging

A VLAN creates a separate Layer 2 broadcast domain by adding an IEEE 802.1Q tag containing a VLAN ID. A switch access port normally carries one untagged VLAN. A trunk carries one or more tagged VLANs. The host parent and switch port must agree on tagging, native VLAN, allowed IDs, MTU, and link aggregation membership.

Temporary VLAN Interface

Create VLAN 100 on enp1s0:

# ip link add link enp1s0 name vlan100 type vlan id 100
# ip address add 192.0.2.10/24 dev vlan100
# ip link set dev enp1s0 up
# ip link set dev vlan100 up
$ ip -d link show vlan100
$ ip -br address show vlan100

Delete it:

# ip link delete vlan100

Persistent VLAN with NetworkManager

# nmcli connection add type vlan con-name vlan100 ifname vlan100 \
  vlan.parent enp1s0 vlan.id 100
# nmcli connection modify vlan100 \
  ipv4.method manual ipv4.addresses 192.0.2.10/24 \
  ipv4.gateway 192.0.2.1 \
  ipv4.dns “192.0.2.53 192.0.2.54” \
  ipv6.method disabled
# nmcli connection up vlan100

For a VLAN without a default route:

# nmcli connection modify vlan100 ipv4.never-default yes
# nmcli connection up vlan100

Create a VLAN on a bond by using bond0 as the parent:

# nmcli connection add type vlan con-name bond0.100 ifname bond0.100 \
  vlan.parent bond0 vlan.id 100 \
  ipv4.method manual ipv4.addresses 192.0.2.10/24
# nmcli connection up bond0.100

Persistent VLAN with Nmstate

interfaces:
  – name: enp1s0
    type: ethernet
    state: up
  – name: vlan100
    type: vlan
    state: up
    vlan:
      base-iface: enp1s0
      id: 100
    ipv4:
      enabled: true
      dhcp: false
      address:
        – ip: 192.0.2.10
          prefix-length: 24
routes:
  config:
    – destination: 0.0.0.0/0
      next-hop-interface: vlan100
      next-hop-address: 192.0.2.1
# nmstatectl apply /root/vlan100.yml
$ nmstatectl show vlan100

Legacy ifcfg VLAN – RHEL/Oracle Linux 8 Only

Example /etc/sysconfig/network-scripts/ifcfg-enp1s0.100:

TYPE=Vlan
DEVICE=enp1s0.100
NAME=vlan100
ONBOOT=yes
BOOTPROTO=none
VLAN=yes
PHYSDEV=enp1s0
VLAN_ID=100
IPADDR=192.0.2.10
PREFIX=24
GATEWAY=192.0.2.1
DNS1=192.0.2.53
# nmcli connection reload
# nmcli connection up vlan100

VLAN Verification and Troubleshooting

$ ip -d link show type vlan
$ nmcli -f NAME,TYPE,DEVICE connection show –active
$ bridge vlan show
# tcpdump -eni enp1s0 vlan 100
# tcpdump -ni vlan100 ‘arp or icmp or icmp6’

  • No tagged frames leaving the parent usually means the VLAN profile is inactive, traffic is not routed through it, or a bridge/bond relationship is wrong.
  • Tagged frames leaving with no return traffic point to the switch trunk, allowed VLAN list, native VLAN, remote access port, or remote host.
  • Untagged service traffic belongs on the parent or a bridge access port, not an 802.1Q subinterface.
  • A VLAN over a bond must be attached to the bond, not independently to each bond member.
  • Hardware VLAN offload can make a capture on the VLAN interface look different from a capture on the parent. Capture both when diagnosing tag placement.

Failover IP Address over Two Interfaces

For one host with two links to the same Layer 2 network, use an active-backup bond. Assign the IP to bond0, not separately to both member interfaces. The active member carries traffic and a standby takes over when link monitoring reports failure.

A floating service IP between two separate hosts is different. That normally uses VRRP/keepalived, Pacemaker, a cloud floating-IP mechanism, or a load balancer. Both patterns are shown, but they solve different failure domains.

Active-Backup Bond with NetworkManager

Create the bond and ports with current controller/port terminology:

# nmcli connection add type bond con-name bond0 ifname bond0 \
  bond.options “mode=active-backup,miimon=100,primary=enp1s0,num_grat_arp=3”
# nmcli connection add type ethernet port-type bond con-name bond0-port1 \
  ifname enp1s0 controller bond0
# nmcli connection add type ethernet port-type bond con-name bond0-port2 \
  ifname enp2s0 controller bond0
# nmcli connection modify bond0 \
  ipv4.method manual ipv4.addresses 192.0.2.10/24 \
  ipv4.gateway 192.0.2.1 ipv4.dns “192.0.2.53 192.0.2.54” \
  ipv6.method disabled
# nmcli connection up bond0

Older NetworkManager versions use equivalent master bond0 slave-type bond syntax for the port profiles.

Inspect the relationship:

$ nmcli device status
$ nmcli connection show –active
$ ip -d link show bond0
$ cat /proc/net/bonding/bond0

Active-Backup Bond with Nmstate

interfaces:
  – name: enp1s0
    type: ethernet
    state: up
  – name: enp2s0
    type: ethernet
    state: up
  – name: bond0
    type: bond
    state: up
    link-aggregation:
      mode: active-backup
      options:
        miimon: 100
        primary: enp1s0
        num_grat_arp: 3
      port:
        – enp1s0
        – enp2s0
    ipv4:
      enabled: true
      dhcp: false
      address:
        – ip: 192.0.2.10
          prefix-length: 24
routes:
  config:
    – destination: 0.0.0.0/0
      next-hop-interface: bond0
      next-hop-address: 192.0.2.1
# nmstatectl apply /root/bond-active-backup.yml
$ cat /proc/net/bonding/bond0

Legacy ifcfg Active-Backup Bond – RHEL/Oracle Linux 8 Only

ifcfg-bond0:

TYPE=Bond
DEVICE=bond0
NAME=bond0
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS=”mode=active-backup miimon=100 primary=enp1s0 num_grat_arp=3″
IPADDR=192.0.2.10
PREFIX=24
GATEWAY=192.0.2.1
DNS1=192.0.2.53

ifcfg-enp1s0:

TYPE=Ethernet
DEVICE=enp1s0
NAME=bond0-port1
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes

Create the corresponding ifcfg-enp2s0, reload, and activate:

# nmcli connection reload
# nmcli connection up bond0

Test Active-Backup Failover

  1. Start a continuous ping through bond0.
  2. Confirm the currently active member in /proc/net/bonding/bond0.
  3. Disable the active switch port or administratively lower the member.
  4. Confirm the standby becomes active and observe packet loss.
  5. Restore the member and verify the configured primary re-selection policy.

$ watch -n 1 cat /proc/net/bonding/bond0
$ ping -I bond0 192.0.2.1
# ip link set enp1s0 down
# ip link set enp1s0 up

If failover changes the active member but traffic does not resume, inspect gratuitous ARP, switch port security, VLAN parity, MAC movement limits, neighbour caches, and upstream asymmetric filtering.

Floating IP Between Two Hosts with keepalived

Example requirement: node1 and node2 share service address 192.0.2.100/24 on enp1s0. Install keepalived on both:

# dnf install -y keepalived
# firewall-cmd –permanent –add-protocol=vrrp
# firewall-cmd –reload

Example /etc/keepalived/keepalived.conf on the preferred node:

global_defs {
    router_id NODE1
}

vrrp_instance VI_1 {
    state BACKUP
    interface enp1s0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ReplaceMe
    }
    virtual_ipaddress {
        192.0.2.100/24 dev enp1s0
    }
}

On the second node, use a lower priority such as 100 and a unique router_id. Start and verify:

# systemctl enable –now keepalived
$ systemctl status keepalived
$ ip address show dev enp1s0
# journalctl -fu keepalived

For unicast VRRP on networks that do not pass multicast, configure explicit unicast_src_ip and unicast_peer addresses on both nodes. Protect the configuration, use a stronger operational security design than the simple example password, and test split-brain behaviour.

LACP / IEEE 802.3ad Aggregation

An 802.3ad bond negotiates an aggregation group with the switch using LACP. It provides redundancy and can spread multiple flows across links. A single flow is normally hashed to one member and therefore usually cannot exceed one member’s line rate.

The switch ports must be in the same compatible LACP port-channel. Independent switches require a vendor-supported multi-chassis aggregation technology. The VLAN list, native VLAN, MTU, speed, and duplex must match on every member.

Version note: Network teaming is deprecated in RHEL 9 and Oracle Linux 9. The team driver and teamd are removed in RHEL 10. Use kernel bonding for new designs and migrate teams before upgrading.

LACP Bond with NetworkManager

# nmcli connection add type bond con-name bond0 ifname bond0 \
  bond.options “mode=802.3ad,miimon=100,lacp_rate=fast,xmit_hash_policy=layer3+4,min_links=1”
# nmcli connection add type ethernet port-type bond con-name bond0-port1 \
  ifname enp1s0 controller bond0
# nmcli connection add type ethernet port-type bond con-name bond0-port2 \
  ifname enp2s0 controller bond0
# nmcli connection modify bond0 \
  ipv4.method manual ipv4.addresses 192.0.2.10/24 \
  ipv4.gateway 192.0.2.1 ipv4.dns “192.0.2.53 192.0.2.54”
# nmcli connection up bond0

LACP Bond with Nmstate

interfaces:
  – name: enp1s0
    type: ethernet
    state: up
  – name: enp2s0
    type: ethernet
    state: up
  – name: bond0
    type: bond
    state: up
    link-aggregation:
      mode: 802.3ad
      options:
        miimon: 100
        lacp_rate: fast
        xmit_hash_policy: layer3+4
        min_links: 1
      port:
        – enp1s0
        – enp2s0
    ipv4:
      enabled: true
      dhcp: false
      address:
        – ip: 192.0.2.10
          prefix-length: 24
# nmstatectl apply /root/bond-lacp.yml

Legacy ifcfg LACP Bond – RHEL/Oracle Linux 8 Only

TYPE=Bond
DEVICE=bond0
NAME=bond0
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS=”mode=802.3ad miimon=100 lacp_rate=fast xmit_hash_policy=layer3+4 min_links=1″
IPADDR=192.0.2.10
PREFIX=24
GATEWAY=192.0.2.1

Member profiles use MASTER=bond0 and SLAVE=yes, as shown for active-backup.

Verify LACP State and Traffic Distribution

$ cat /proc/net/bonding/bond0
$ ip -s -d link show bond0
$ ip -s link show enp1s0
$ ip -s link show enp2s0
$ ethtool enp1s0
$ ethtool enp2s0

Healthy members in one aggregator normally show compatible actor and partner keys, the same partner system MAC, and collecting/distributing state. Exercise multiple flows rather than one flow:

$ iperf3 -c 198.51.100.20 -P 8
$ watch -n 1 ‘ip -s link show enp1s0; ip -s link show enp2s0’

Common LACP failures:

Symptom

Likely cause

One member never aggregates

Switch port not in the channel, mismatched key, speed/duplex, or LACP mode.

Both members up but traffic one-way

VLAN or native VLAN mismatch, switch hashing or port-channel inconsistency.

Only one member carries a single test

Expected per-flow hashing; use several source/destination/port combinations.

Bond goes down when one member fails

min_links too high, switch removes the aggregator, or monitoring is wrong.

Frequent member churn

Physical errors, optics, LACP timer mismatch, driver resets, or switch instability.

Routing

Linux normally chooses the longest prefix match, then considers preference and metric among otherwise equivalent routes. Connected routes are created from interface prefixes. Policy rules can select additional routing tables based on source, destination, incoming interface, firewall mark, or other attributes.

List All Routes and Rules

$ ip -4 route show
$ ip -6 route show
$ ip route show table all
$ ip -6 route show table all
$ ip rule show
$ ip -6 rule show
$ ip route get 198.51.100.25
$ ip route get 198.51.100.25 from 192.0.2.10

Filter by interface, protocol, or default:

$ ip route show dev enp1s0
$ ip route show proto dhcp
$ ip route show default
$ nmcli -f IP4.ROUTE,IP6.ROUTE device show enp1s0

Temporary Default Route – Add, Change, and Delete

# ip route add default via 192.0.2.1 dev enp1s0 metric 100
# ip route replace default via 192.0.2.254 dev enp1s0 metric 100
# ip route del default via 192.0.2.254 dev enp1s0

IPv6 through a link-local next hop:

# ip -6 route add default via fe80::1 dev enp1s0 metric 100
# ip -6 route del default via fe80::1 dev enp1s0

Temporary Static Route – Add, Change, and Delete

# ip route add 198.51.100.0/24 via 192.0.2.254 dev enp1s0 metric 50
# ip route change 198.51.100.0/24 via 192.0.2.253 dev enp1s0 metric 50
# ip route replace 198.51.100.0/24 via 192.0.2.253 dev enp1s0 metric 50
# ip route del 198.51.100.0/24 via 192.0.2.253 dev enp1s0

Special routes:

# ip route add blackhole 203.0.113.0/24
# ip route add unreachable 198.51.100.128/25
# ip route add 198.51.100.25/32 dev enp1s0 scope link
# ip route del blackhole 203.0.113.0/24

ip route replace is useful in idempotent scripts because it creates an absent route and replaces an existing matching destination. Always check ip route get after a change to confirm the selected source, table, device, and next hop.

Permanent Default Route with NetworkManager

Set or replace the gateway on a static profile:

# nmcli connection modify LAN ipv4.gateway 192.0.2.1
# nmcli connection modify LAN ipv4.route-metric 100
# nmcli connection up LAN

Prevent a profile from installing any default route:

# nmcli connection modify BACKUP-LAN ipv4.never-default yes ipv6.never-default yes
# nmcli connection up BACKUP-LAN

For DHCP profiles, lower metrics are preferred:

# nmcli connection modify WIRED ipv4.route-metric 100
# nmcli connection modify WIFI ipv4.route-metric 600
# nmcli connection up WIRED
# nmcli connection up WIFI
$ ip route show default

Permanent Static Routes with NetworkManager

Add a route to an existing profile:

# nmcli connection modify LAN \
  +ipv4.routes “198.51.100.0/24 192.0.2.254 50”
# nmcli connection up LAN

Add several routes in one property:

# nmcli connection modify LAN ipv4.routes \
  “198.51.100.0/24 192.0.2.254 50, 203.0.113.25/32 192.0.2.253 75”
# nmcli connection up LAN

Remove one exact route:

# nmcli connection modify LAN \
  -ipv4.routes “198.51.100.0/24 192.0.2.254 50”
# nmcli device reapply enp1s0

Inspect persistent and active routes:

$ nmcli -f ipv4.gateway,ipv4.routes,ipv4.route-metric connection show LAN
$ nmcli -f IP4.ROUTE device show enp1s0
$ ip route show

Permanent Routes with Nmstate

routes:
  config:
    – destination: 0.0.0.0/0
      next-hop-interface: enp1s0
      next-hop-address: 192.0.2.1
      metric: 100
    – destination: 198.51.100.0/24
      next-hop-interface: enp1s0
      next-hop-address: 192.0.2.254
      metric: 50
# nmstatectl apply /root/routes.yml
$ nmstatectl show
$ ip route show

Legacy Static Route Files – RHEL/Oracle Linux 8 Only

A route file corresponding to ifcfg-enp1s0 can use command-style entries in /etc/sysconfig/network-scripts/route-enp1s0:

198.51.100.0/24 via 192.0.2.254 dev enp1s0 metric 50
203.0.113.25/32 via 192.0.2.253 dev enp1s0 metric 75

IPv6 routes can be placed in route6-enp1s0. Reload and reactivate through NetworkManager:

# nmcli connection reload
# nmcli connection up LAN

Do not introduce new legacy route files on RHEL/Oracle Linux 9 or 10. Store routes in keyfile profiles through nmcli, Nmstate, the RHEL system role, or equivalent automation.

Multiple Default Routes and Metrics

Temporary wired-primary and wireless-backup example:

# ip route replace default via 192.0.2.1 dev enp1s0 metric 100
# ip route replace default via 198.51.100.1 dev wlp2s0 metric 600
$ ip route show default
$ ip route get 203.0.113.25

Persistent profile metrics:

# nmcli connection modify WIRED ipv4.route-metric 100 ipv6.route-metric 100
# nmcli connection modify WIFI ipv4.route-metric 600 ipv6.route-metric 600
# nmcli connection up WIRED
# nmcli connection up WIFI

Two defaults do not automatically guarantee application-level failover. Existing TCP sessions normally break when source address or path changes. DNS, VPN policy, firewall state, reverse-path filtering, and cloud routing can also affect failover.

Policy Routing

Temporary source-based routing through table 100:

# ip route add table 100 192.0.2.0/24 dev enp1s0 src 192.0.2.10
# ip route add table 100 default via 192.0.2.1 dev enp1s0
# ip rule add priority 100 from 192.0.2.10/32 table 100
$ ip rule show
$ ip route show table 100
$ ip route get 203.0.113.25 from 192.0.2.10

Remove in reverse order:

# ip rule del priority 100
# ip route flush table 100

Persistent NetworkManager route and rule example:

# nmcli connection modify LAN \
  +ipv4.routes “0.0.0.0/0 192.0.2.1 table=100”
# nmcli connection modify LAN \
  +ipv4.routing-rules “priority 100 from 192.0.2.10/32 table 100”
# nmcli connection up LAN

Inspect:

$ nmcli -f ipv4.routes,ipv4.routing-rules connection show LAN
$ ip rule show
$ ip route show table 100

Warning: Policy routing can create asymmetric forward and return paths. Stateful firewalls, strict reverse-path filtering, load balancers, and upstream routers may drop otherwise valid traffic. Test both directions and every source address.

Enable IP Forwarding

Temporary router settings:

# sysctl -w net.ipv4.ip_forward=1
# sysctl -w net.ipv6.conf.all.forwarding=1

Persist in /etc/sysctl.d/60-router.conf:

net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
# sysctl –system
$ sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding

Forwarding does not create a firewall forward policy or NAT. Configure those separately and keep ICMP/ICMPv6 types required for error reporting, neighbour discovery, and path-MTU discovery.

Host Naming and Naming Services

Linux name resolution is broader than DNS. Most applications use the GNU C Library Name Service Switch (NSS), which can consult local files, DNS, systemd modules, mDNS, SSSD, LDAP, and other sources according to /etc/nsswitch.conf. Use getent to test the same lookup path that normal applications use.

Display and Configure the Host Name

$ hostnamectl status
$ hostname
$ hostname –fqdn
$ cat /etc/hostname

Set a persistent fully qualified host name:

# hostnamectl set-hostname web01.example.com
$ hostnamectl status

Add a deliberate local mapping in /etc/hosts when required:

127.0.0.1       localhost localhost.localdomain
::1             localhost localhost.localdomain
192.0.2.10      web01.example.com web01

Test through NSS:

$ getent hosts web01
$ getent ahosts web01.example.com
$ getent hosts 192.0.2.10

hostname –fqdn depends on name service data and is not simply the text stored in /etc/hostname. Confirm both the name and the address returned by getent.

Inspect Name Service Switch Order

$ grep -E ‘^(hosts|networks|passwd|group|netgroup|automount):’ /etc/nsswitch.conf
$ getent hosts app.example.com
$ getent passwd alice
$ getent netgroup engineering

A simple host lookup order is:

hosts:      files dns myhostname

Actual installations can contain resolve, mdns4_minimal, mymachines, sss, or other modules. Do not replace the line blindly. Desktop discovery, containers, SSSD, and local policy can depend on the existing order.

RHEL and Oracle Linux systems using authselect can manage selected NSS and PAM settings. Inspect before editing identity-related entries:

$ authselect current
$ authselect check

DNS Client Configuration and Management

By default, NetworkManager receives DNS information from static profiles, DHCP, VPNs, and other connections and writes resolver configuration. /etc/resolv.conf is often NetworkManager-managed. It can also be a symbolic link when systemd-resolved, dnsmasq, or another local resolver is deliberately enabled.

Inspect Resolver Configuration and Test Name Resolution

$ ls -l /etc/resolv.conf
$ readlink -f /etc/resolv.conf
$ cat /etc/resolv.conf
$ nmcli -f IP4.DNS,IP4.DOMAIN,IP6.DNS,IP6.DOMAIN device show
$ nmcli -f ipv4.dns,ipv4.dns-search,ipv4.ignore-auto-dns,ipv4.dns-priority \
  connection show LAN

Test the application/NSS path:

$ getent ahosts app.example.com
$ getent hosts app.example.com
$ getent hosts 192.0.2.25

Test DNS directly:

$ dig app.example.com A
$ dig app.example.com AAAA
$ dig -x 192.0.2.25
$ dig @192.0.2.53 app.example.com A +noall +answer
$ dig @192.0.2.53 example.com SOA +multiline
$ dig +trace example.com

getent can return local /etc/hosts or SSSD data and reflects NSS ordering. dig bypasses NSS and interrogates DNS, making it better for flags, TTLs, authority data, DNSSEC details, and testing a specific server.

Configure Static DNS Servers with NetworkManager

Use only the configured DNS servers and ignore DHCP-provided servers:

# nmcli connection modify LAN \
  ipv4.ignore-auto-dns yes \
  ipv4.dns “192.0.2.53 192.0.2.54” \
  ipv4.dns-search “example.com corp.example.com” \
  ipv6.ignore-auto-dns yes \
  ipv6.dns “2001:db8:1::53”
# nmcli connection up LAN

Add or remove one DNS server without replacing the whole list:

# nmcli connection modify LAN +ipv4.dns 192.0.2.55
# nmcli connection modify LAN -ipv4.dns 192.0.2.55
# nmcli device reapply enp1s0

Return to DHCP-provided DNS:

# nmcli connection modify LAN \
  ipv4.ignore-auto-dns no ipv4.dns “” ipv4.dns-search “” \
  ipv6.ignore-auto-dns no ipv6.dns “” ipv6.dns-search “”
# nmcli connection up LAN

DNS Priority and Split-DNS Behaviour

When several active profiles provide DNS servers, NetworkManager uses DNS priorities and connection type to order them. A lower numeric priority is preferred:

# nmcli connection modify LAN ipv4.dns-priority 50 ipv6.dns-priority 50
# nmcli connection modify BACKUP-LAN ipv4.dns-priority 200 ipv6.dns-priority 200

A negative DNS priority can exclude DNS from profiles with higher numerical priority. Use negative values only after testing VPN and split-DNS behaviour; they can unexpectedly hide otherwise valid resolvers.

Search domains are appended to short names. Route-only domains are most useful when NetworkManager is integrated with a resolver that supports per-link routing, such as systemd-resolved. A leading tilde marks a route-only domain:

# nmcli connection modify CORP-VPN ipv4.dns-search ‘~corp.example.com’

On the default direct /etc/resolv.conf path, per-link split DNS is limited because traditional resolver files contain one global ordered server list. Use an approved local resolver or VPN integration when true split DNS is required.

Optional systemd-resolved Integration

First check whether it is installed and active:

$ systemctl status systemd-resolved
$ resolvectl status

A controlled NetworkManager integration normally requires the NetworkManager DNS mode and an appropriate /etc/resolv.conf symlink. Example /etc/NetworkManager/conf.d/20-resolved.conf:

[main]
dns=systemd-resolved

Apply during a maintenance window:

# systemctl enable –now systemd-resolved
# ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# systemctl restart NetworkManager
$ resolvectl status

Do not make this change casually on production hosts. VPN software, local caching resolvers, container runtimes, and security policy can expect a different resolver ownership model. Back up the original file and configuration.

When systemd-resolved is active:

$ resolvectl query app.example.com
# resolvectl flush-caches
$ resolvectl statistics

Manual /etc/resolv.conf Configuration

A minimal static file looks like:

search example.com
nameserver 192.0.2.53
nameserver 192.0.2.54
options timeout:2 attempts:2

However, NetworkManager can overwrite it. Prefer profile properties. If a specific architecture requires NetworkManager not to manage the file, configure that deliberately in /etc/NetworkManager/NetworkManager.conf and document the new owner. Do not use chattr +i /etc/resolv.conf as a routine fix; it hides ownership problems and can break DHCP, VPN, and automation.

DNS Troubleshooting Sequence

$ getent ahosts app.example.com
$ cat /etc/resolv.conf
$ nmcli -f IP4.DNS,IP4.DOMAIN,IP6.DNS,IP6.DOMAIN device show
$ ip route get 192.0.2.53
$ ping -c 2 192.0.2.53
$ nc -vz -w 3 192.0.2.53 53
$ dig @192.0.2.53 app.example.com A
$ dig @192.0.2.53 app.example.com A +tcp
# tcpdump -ni any ‘port 53’

Interpret common responses:

Result

Meaning

NXDOMAIN

The queried name does not exist according to the server.

SERVFAIL

Server-side validation, delegation, forwarding, or upstream failure.

REFUSED

Server policy refuses the query or recursion.

Timeout over UDP but TCP works

Fragmentation, EDNS, firewall, or UDP path issue.

dig works but getent fails

NSS order, resolver ownership, search domain, or application lookup difference.

One server works, another fails

Profile ordering, server outage, routing, ACL, or split-DNS error.

NTP Client Configuration and Management

Accurate time is required for TLS validation, Kerberos, LDAP, distributed databases, logs, cluster decisions, monitoring, and incident correlation. Chrony is the standard client and server implementation on supported RHEL and Oracle Linux releases.

Install, Enable, and Inspect Chrony

# dnf install -y chrony
# systemctl enable –now chronyd
$ systemctl status chronyd
$ timedatectl status
$ chronyc tracking
$ chronyc sources -v
$ chronyc sourcestats -v
$ chronyc activity

Important indicators:

Field

Interpretation

Leap status Normal

The clock is synchronized or usable.

Reference ID

Current selected time source.

Stratum

Distance from a reference clock; lower is not automatically better.

System time

Current offset between system and corrected clock.

Last offset / RMS offset

Recent and long-term error.

* in sources

Selected source.

+

Acceptable combined source.

Acceptable but not currently combined.

?

Unreachable, unselectable, or insufficient samples.

x

Source judged false.

Configure Chrony Servers or Pools

Back up /etc/chrony.conf, then use approved sources:

server ntp1.example.com iburst
server ntp2.example.com iburst
pool pool.example.com iburst maxsources 4

makestep 1.0 3
rtcsync
driftfile /var/lib/chrony/drift
logdir /var/log/chrony

Restart and verify:

# chronyd -Q -f /etc/chrony.conf
# systemctl restart chronyd
$ chronyc sources -v
$ chronyc tracking

chronyd -Q measures and reports the offset without setting the clock. Use chronyd -q carefully because it sets the clock once and exits; it can conflict with the running service.

Force a short burst of measurements and step a large offset when policy allows:

# chronyc burst 4/4
# chronyc makestep

A time step can disturb databases, authentication, scheduled work, and monotonicity assumptions. Prefer gradual correction on established production systems unless the offset is operationally unacceptable.

Network Time Security and Client Firewalling

When the installed Chrony version and server support Network Time Security:

server nts.example.com iburst nts

NTP normally uses UDP port 123. NTS key exchange normally uses TCP port 4460 in addition to NTP. A client usually needs outbound access and established return traffic rather than an inbound server rule.

Test reachability and packet flow:

$ getent ahosts ntp1.example.com
$ ip route get 192.0.2.123
# tcpdump -ni any ‘udp port 123 or tcp port 4460’
$ chronyc sources -v

Chrony and NetworkManager Events

NetworkManager dispatcher integration can mark network sources online and offline as interfaces change. Inspect the dispatcher and service logs:

$ ls -l /etc/NetworkManager/dispatcher.d/20-chrony* /usr/lib/NetworkManager/dispatcher.d/20-chrony* 2>/dev/null
$ journalctl -b -u NetworkManager -u chronyd
$ chronyc activity

If a source remains offline after configuring links outside NetworkManager, use:

# chronyc online

NTP Troubleshooting

$ timedatectl status
$ chronyc tracking
$ chronyc sources -v
$ chronyc sourcestats -v
$ journalctl -b -u chronyd
$ getent ahosts ntp1.example.com
$ ip route get 192.0.2.123
# tcpdump -ni any udp port 123

Common causes of ? sources include DNS failure, no route, firewall filtering, server ACLs, a source that is not serving time, a very large initial offset, or an offline state. TLS or NTS failures can also result from an incorrect system clock or missing CA trust.

LDAP Client Configuration and Management

SSSD is the preferred client integration layer for LDAP and many identity environments. It provides NSS and PAM integration, caching, failover, access control, TLS support, and diagnostic tools. For Active Directory or Red Hat Identity Management, use the appropriate AD or IPA provider rather than treating those environments as generic LDAP when possible.

Test Directory Connectivity Before NSS/PAM Integration

Install client tools and test DNS, routing, TCP, TLS, and a base search first:

# dnf install -y openldap-clients
$ getent ahosts ldap01.example.com
$ ip route get 192.0.2.60
$ nc -vz -w 3 ldap01.example.com 389
$ nc -vz -w 3 ldap01.example.com 636
$ openssl s_client -connect ldap01.example.com:636 -servername ldap01.example.com -showcerts </dev/null
$ ldapsearch -x -H ldaps://ldap01.example.com \
  -b ‘dc=example,dc=com’ -s base ‘(objectClass=*)’

For StartTLS on port 389:

$ ldapsearch -x -H ldap://ldap01.example.com -ZZ \
  -b ‘dc=example,dc=com’ -s base ‘(objectClass=*)’

Do not continue to PAM integration until the certificate name, CA chain, DNS, and simple LDAP query are correct.

Install SSSD and Select the Authentication Profile

# dnf install -y sssd sssd-ldap sssd-tools oddjob oddjob-mkhomedir openldap-clients
$ authselect current
# authselect select sssd with-mkhomedir –force
# systemctl enable –now oddjobd

Warning: authselect –force can overwrite unsupported manual PAM/NSS changes. Back up /etc/pam.d, /etc/nsswitch.conf, and the current authselect profile before replacing an established authentication stack.

Trust the LDAP Certificate Authority

Copy the issuing CA certificate into the system trust store:

# cp example-root-ca.pem /etc/pki/ca-trust/source/anchors/
# update-ca-trust
$ trust list | grep -A3 -i ‘Example Root CA’

Re-test the TLS connection using the server’s real DNS name. Do not disable certificate verification as a permanent workaround.

Configure SSSD for LDAP

Example /etc/sssd/sssd.conf using LDAPS and anonymous or server-authorized searches:

[sssd]
config_file_version = 2
services = nss, pam
domains = example.com

[nss]
homedir_substring = /home

[pam]

[domain/example.com]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
access_provider = ldap

ldap_uri = ldaps://ldap01.example.com, ldaps://ldap02.example.com
ldap_search_base = dc=example,dc=com
ldap_schema = rfc2307bis
ldap_tls_cacert = /etc/pki/tls/certs/ca-bundle.crt
ldap_tls_reqcert = demand

ldap_user_search_base = ou=People,dc=example,dc=com
ldap_group_search_base = ou=Groups,dc=example,dc=com
ldap_access_filter = (memberOf=cn=linux-login,ou=Groups,dc=example,dc=com)

cache_credentials = true
enumerate = false
entry_cache_timeout = 600
offline_credentials_expiration = 7
fallback_homedir = /home/%u
default_shell = /bin/bash

Protect, validate, and start:

# chown root:root /etc/sssd/sssd.conf
# chmod 600 /etc/sssd/sssd.conf
# sssctl config-check
# systemctl enable –now sssd
$ systemctl status sssd

For StartTLS, use LDAP URIs and require TLS:

ldap_uri = ldap://ldap01.example.com, ldap://ldap02.example.com
ldap_id_use_start_tls = true
ldap_tls_reqcert = demand

A directory that requires a search bind can use ldap_default_bind_dn and an authentication token. The token is stored in the protected SSSD file, so use the least-privileged read-only account and a secret-management process. Avoid embedding privileged directory credentials.

Verify LDAP Identity and Authentication Paths

$ getent passwd alice
$ getent group linux-admins
$ id alice
$ sssctl user-checks alice
$ sssctl domain-status example.com
$ authselect check

Check home-directory creation and PAM without exposing a production password in logs. A controlled console login is preferable to repeated remote tests.

Clear one cached entry after a directory correction:

# sss_cache -u alice
# sss_cache -g linux-admins

Clear the entire cache only when necessary:

# sss_cache -E

Clearing all cached identity data increases directory load and removes offline records. Prefer the narrowest operation.

LDAP and SSSD Logs

$ journalctl -b -u sssd
# ls -l /var/log/sssd/
# tail -f /var/log/sssd/sssd_example.com.log
$ sssctl config-check
$ sssctl domain-status example.com

Increase SSSD debug level for a short diagnostic window by adding debug_level = 6 to the affected domain, restarting SSSD, reproducing the issue, and then removing the setting. High levels can log sensitive metadata and create large files.

Symptom

Common cause

Focused check

ldapsearch works but getent fails

NSS/SSSD profile, cache, service, or search-base issue

authselect check, sssctl config-check, SSSD logs.

Certificate verification fails

Missing CA, wrong DNS name, expired certificate, or wrong clock

openssl s_client, trust store, timedatectl.

User resolves but login fails

PAM, access filter, shell, password policy, or account lock

sssctl user-checks, secure journal, directory policy.

Intermittent long delays

DNS ordering, unreachable URI, referrals, enumeration, or failover timeout

Test each server directly; keep enumerate=false.

Offline login fails

Credentials not previously cached or cache expired

Complete one online login and review offline policy.

Duplicate or inconsistent IDs

Multiple identity sources or conflicting uidNumber/gidNumber

getent, SSSD domains, local files, directory data.

NFS Client Configuration and Management

NFS mounts server-exported file systems into the local directory tree. NFSv4 normally uses TCP port 2049 and has a cleaner firewall model than older versions. Export permissions, security flavour, identity mapping, and file ownership are controlled by the server and directory environment as well as the network path.

Install NFS Client Utilities and Discover Exports

# dnf install -y nfs-utils
$ showmount -e nfs01.example.com
$ rpcinfo -p nfs01.example.com
$ nc -vz -w 3 nfs01.example.com 2049

showmount uses the older mount protocol and can fail or return nothing against a pure NFSv4 server even when NFSv4 mounts work. Confirm the NFSv4 pseudo-filesystem path with the server administrator.

Mount and Unmount an NFS File System

# mkdir -p /mnt/projects
# mount -t nfs4 -o vers=4.2,proto=tcp nfs01.example.com:/projects /mnt/projects
$ findmnt /mnt/projects
$ nfsstat -m
# umount /mnt/projects

Test access and numeric ownership:

$ stat -f /mnt/projects
$ ls -ldn /mnt/projects
$ touch /mnt/projects/client-write-test && rm /mnt/projects/client-write-test

A successful mount does not prove that UID/GID mapping, SELinux policy, application credentials, or server export permissions are correct.

Persistent NFS Mount in /etc/fstab

An on-demand systemd automount avoids blocking boot when the server or network is unavailable:

nfs01.example.com:/projects  /mnt/projects  nfs4  rw,_netdev,nofail,x-systemd.automount,x-systemd.idle-timeout=600,vers=4.2,proto=tcp  0  0

Activate and test:

# mkdir -p /mnt/projects
# systemctl daemon-reload
# mount -a
$ findmnt /mnt/projects
$ systemctl status mnt-projects.automount

NFS hard mounts are normally preferred for data integrity because operations continue retrying through transient outages. Soft mounts can turn a network interruption into application I/O errors and possible corruption. Use them only with a documented application-specific reason.

Automount Many NFS Paths with autofs

# dnf install -y autofs

Example /etc/auto.master.d/projects.autofs:

/projects  /etc/auto.projects  –timeout=600

Example /etc/auto.projects:

engineering  -fstype=nfs4,rw,vers=4.2  nfs01.example.com:/projects/engineering
finance      -fstype=nfs4,ro,vers=4.2  nfs01.example.com:/projects/finance
# systemctl enable –now autofs
$ ls /projects/engineering
$ mount | grep ‘/projects/’
# journalctl -u autofs -b

Kerberos-Secured NFS

Security flavours krb5, krb5i, and krb5p provide authentication, integrity, and privacy respectively. They require correct forward and reverse DNS, synchronized time, Kerberos configuration, host credentials, and the NFS GSS services.

# systemctl enable –now rpc-gssd
# mount -t nfs4 -o sec=krb5p nfs01.example.com:/secure /mnt/secure
$ nfsstat -m

Troubleshoot the identity and time path before blaming NFS transport:

$ klist
$ getent hosts nfs01.example.com
$ timedatectl status
$ chronyc tracking
# journalctl -b -u rpc-gssd

SELinux and NFS Client Access

SELinux can allow an interactive shell to read an NFS mount while preventing a confined service from using it. Inspect relevant booleans:

$ getsebool -a | grep -i nfs
$ getsebool httpd_use_nfs
$ getsebool virt_use_nfs
$ getsebool use_nfs_home_dirs

Enable only the boolean required by the service:

# setsebool -P httpd_use_nfs on

Investigate denials rather than disabling SELinux:

# ausearch -m AVC,USER_AVC -ts recent
# journalctl -t setroubleshoot –since ‘-30 minutes’

NFS Performance and Troubleshooting

$ nfsstat -m
$ nfsstat -c
$ nfsiostat 1
$ mountstats /mnt/projects
$ ss -tn dst :2049
# tcpdump -ni enp1s0 host nfs01.example.com and port 2049

Find processes blocking an unmount:

# fuser -vm /mnt/projects
# lsof +f — /mnt/projects
# umount /mnt/projects

Common interpretations:

  • Permission denied can mean a wrong export path, client outside the export allow-list, root squashing, a mismatched security flavour, or application identity failure.
  • Unexpected ownership usually indicates numeric UID/GID inconsistency or NFSv4 identity mapping, not packet loss.
  • Stale file handle normally requires the server export or underlying file identity to be corrected; remount only after the server issue is resolved.
  • server not responding requires checking DNS, route, TCP 2049, firewall, loss, and server health.
  • NFSv3 can require additional portmapper, mountd, lockd, and statd ports. Prefer NFSv4 where architecture and compatibility permit.

firewalld, nftables, SELinux, and Network Security

The Linux kernel netfilter framework performs filtering, connection tracking, NAT, and packet modification. On RHEL and Oracle Linux, firewalld is the normal host-firewall manager. It commonly uses nftables as its backend. The nft command is the native low-level interface for administrators who intentionally own the complete ruleset.

Do not manage the same host concurrently with firewalld and the nftables.service persistent ruleset. Firewalld-created nftables objects are normal and should not be mistaken for a second firewall. Choose one configuration owner, then use packet captures, counters, and socket inspection to verify behaviour.

SELinux is separate from the packet firewall. A packet can reach a listening process and still be denied by SELinux, or the firewall can block a port that SELinux permits. Check both layers.

Inspect Existing Firewall and Security State

$ systemctl is-enabled firewalld
$ systemctl is-active firewalld
# firewall-cmd –state
# firewall-cmd –get-default-zone
# firewall-cmd –get-active-zones
# firewall-cmd –list-all
# firewall-cmd –list-all-zones
# nft list ruleset
$ ss -lntup
$ getenforce

Show the zone associated with a NetworkManager profile:

$ nmcli -f connection.id,connection.interface-name,connection.zone connection show LAN

Listening versus permitted: a listening socket does not prove that remote packets are accepted. An allow rule does not prove that a service is running or bound to the expected address. Check ss, firewalld/nftables, SELinux, and packet flow.

Runtime and Permanent firewalld Configuration

Firewalld maintains two configurations:

  • Runtime rules take effect immediately and disappear at reload or reboot.
  • Permanent rules are stored on disk and take effect after reload, restart, or reboot.

Safely test a rule at runtime, then persist it:

# firewall-cmd –zone=public –add-service=http
# firewall-cmd –zone=public –list-all
# firewall-cmd –runtime-to-permanent

Or create the permanent rule and reload:

# firewall-cmd –permanent –zone=public –add-service=http
# firewall-cmd –reload

A reload replaces runtime-only changes with the permanent configuration. Record important runtime changes before reloading.

Enable firewalld Without Losing Remote Access

When firewalld is already running, add the management rule to both runtime and permanent state before changing zones or defaults:

# firewall-cmd –zone=public –add-rich-rule=’rule family=”ipv4″ source address=”192.0.2.0/24″ service name=”ssh” accept’
# firewall-cmd –permanent –zone=public –add-rich-rule=’rule family=”ipv4″ source address=”192.0.2.0/24″ service name=”ssh” accept’
# systemctl enable –now firewalld
# firewall-cmd –zone=public –list-all

When the service is stopped, prepare the permanent configuration offline:

# firewall-offline-cmd –set-default-zone=public
# firewall-offline-cmd –zone=public –add-service=ssh
# systemctl enable –now firewalld
# firewall-cmd –list-all

Warning: A broad predefined ssh service permits SSH from every source in the zone. Replace it with a source-limited rich rule when policy requires restricted administration. Keep the existing session open and test a second login before closing it.

Manage Zones and Interface Assignment

List zones and assign a profile persistently:

# firewall-cmd –get-zones
# nmcli connection modify LAN connection.zone internal
# nmcli connection up LAN
# firewall-cmd –get-active-zones

Assign an interface directly when NetworkManager does not own it:

# firewall-cmd –permanent –zone=internal –change-interface=enp1s0
# firewall-cmd –reload

Prefer the NetworkManager connection.zone property for NetworkManager-managed interfaces so the correct zone follows profile activation.

Common zones include:

Zone

Typical intent

trusted

Accept all traffic; use only for fully trusted paths.

internal

Internal networks with selected services.

public

Untrusted network with explicitly allowed services.

external

Router-facing network, commonly with masquerading.

dmz

Limited services exposed to less-trusted networks.

block

Reject incoming connections except established/related traffic.

drop

Silently drop unsolicited incoming traffic.

Zone names are policy labels, not automatic security guarantees. Inspect the actual services, ports, protocols, sources, forwarding, and rich rules.

List and Manage Services, Ports, and Rules

# firewall-cmd –zone=public –list-services
# firewall-cmd –zone=public –list-ports
# firewall-cmd –zone=public –list-rich-rules
# firewall-cmd –zone=public –list-icmp-blocks
# firewall-cmd –zone=public –query-service=https

Add and remove services or ports:

# firewall-cmd –permanent –zone=public –add-service=https
# firewall-cmd –permanent –zone=public –add-port=8443/tcp
# firewall-cmd –permanent –zone=public –remove-port=8443/tcp
# firewall-cmd –reload

Inspect predefined service definitions:

$ firewall-cmd –get-services
$ firewall-cmd –info-service=ssh
$ ls /usr/lib/firewalld/services/
$ ls /etc/firewalld/services/ 2>/dev/null

Create a custom service for TCP 8443 and UDP 8443:

# firewall-cmd –permanent –new-service=example-app
# firewall-cmd –permanent –service=example-app –set-description=’Example application’
# firewall-cmd –permanent –service=example-app –add-port=8443/tcp
# firewall-cmd –permanent –service=example-app –add-port=8443/udp
# firewall-cmd –permanent –zone=internal –add-service=example-app
# firewall-cmd –reload

Allow Traffic – firewalld Examples

Allow web traffic in the public zone:

# firewall-cmd –permanent –zone=public –add-service=http
# firewall-cmd –permanent –zone=public –add-service=https
# firewall-cmd –reload

Allow SSH only from the management subnet:

# firewall-cmd –permanent –zone=public \
  –add-rich-rule=’rule family=”ipv4″ source address=”192.0.2.0/24″ service name=”ssh” accept’
# firewall-cmd –reload

Allow TCP 5432 only from an application subnet through VLAN 100 by assigning the VLAN to an internal zone and using a rich rule:

# nmcli connection modify vlan100 connection.zone internal
# nmcli connection up vlan100
# firewall-cmd –permanent –zone=internal \
  –add-rich-rule=’rule family=”ipv4″ source address=”198.51.100.0/24″ port port=”5432″ protocol=”tcp” accept’
# firewall-cmd –reload

Allow NFSv4 from one subnet:

# firewall-cmd –permanent –zone=internal \
  –add-rich-rule=’rule family=”ipv4″ source address=”192.0.2.0/24″ port port=”2049″ protocol=”tcp” accept’
# firewall-cmd –reload

Allow VRRP for keepalived peers:

# firewall-cmd –permanent –zone=internal –add-protocol=vrrp
# firewall-cmd –reload

Rate-limit new SSH accepts from a subnet:

# firewall-cmd –permanent –zone=public \
  –add-rich-rule=’rule family=”ipv4″ source address=”192.0.2.0/24″ service name=”ssh” limit value=”15/m” accept’
# firewall-cmd –reload

Rate limiting is not an authentication control. Use keys, strong policy, logging, and an upstream protection strategy as appropriate.

Block or Reject Traffic – firewalld Examples

Remove an unnecessary service:

# firewall-cmd –permanent –zone=public –remove-service=cockpit
# firewall-cmd –reload

Drop all traffic from a source:

# firewall-cmd –permanent –zone=public \
  –add-rich-rule=’rule family=”ipv4″ source address=”198.51.100.50″ drop’
# firewall-cmd –reload

Reject Telnet with an explicit response:

# firewall-cmd –permanent –zone=public \
  –add-rich-rule=’rule family=”ipv4″ port port=”23″ protocol=”tcp” reject’
# firewall-cmd –reload

Block IPv4 echo requests only when policy requires it:

# firewall-cmd –permanent –zone=public –add-icmp-block=echo-request
# firewall-cmd –reload

Do not broadly block ICMP or ICMPv6. Error reporting, neighbour discovery, router discovery, duplicate-address detection, and path-MTU discovery depend on specific types.

Remove a rich rule by repeating it exactly with –remove-rich-rule:

# firewall-cmd –permanent –zone=public \
  –remove-rich-rule=’rule family=”ipv4″ source address=”198.51.100.50″ drop’
# firewall-cmd –reload

Forwarding, Policies, NAT, and Port Forwarding

Enable kernel forwarding first, as described in the routing section. Use a firewalld policy to permit traffic from an internal zone to an external zone:

# firewall-cmd –permanent –new-policy=internal-to-external
# firewall-cmd –permanent –policy=internal-to-external –add-ingress-zone=internal
# firewall-cmd –permanent –policy=internal-to-external –add-egress-zone=external
# firewall-cmd –permanent –policy=internal-to-external –set-target=ACCEPT
# firewall-cmd –reload

Enable IPv4 masquerading on the external zone:

# firewall-cmd –permanent –zone=external –add-masquerade
# firewall-cmd –reload

Forward external TCP port 8080 to an internal web server on port 80:

# firewall-cmd –permanent –zone=external \
  –add-forward-port=port=8080:proto=tcp:toaddr=192.0.2.20:toport=80
# firewall-cmd –reload

Verify:

# firewall-cmd –zone=external –query-masquerade
# firewall-cmd –zone=external –list-forward-ports
# firewall-cmd –info-policy=internal-to-external
# nft list ruleset

NAT can hide source addresses and complicate logs, access controls, and troubleshooting. Use routing without NAT when the network design supports it.

Logging and Firewall Diagnostics

Enable logging of denied packets at an appropriate rate:

# firewall-cmd –set-log-denied=all
$ firewall-cmd –get-log-denied
# journalctl -k -f

Disable after the diagnostic window if the volume is excessive:

# firewall-cmd –set-log-denied=off

Trace a failed connection with state from several layers:

$ ss -lntup | grep ‘:8443’
# firewall-cmd –get-active-zones
# firewall-cmd –list-all-zones
# nft -a list ruleset
# tcpdump -ni any ‘tcp port 8443’
# journalctl -k –since ‘-10 minutes’ | grep -Ei ‘DROP|REJECT|FINAL_REJECT’

Packet counters that remain at zero can prove that a rule is not being reached. Use nft -a to display handles and counters in the backend ruleset, but make policy changes through firewall-cmd while firewalld owns the rules.

Native nftables Management

Use native nftables when the host requires a directly maintained ruleset and firewalld is not the owner:

# systemctl disable –now firewalld
# dnf install -y nftables

Example /etc/sysconfig/nftables.conf:

flush ruleset

table inet filter {
    set management_v4 {
        type ipv4_addr
        flags interval
        elements = { 192.0.2.0/24 }
    }

    chain input {
        type filter hook input priority filter; policy drop;

        ct state invalid drop
        ct state established,related accept
        iifname “lo” accept

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept

        ip saddr @management_v4 tcp dport 22 ct state new accept
        tcp dport { 80, 443 } accept
        ip saddr 192.0.2.0/24 tcp dport 2049 accept

        limit rate 5/second counter log prefix “nft-input-drop: ” drop
    }

    chain forward {
        type filter hook forward priority filter; policy drop;
        ct state established,related accept
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}

Validate before loading:

# nft –check –file /etc/sysconfig/nftables.conf
# nft –file /etc/sysconfig/nftables.conf
# systemctl enable –now nftables
# nft list ruleset

Keep console access when testing a default-drop ruleset. A successful syntax check does not prove that the policy preserves management access.

List, Add, Replace, and Delete nftables Rules

# nft list tables
# nft list table inet filter
# nft -a list chain inet filter input
# nft insert rule inet filter input ip saddr 198.51.100.50 counter drop
# nft insert rule inet filter input ip saddr 192.0.2.25 tcp dport 8443 counter accept

Delete by the handle shown with -a:

# nft -a list chain inet filter input
# nft delete rule inet filter input handle 27

Interactive changes disappear when the persistent file is reloaded or the host reboots. Add intended rules to the file and validate the entire ruleset.

nftables Allow, Block, Egress, and NAT Examples

# nft insert rule inet filter input iifname “vlan100” \
  ip saddr 198.51.100.0/24 tcp dport 5432 ct state new accept
# nft insert rule inet filter input ip saddr 203.0.113.0/24 tcp dport 443 drop
# nft insert rule inet filter output ip daddr 198.51.100.25 tcp dport 25 reject
# nft insert rule inet filter input udp dport 51820 accept

Example forwarding and masquerade table:

table inet forward_filter {
    chain forward {
        type filter hook forward priority filter; policy drop;
        ct state established,related accept
        iifname “lan0” oifname “wan0” accept
    }
}

table ip nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        oifname “wan0” ip saddr 192.0.2.0/24 masquerade
    }
}

SELinux Network Controls

Inspect enforcement and recent denials:

$ getenforce
$ sestatus
# ausearch -m AVC,USER_AVC -ts recent
# journalctl -t setroubleshoot –since ‘-30 minutes’

List port labels:

# dnf install -y policycoreutils-python-utils
$ semanage port -l | grep -E ‘^ssh_port_t|^http_port_t’

Permit sshd to bind TCP 2222 by assigning the correct SELinux port type:

# semanage port -a -t ssh_port_t -p tcp 2222
$ semanage port -l | grep ssh_port_t

Modify an existing custom port mapping with -m, and delete only a locally added mapping with -d.

Permit a confined web server to initiate network connections when required:

$ getsebool httpd_can_network_connect
# setsebool -P httpd_can_network_connect on

Use the narrowest relevant boolean, such as a database-specific or NFS-specific boolean, rather than enabling broad access. Do not disable SELinux to resolve a network error; identify the denial and correct the port label, file label, or boolean.

Selected Kernel Network Security Controls

Inspect current values:

$ sysctl net.ipv4.conf.all.rp_filter
$ sysctl net.ipv4.conf.default.accept_redirects
$ sysctl net.ipv4.conf.all.send_redirects
$ sysctl net.ipv4.conf.all.accept_source_route
$ sysctl net.ipv4.tcp_syncookies
$ sysctl net.ipv6.conf.all.accept_redirects

Example /etc/sysctl.d/70-network-security.conf for a non-router host:

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 1
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# sysctl –system

Reverse-path filtering requires design-specific care:

  • rp_filter=1 is strict and can drop valid asymmetric or policy-routed traffic.
  • rp_filter=2 is loose and accepts a packet if the source is reachable through any interface.
  • rp_filter=0 disables the check.

Do not copy a strict value onto multihomed, VPN, container, or policy-routing hosts without testing return paths.

Traffic Flow, Bandwidth, and Resource Control

Linux traffic control (tc) manages queueing, classification, shaping, policing, and network emulation. It normally controls egress directly. Ingress shaping usually redirects traffic to an Intermediate Functional Block (IFB) device.

Inspect Queueing Disciplines and Counters

$ tc qdisc show
$ tc -s qdisc show dev enp1s0
$ tc class show dev enp1s0
$ tc -s class show dev enp1s0
$ tc filter show dev enp1s0

Before replacing a qdisc, record the original. noqueue is normal for some virtual devices; fq_codel, fq, or mq can be normal for physical devices depending on release and driver.

Use Fair Queueing with Controlled Delay

# tc qdisc replace dev enp1s0 root fq_codel
$ tc -s qdisc show dev enp1s0

Remove the custom root qdisc and return to the device default:

# tc qdisc del dev enp1s0 root

Fair queueing reduces latency under load but does not create a hard bandwidth ceiling.

Limit Egress Bandwidth with Token Bucket Filter

Limit egress to approximately 100 Mbit/s:

# tc qdisc replace dev enp1s0 root tbf \
  rate 100mbit burst 1mb latency 50ms
$ tc -s qdisc show dev enp1s0

Remove the limit:

# tc qdisc del dev enp1s0 root

Choose a burst large enough for the intended rate and timer resolution. An undersized burst can reduce throughput below the configured rate.

Classify Traffic with HTB

Create a 100 Mbit/s root with a 30 Mbit/s class for destination TCP port 22 and a default class:

# tc qdisc replace dev enp1s0 root handle 1: htb default 30
# tc class add dev enp1s0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
# tc class add dev enp1s0 parent 1:1 classid 1:10 htb rate 30mbit ceil 100mbit prio 1
# tc class add dev enp1s0 parent 1:1 classid 1:30 htb rate 70mbit ceil 100mbit prio 2
# tc qdisc add dev enp1s0 parent 1:10 handle 10: fq_codel
# tc qdisc add dev enp1s0 parent 1:30 handle 30: fq_codel
# tc filter add dev enp1s0 protocol ip parent 1: prio 1 u32 \
  match ip dport 22 0xffff flowid 1:10
$ tc -s class show dev enp1s0

Classification is direction-sensitive. On egress, destination port matches outbound packets. Return traffic may have source port 22 and require a separate filter depending on the goal.

Emulate Delay, Loss, Duplication, and Reordering

Use only in a controlled test environment:

# tc qdisc replace dev enp1s0 root netem delay 100ms 20ms distribution normal
# tc qdisc replace dev enp1s0 root netem loss 1%
# tc qdisc replace dev enp1s0 root netem delay 50ms reorder 5% 50%
$ tc -s qdisc show dev enp1s0
# tc qdisc del dev enp1s0 root

Warning: Applying netem to the management interface immediately degrades the administrative session and every service using the link.

Shape Ingress with an IFB Device

# modprobe ifb numifbs=1
# ip link set ifb0 up
# tc qdisc add dev enp1s0 handle ffff: ingress
# tc filter add dev enp1s0 parent ffff: protocol all u32 match u32 0 0 \
  action mirred egress redirect dev ifb0
# tc qdisc replace dev ifb0 root tbf rate 100mbit burst 1mb latency 50ms
$ tc -s qdisc show dev ifb0

Remove the ingress setup:

# tc qdisc del dev enp1s0 ingress
# tc qdisc del dev ifb0 root
# ip link set ifb0 down

Persist a Traffic-Control Policy

NetworkManager versions expose tc.qdiscs and tc.tfilters connection settings, but syntax and supported classifiers vary. Inspect local documentation before using them:

$ man nm-settings-nmcli
$ nmcli –fields all connection show LAN | grep ‘^tc\.’

A simple alternative is a dedicated systemd oneshot unit. Example /etc/systemd/system/limit-enp1s0.service:

[Unit]
Description=Apply egress limit to enp1s0
After=NetworkManager-wait-online.service
Wants=NetworkManager-wait-online.service

[Service]
Type=oneshot
ExecStart=/usr/sbin/tc qdisc replace dev enp1s0 root tbf rate 100mbit burst 1mb latency 50ms
ExecStop=/usr/sbin/tc qdisc del dev enp1s0 root
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl enable –now limit-enp1s0.service
$ tc -s qdisc show dev enp1s0

Measure Throughput with iperf3

On the receiving host:

$ iperf3 -s

On the client:

$ iperf3 -c 198.51.100.20
$ iperf3 -c 198.51.100.20 -P 8
$ iperf3 -c 198.51.100.20 -R
$ iperf3 -c 198.51.100.20 -u -b 500M -t 30

  • -P 8 creates multiple flows and is useful for LACP hashing tests.
  • -R reverses the test direction.
  • UDP tests report loss and jitter but can intentionally overload the path.

Do not interpret an iperf result without CPU, offload, retransmission, and interface-error context. The bottleneck can be encryption, virtualisation, storage, CPU frequency, a single flow, or the remote host rather than line rate.

Per-Service Network Accounting and Address Restrictions

Enable systemd IP accounting temporarily for a service:

# systemctl set-property example.service IPAccounting=yes
$ systemctl show example.service \
  -p IPAccounting -p IPIngressBytes -p IPEgressBytes \
  -p IPIngressPackets -p IPEgressPackets

Restrict a service with unit properties where supported by the systemd/cgroup/BPF stack. Example drop-in:

[Service]
IPAccounting=yes
IPAddressDeny=any
IPAddressAllow=192.0.2.0/24
IPAddressAllow=127.0.0.0/8
IPAddressAllow=::1/128
# systemctl daemon-reload
# systemctl restart example.service

These restrictions apply to sockets used by the service’s cgroup and are independent of the host firewall. Test DNS, loopback, logging, and dependent services before enforcing a deny-all policy.

Network Namespace Isolation Example

# ip netns add lab
# ip link add veth-host type veth peer name veth-lab
# ip link set veth-lab netns lab
# ip address add 192.0.2.1/30 dev veth-host
# ip link set veth-host up
# ip -n lab address add 192.0.2.2/30 dev veth-lab
# ip -n lab link set lo up
# ip -n lab link set veth-lab up
# ip -n lab route add default via 192.0.2.1
$ ip netns exec lab ping -c 2 192.0.2.1
$ ip netns exec lab ip address
# ip netns delete lab
# ip link delete veth-host 2>/dev/null || true

Namespaces isolate interfaces, routes, neighbour tables, sockets, and many sysctls. External access additionally requires forwarding, firewall policy, and possibly NAT.

Monitoring Traffic and Collecting Performance Metrics

A useful network baseline combines interface counters, driver counters, queue statistics, socket state, protocol statistics, packet captures, and historical metrics. One tool rarely explains a performance issue by itself.

Interface Counters

$ ip -s link show dev enp1s0
$ ip -details -statistics link show dev enp1s0
$ cat /proc/net/dev
$ ethtool -S enp1s0
$ nmcli device show enp1s0

Look for increasing receive/transmit errors, drops, missed packets, CRC/FCS errors, carrier changes, queue timeouts, and no-buffer counters. Driver counter names are vendor-specific; compare the rate of change rather than relying only on one absolute number.

Watch counters every second:

$ watch -n 1 ‘ip -s link show dev enp1s0’
$ watch -n 1 “ethtool -S enp1s0 | grep -Ei ‘drop|error|crc|miss|timeout|reset'”

Interactive Bandwidth and Flow Tools

Repository availability varies by release and enabled repositories:

# dnf install -y iftop nload bmon vnstat

Examples:

# iftop -i enp1s0 -nNP
$ nload enp1s0
$ bmon -p enp1s0
$ vnstat -i enp1s0
$ vnstat -l -i enp1s0

iftop shows conversations, nload shows aggregate rates, bmon shows interface counters, and vnstat stores long-term totals. These tools are useful for orientation but do not replace packet captures or application metrics.

Packet Capture with tcpdump

Basic interface capture without name or service resolution:

# tcpdump -ni enp1s0

Useful filters:

# tcpdump -ni enp1s0 host 198.51.100.20
# tcpdump -ni enp1s0 ‘tcp port 22’
# tcpdump -ni enp1s0 ‘udp port 53 or tcp port 53’
# tcpdump -ni enp1s0 ‘arp or icmp or icmp6’
# tcpdump -eni enp1s0 ‘vlan 100’
# tcpdump -ni any ‘tcp[tcpflags] & (tcp-syn|tcp-rst|tcp-fin) != 0’

Save full packets for later analysis:

# tcpdump -ni enp1s0 -s 0 -w /var/tmp/network.pcap ‘host 198.51.100.20’

Rotate bounded capture files:

# tcpdump -ni enp1s0 -s 0 -C 100 -W 10 \
  -w /var/tmp/network-%Y%m%d%H%M%S.pcap ‘tcp port 443’

-C 100 rotates near 100 MB and -W 10 retains ten files. Packet captures can contain credentials, tokens, personal data, and proprietary payloads even when application encryption hides content. Protect, transfer, and delete them according to policy.

Capture both sides of a host when diagnosing forwarding, NAT, VLAN, bond, or asymmetric-path problems:

# tcpdump -ni enp1s0 -w /var/tmp/inside.pcap host 198.51.100.20
# tcpdump -ni enp2s0 -w /var/tmp/outside.pcap host 198.51.100.20

Monitor Sockets and TCP Health

$ ss -s
$ ss -lntup
$ ss -tan state established
$ ss -tan state syn-sent
$ ss -tan state syn-recv
$ ss -tan state time-wait
$ ss -ti dst 198.51.100.20
$ ss -uapn

ss -ti can expose congestion control, RTT, retransmissions, pacing, cwnd, and delivery-rate information for TCP sockets.

Protocol counters:

$ nstat -az
$ nstat -az | grep -Ei ‘Retrans|Timeout|InErrors|NoRoutes|Frag|Rcvbuf|Sndbuf’
$ cat /proc/net/snmp
$ cat /proc/net/netstat

Take two snapshots and compare counter deltas during the problem rather than interpreting lifetime totals without context.

Collect Current and Historical Metrics with sysstat

# dnf install -y sysstat
# systemctl enable –now sysstat 2>/dev/null || true
# systemctl enable –now sysstat-collect.timer 2>/dev/null || true

Live samples:

$ sar -n DEV 1
$ sar -n EDEV 1
$ sar -n TCP,ETCP 1
$ sar -n SOCK 1
$ sar -u 1
$ mpstat -P ALL 1

Historical examples:

$ sar -n DEV -f /var/log/sa/sa14
$ sar -n EDEV -s 09:00:00 -e 10:00:00

  • DEV reports throughput and packets by interface.
  • EDEV reports errors, drops, collisions, and overruns.
  • TCP and ETCP show connection and retransmission activity.
  • CPU and interrupt pressure should be reviewed alongside network rates.

Performance Co-Pilot

PCP provides live and archived metrics with a consistent namespace:

# dnf install -y pcp pcp-system-tools
# systemctl enable –now pmcd pmlogger
$ pmstat
$ pminfo network.interface
$ pmrep -t 1 network.interface.in.bytes network.interface.out.bytes
$ pmrep -t 1 network.interface.in.errors network.interface.out.errors

Discover exact metric names on the installed version:

$ pminfo | grep -E ‘^network\.|^kernel\.all\.network’
$ pminfo -f network.interface

Archive analysis is valuable for intermittent incidents that finish before an administrator connects. Verify that pmlogger retention and storage match operational requirements.

Optional eBPF and Socket-Tracing Tools

When repositories and kernel support provide them:

# dnf install -y bcc-tools bpftrace bpftool

Common tools can include:

# tcpconnect
# tcplife
# tcptop
# softirqs
# bpftool prog show

Tool names and packaging vary by release and kernel. On Oracle Linux, UEK and RHCK can expose different probe support. Use eBPF tools carefully on production systems and validate their overhead.

Create a Repeatable Performance Baseline

Record idle and loaded measurements:

$ date -Ins
$ uname -r
$ ethtool enp1s0
$ ethtool -k enp1s0
$ ethtool -g enp1s0
$ ip -s link show dev enp1s0
$ sar -n DEV,EDEV,TCP,ETCP 1 10
$ mpstat -P ALL 1 10
$ ss -s
$ nstat -az
$ tc -s qdisc show dev enp1s0

Then run a controlled throughput test and repeat. A baseline makes later deviations visible and helps distinguish a network change from a workload, CPU, driver, firmware, or virtualisation change.

Troubleshooting Workflow and Common Tools

Troubleshooting is faster when each layer is tested in order and evidence is collected before restarting services. Begin with the smallest failing scope: one interface, one address, one path, one protocol, and one time window.

Step-by-Step Network Troubleshooting

  1. Confirm the intended interface and NetworkManager profile.
  2. Confirm hardware, driver, carrier, speed, duplex, MTU, and errors.
  3. Confirm VLAN, bridge, bond, MAC, and neighbour state.
  4. Confirm IP address, prefix, source selection, routes, and policy rules.
  5. Test the local gateway and a remote IP address.
  6. Test DNS/NSS separately from raw IP reachability.
  7. Confirm the server socket, firewall, SELinux, and application protocol.
  8. Capture packets on the relevant interfaces and correlate timestamps with logs.

A compact first pass:

$ nmcli device status
$ nmcli connection show –active
$ ip -br link
$ ip -br address
$ ip route
$ ip rule
$ ip neigh
$ ping -c 3 192.0.2.1
$ ip route get 198.51.100.20
$ getent ahosts app.example.com
$ nc -vz -w 3 app.example.com 443
$ ss -lntup

ping – Reachability, Latency, Loss, and MTU

$ ping -c 4 192.0.2.1
$ ping -c 4 198.51.100.20
$ ping -I enp1s0 -c 4 198.51.100.20
$ ping -I 192.0.2.10 -c 4 198.51.100.20
$ ping -6 -c 4 2001:db8:2::20

Control interval and deadline:

$ ping -c 10 -i 0.2 -w 5 198.51.100.20

Probe path MTU:

$ ping -c 3 -M do -s 1472 198.51.100.20
$ ping -c 3 -M do -s 8972 198.51.100.20

The 1472-byte payload plus IPv4 and ICMP headers tests a 1500-byte IP packet. VLAN/Ethernet framing is outside that calculation. Reduce the payload until it succeeds, then investigate the path component with the smaller MTU.

Interpretation:

Observation

Likely direction

Local gateway does not reply

Link, VLAN, address/prefix, ARP, switch, or gateway filtering.

Gateway replies but remote IP does not

Upstream route, firewall, remote host, or return path.

Remote IP replies but name fails

DNS/NSS, not general IP connectivity.

Small payload succeeds but large DF payload fails

Path-MTU discovery or MTU mismatch.

Variable high RTT and loss

Congestion, Wi-Fi quality, queueing, errors, duplex, or remote load.

A host can block echo while allowing the intended service, so ping failure is not final proof that the service is unreachable.

arp, ip neighbour, and arping

The arp command from net-tools is legacy:

$ arp -n

Preferred neighbour-table commands:

$ ip neigh show
$ ip neigh show dev enp1s0
$ ip -6 neigh show
$ ip neigh get 192.0.2.1 dev enp1s0

Neighbour states:

State

Meaning

REACHABLE

Recently confirmed reachable.

STALE

Entry is valid but not recently confirmed; normal until used.

DELAY / PROBE

Kernel is actively confirming reachability.

INCOMPLETE

Resolution request sent; no MAC learned yet.

FAILED

Resolution attempts failed. Check subnet, VLAN, peer, and switch path.

PERMANENT

Static entry that is not normally aged.

Probe a neighbour or duplicate address:

# arping -I enp1s0 -c 3 192.0.2.1
# arping -D -I enp1s0 -c 3 192.0.2.10

Delete one stale entry and allow relearning:

# ip neigh del 192.0.2.1 dev enp1s0

Flushing an entire neighbour table can interrupt active traffic and conceal the original evidence. Delete only the affected entry unless a full flush is deliberate.

traceroute and tracepath – Path Discovery

$ traceroute -n 198.51.100.20
$ traceroute -I -n 198.51.100.20
$ traceroute -T -p 443 -n 198.51.100.20
$ traceroute -U -p 53 -n 192.0.2.53
$ traceroute -6 -n 2001:db8:2::20
$ tracepath -n 198.51.100.20

  • Default traceroute commonly sends UDP probes.
  • -I uses ICMP echo.
  • -T uses TCP and can follow the same firewall path as an application port.
  • tracepath does not normally require root and reports discovered path MTU.

Asterisks indicate no response to that probe, not necessarily packet loss at that router. Many routers forward traffic while rate-limiting or filtering TTL-expired replies.

nc / ncat – TCP and UDP Port Testing

Test a TCP connection:

$ nc -vz -w 3 198.51.100.20 443
$ ncat -vz –wait 3 app.example.com 443

Listen temporarily on a test port:

$ nc -l 8443

From another host:

$ printf ‘test\n’ | nc -w 3 192.0.2.10 8443

UDP test:

$ nc -vzu -w 3 192.0.2.53 53

A UDP succeeded message often means no immediate ICMP error was received; it does not prove that the application accepted or replied to the datagram. Use a protocol-aware query and packet capture.

ss – Socket and Connection Inspection

$ ss -lntup
$ ss -lnpt ‘sport = :443’
$ ss -tan ‘dst 198.51.100.20’
$ ss -tan state syn-sent
$ ss -tan state syn-recv
$ ss -ti ‘dst 198.51.100.20’
$ ss -uapn

Interpret common TCP conditions:

  • SYN-SENT accumulating on a client suggests no SYN-ACK, routing failure, silent filtering, or remote outage.
  • SYN-RECV accumulating on a server can indicate backlog pressure, an attack, or return-path problems.
  • Immediate ECONNREFUSED generally means a TCP reset from the host or an active firewall reject.
  • Many retransmissions with an established socket indicate loss, congestion, MTU, or severe receiver/application delay.

dig and getent – DNS and NSS

$ getent ahosts app.example.com
$ getent hosts app
$ dig app.example.com A
$ dig app.example.com AAAA
$ dig @192.0.2.53 app.example.com A +tcp
$ dig -x 198.51.100.20

Compare results. When dig succeeds but getent fails, inspect /etc/nsswitch.conf, /etc/resolv.conf, search domains, local hosts, SSSD, and any local resolver.

tcpdump – Packet-Level Evidence

Observe a TCP handshake:

# tcpdump -ni enp1s0 ‘host 198.51.100.20 and tcp port 443’

Handshake patterns:

Packet pattern

Interpretation

SYN, SYN-ACK, ACK

TCP path and handshake succeeded. Continue at TLS/application layer.

Repeated SYN, no reply

Silent drop, route/return-path problem, or destination down.

SYN followed by RST

Host reached but no listener, active reject, or application reset.

SYN-ACK seen leaving server but not at client

Return-path or intermediate filtering problem.

Repeated retransmissions after establishment

Loss, congestion, MTU, receiver, or application stall.

Capture DNS plus the resulting connection to correlate name and application behaviour:

# tcpdump -ni any ‘port 53 or (host 198.51.100.20 and tcp port 443)’

curl, openssl, and Application-Layer Tests

HTTP/TLS detail:

$ curl -v –connect-timeout 5 https://app.example.com/
$ curl -sS -o /dev/null -w \
  ‘dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total}\n’ \
  https://app.example.com/
$ curl –resolve app.example.com:443:198.51.100.20 https://app.example.com/

–resolve tests a specific address while preserving the HTTP Host header and TLS server name.

Inspect the TLS handshake and certificate chain:

$ openssl s_client -connect app.example.com:443 \
  -servername app.example.com -showcerts </dev/null

Application tests distinguish a successful TCP handshake from HTTP redirects, TLS trust errors, proxy policy, authentication failures, or server-side delays.

mtr – Continuous Path Testing

$ mtr -rwzc 100 198.51.100.20
$ mtr -T -P 443 -rwzc 100 app.example.com

Loss shown at an intermediate hop is meaningful only when it continues to later hops. A router can rate-limit diagnostic responses while forwarding transit traffic normally.

Troubleshooting Common Scenarios

Interface Missing

$ ip link
$ lspci -nnk | grep -A3 -Ei ‘ethernet|network’
$ lsusb
$ ethtool -i enp1s0
# journalctl -k -b | grep -Ei ‘net|ether|firmware|rename|pci|usb’

Check whether the device is physically detected, the expected driver is present, firmware loaded, the name changed, the interface moved to a namespace, or a virtual device was not recreated.

Interface Present but No Carrier

$ ip -br link show enp1s0
$ ethtool enp1s0
$ cat /sys/class/net/enp1s0/carrier
$ ethtool -S enp1s0 | grep -Ei ‘error|crc|carrier|link|fault’
# journalctl -k -b | grep -i enp1s0

Check cable, optic, transceiver support, switch port state, speed/autonegotiation compatibility, radio block, and driver resets.

DHCP Does Not Obtain an Address

$ nmcli device status
$ nmcli -f GENERAL,IP4,DHCP4 device show enp1s0
# journalctl -fu NetworkManager
# tcpdump -ni enp1s0 ‘udp port 67 or udp port 68’

No DHCP discover usually means the profile is not active, device is unmanaged, or lower-layer state is wrong. Discover without offer points to VLAN, relay, server, scope, or filtering. Offer without successful request/ack can indicate duplicate-address detection, server policy, or client/profile conflict.

Local Subnet Peer Is Unreachable

$ ip address show dev enp1s0
$ ip route get 192.0.2.25
$ ip neigh show 192.0.2.25
# arping -I enp1s0 -c 3 192.0.2.25
# tcpdump -ni enp1s0 ‘arp or host 192.0.2.25’

Focus on prefix length, VLAN, duplicate address, ARP/NDP, bridge/bond membership, switch isolation, and host firewall.

Internet Works by Address but Not by Name

$ ping -c 2 198.51.100.20
$ getent ahosts app.example.com
$ cat /etc/resolv.conf
$ nmcli -f IP4.DNS,IP4.DOMAIN device show
$ dig @192.0.2.53 app.example.com A
# tcpdump -ni any port 53

Remote Service Is Unreachable

Client:

$ ip route get 198.51.100.20
$ nc -vz -w 3 198.51.100.20 443
$ traceroute -T -p 443 -n 198.51.100.20
# tcpdump -ni enp1s0 ‘host 198.51.100.20 and tcp port 443’

Server:

$ ss -lntp ‘sport = :443’
# firewall-cmd –list-all
$ getenforce
# ausearch -m AVC -ts recent
# tcpdump -ni any ‘host 192.0.2.10 and tcp port 443’

Intermittent Freezes or MTU Black Hole

$ tracepath 198.51.100.20
$ ping -M do -s 1472 -c 3 198.51.100.20
$ ss -ti dst 198.51.100.20
# tcpdump -ni enp1s0 ‘icmp or icmp6 or host 198.51.100.20’

Look for large-packet retransmissions, missing ICMP fragmentation-needed or packet-too-big messages, tunnels, VLANs, VPN overhead, and inconsistent jumbo-frame settings.

Slow Throughput

$ ethtool enp1s0
$ ip -s link show enp1s0
$ ethtool -S enp1s0
$ sar -n DEV,EDEV,TCP,ETCP 1
$ mpstat -P ALL 1
$ ss -ti dst 198.51.100.20
$ tc -s qdisc show dev enp1s0
$ iperf3 -c 198.51.100.20 -P 8

Check negotiated speed, duplex, CRC/errors, drops, retransmissions, queue pressure, CPU saturation, IRQ distribution, offload settings, single-flow limits, virtualisation, and remote bottlenecks.

VLAN Traffic Fails

$ ip -d link show vlan100
$ nmcli connection show vlan100
# tcpdump -eni enp1s0 vlan 100
# tcpdump -ni vlan100 ‘arp or icmp or icmp6’

Confirm parent, VLAN ID, trunk allowance, native VLAN, bond placement, MTU, and IP prefix. Compare capture on both parent and VLAN interface.

Bond or LACP Fails Over Incorrectly

$ cat /proc/net/bonding/bond0
$ ip -s -d link show bond0
$ ethtool enp1s0
$ ethtool enp2s0
# journalctl -k -b | grep -i bond

For active-backup, verify monitoring, primary policy, VLAN parity, MAC movement, and switch security. For LACP, verify partner keys, aggregator IDs, collecting/distributing state, switch channel, and multi-chassis support.

Asymmetric Routing or Reverse-Path Filtering

$ ip rule show
$ ip route show table all
$ ip route get 198.51.100.20 from 192.0.2.10
$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.enp1s0.rp_filter
# tcpdump -ni any host 198.51.100.20

Capture both ingress and egress. A packet can arrive on one interface while the kernel’s reverse route points to another, causing strict reverse-path filtering or a stateful firewall to drop it.

Common Errors and Focused Fixes

Problem

Likely explanation

Focused action

Network is unreachable

No matching route or no usable interface address

ip route get; inspect address, connected route, default route, and rules.

Destination Host Unreachable from local host

Neighbour resolution or local route failed

ip neigh, arping, VLAN, prefix, peer, switch path.

Connection refused

Destination returned TCP RST or firewall reject

Check server listener, bind address, service state, reject rules.

Connection timeout

Silent filtering, loss, route failure, return path, or application stall

Capture both ends; inspect routes, firewall, and service.

RTNETLINK answers: File exists

Conflicting existing address, route, rule, or device

Show the exact object; delete or use replace.

Temporary failure in name resolution

Resolver unavailable, wrong ownership, or DNS path failure

getent, resolv.conf, NetworkManager DNS, direct dig.

Address already in use

Duplicate IP or local socket bind conflict

arping -D, ip address, ss -lntup, IP inventory.

No such device

Wrong/renamed interface, namespace move, or missing driver

ip link, udevadm, lspci -k, kernel logs.

Operation not supported

Driver, hardware, kernel, or manager lacks requested feature

ethtool -i/-k, local docs, alternate mode.

NetworkManager activation failed

Invalid profile, carrier/DHCP failure, duplicate address, dependency

nmcli con up, journalctl -u NetworkManager, validate profile.

NFS server not responding

DNS, route, TCP 2049, firewall, loss, or server outage

getent, nc, mount -v, nfsstat, packet capture.

LDAP certificate verify failed

CA, name, expiration, or clock mismatch

openssl s_client, CA trust, DNS name, Chrony.

Firewalld rule appears ineffective

Wrong zone, runtime/permanent mismatch, rule order, no listener

Active zones, –list-all-zones, nft counters, ss.

SELinux denial

Process or port type not authorised

ausearch, semanage port, relevant boolean or label.

Collect a Network Diagnostic Snapshot

# out=/var/tmp/network-snapshot-$(date +%F-%H%M%S)
# mkdir -p “$out”
# date -Ins > “$out/date.txt”
# uname -a > “$out/uname.txt”
# nmcli general status > “$out/nm-general.txt”
# nmcli device status > “$out/nm-devices.txt”
# nmcli connection show –active > “$out/nm-active.txt”
# nmcli –terse –fields all connection show > “$out/nm-profiles.txt”
# ip -details -statistics link > “$out/ip-link.txt”
# ip -details address > “$out/ip-address.txt”
# ip route show table all > “$out/ip4-routes.txt”
# ip -6 route show table all > “$out/ip6-routes.txt”
# ip rule show > “$out/ip-rules.txt”
# ip neigh show > “$out/neighbours.txt”
# ss -lntup > “$out/listeners.txt”
# ss -s > “$out/socket-summary.txt”
# nstat -az > “$out/nstat.txt”
# firewall-cmd –list-all-zones > “$out/firewalld.txt” 2>&1
# nft list ruleset > “$out/nftables.txt” 2>&1
# journalctl -b -u NetworkManager > “$out/NetworkManager.log”
# journalctl -k -b > “$out/kernel.log”
# tar -C /var/tmp -czf “$out.tar.gz” “${out##*/}”

Sanitise addresses, profile secrets, DNS names, LDAP data, packet captures, and logs before sharing outside the authorised support path.

For a broader support archive, install and run sos:

# dnf install -y sos
# sos report –batch

The sos archive can contain sensitive configuration and logs. Handle it as confidential operational data.

Command Reference Summary

Task

Command

List interfaces and addresses

ip -br link; ip -br address

Show NetworkManager devices

nmcli device status

Show active profiles

nmcli connection show –active

Detailed interface state

ip -s -d link show dev enp1s0

Driver, firmware, and bus

ethtool -i enp1s0

Link speed and duplex

ethtool enp1s0

Wireless state

iw dev; iw dev wlp2s0 link; rfkill list

Current/permanent MAC

ip link show enp1s0; ethtool -P enp1s0

Add/delete temporary address

ip addr add PREFIX dev IFACE; ip addr del PREFIX dev IFACE

Create static NetworkManager profile

nmcli con add type ethernet ifname IFACE con-name NAME ipv4.method manual …

Create DHCP profile

nmcli con add type ethernet ifname IFACE con-name NAME ipv4.method auto

Add a VLAN

nmcli con add type vlan ifname vlan100 vlan.parent enp1s0 vlan.id 100

Inspect bond

cat /proc/net/bonding/bond0

List all routes/rules

ip route show table all; ip -6 route show table all; ip rule

Explain route choice

ip route get DEST from SOURCE

Add/replace default route

ip route replace default via GATEWAY dev IFACE metric N

Add/delete static route

ip route add PREFIX via GATEWAY; ip route del PREFIX via GATEWAY

Show neighbours

ip neigh show; ip -6 neigh show

Duplicate IPv4 probe

arping -D -I IFACE -c 3 ADDRESS

Show resolver inputs

cat /etc/resolv.conf; nmcli -f IP4.DNS,IP4.DOMAIN device show

DNS through NSS

getent ahosts NAME

Direct DNS query

dig @SERVER NAME TYPE

Chrony status

chronyc tracking; chronyc sources -v

LDAP identity test

getent passwd USER; id USER; sssctl user-checks USER

NFS mount state

findmnt; nfsstat -m; nfsiostat 1

List firewall zones

firewall-cmd –get-active-zones; firewall-cmd –list-all-zones

List native ruleset

nft -a list ruleset

Listening sockets

ss -lntup

TCP port test

nc -vz -w 3 HOST PORT

TCP path trace

traceroute -T -p PORT -n HOST

Path MTU

tracepath HOST; ping -M do -s SIZE HOST

Packet capture

tcpdump -ni IFACE FILTER

Interface metrics

ip -s link; ethtool -S IFACE; sar -n DEV,EDEV 1

TCP metrics

ss -ti; nstat -az; sar -n TCP,ETCP 1

Queue metrics

tc -s qdisc show dev IFACE

Throughput test

iperf3 -c HOST -P 8

Follow network logs

journalctl -fu NetworkManager

Declarative state

nmstatectl show; nmstatectl apply FILE.yml

Quick Layer-to-Tool Reference

Layer or service

Interrogate

Configure or manage

Physical Ethernet

lspci, lshw, ethtool, kernel journal

Driver/firmware, ethtool, NetworkManager link properties

Wireless physical/link

iw phy, iw dev, rfkill, nmcli wifi

nmcli, nmtui, rfkill, regulatory policy

Data link

ip -s -d link, bridge, ip neigh

ip link, nmcli, Nmstate, bridge/bond/VLAN profiles

VLAN

ip -d link, bridge vlan, tcpdump -e

NetworkManager VLAN profile, Nmstate

Bond/LACP

/proc/net/bonding, ip -d link

NetworkManager bond and port profiles, switch LAG

IPv4/IPv6 address

ip address, nmcli device show

ip address, NetworkManager, Nmstate

Routing

ip route, ip rule, ip route get

ip route/rule, NetworkManager routes/rules, Nmstate

TCP/UDP

ss, nc, tcpdump, nstat

Application bind, firewalld/nftables, sysctl, tc

DNS

getent, dig, resolver files, nmcli

NetworkManager DNS, local resolver, NSS, hosts

NTP

timedatectl, chronyc

/etc/chrony.conf, chronyd

LDAP

ldapsearch, getent, id, sssctl

SSSD, authselect, CA trust

NFS

findmnt, nfsstat, nfsiostat, tcpdump

mount, /etc/fstab, autofs, SELinux booleans

Firewall

firewall-cmd, nft, counters, logs

firewalld or native nftables, not both as owners

SELinux

getenforce, ausearch, semanage

Port types, booleans, labels, policy

Performance

sar, PCP, ethtool -S, ss -ti, tc -s

tc, qdiscs/classes, systemd IP accounting

Final Notes

Network troubleshooting becomes predictable when each layer is verified before the next. Begin with hardware and carrier, then data-link state, address and prefix, neighbour discovery, route selection, DNS, transport sockets, firewall/SELinux policy, and finally the application protocol.

For persistent configuration on current systems, use NetworkManager profiles through nmcli, nmtui, Cockpit, Nmstate, or automation. Treat ifcfg examples as migration references for RHEL and Oracle Linux 8, not as the design target for 9 or 10. Use bonds rather than teams for new deployments.

Before every remote networking or firewall change, capture the working state, preserve console access, make one change at a time, and verify the running kernel state rather than trusting only the saved configuration.

Authoritative References

  • Red Hat Enterprise Linux 10 – Configuring and managing networking: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_and_managing_networking/
  • Red Hat Enterprise Linux 10 – Network troubleshooting and performance tuning: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/network_troubleshooting_and_performance_tuning/
  • Red Hat Enterprise Linux 10 – Configuring firewalls and packet filters: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_firewalls_and_packet_filters/
  • Red Hat Enterprise Linux 10 – Configuring time synchronization: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_time_synchronization/
  • Red Hat Enterprise Linux 10 – Configuring authentication and authorization: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_authentication_and_authorization_in_rhel/
  • Red Hat Enterprise Linux 10 – Configuring and using network file services: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_and_using_network_file_services/
  • Red Hat Enterprise Linux 9 – Configuring and managing networking: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_and_managing_networking/
  • Red Hat Enterprise Linux 8 – Configuring and managing networking: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/
  • Oracle Linux 10 – Setting Up Networking With NetworkManager: https://docs.oracle.com/en/operating-systems/oracle-linux/10/network/
  • Oracle Linux 9 – Setting Up Networking: https://docs.oracle.com/en/operating-systems/oracle-linux/9/network/
  • Oracle Linux 8 – Setting Up Networking: https://docs.oracle.com/en/operating-systems/oracle-linux/8/network/
  • Oracle Linux – Configuring the Firewall: https://docs.oracle.com/en/operating-systems/oracle-linux/9/firewall/
  • NetworkManager command-line documentation: man nmcli, man nm-settings-nmcli, man NetworkManager.conf
  • iproute2 documentation: man ip, man ip-link, man ip-address, man ip-route, man ip-rule, man ss, man tc
  • Ethernet and driver documentation: man ethtool
  • firewalld and nftables documentation: man firewall-cmd, man firewalld.richlanguage, man nft
  • SSSD and LDAP documentation: man sssd.conf, man sssd-ldap, man authselect, man ldapsearch
  • NFS documentation: man nfs, man nfs.conf, man mount.nfs, man autofs

 

Check out our other Cheat Sheets and Blogs and if you would like us to write a cheat sheet for you, for FREE, (and we find it suitable) Contact Us.