IPv6 adoption has accelerated significantly as IPv4 address exhaustion becomes more acute, and most modern Linux distributions including RHEL 8 ship with full IPv6 support enabled by default. Configuring IPv6 on RHEL 8 requires working with nmcli for network interface configuration, firewalld for controlling IPv6 traffic including ICMPv6, and optionally adjusting service configurations to bind to IPv6 addresses. This tutorial walks through verifying IPv6 kernel support, assigning a static IPv6 address, configuring the firewall, testing connectivity, and enabling IPv6 for common network services.
Prerequisites
- A RHEL 8 server with NetworkManager running (
systemctl status NetworkManager) - Root or sudo access
- An IPv6 address prefix allocated to your network (this tutorial uses the documentation prefix
2001:db8::/32— replace with your actual prefix in production) - Knowledge of your network interface name (use
ip link showto list interfaces) - IPv6 connectivity at your network gateway if you plan to test external IPv6 routing
Step 1 — Verify IPv6 Kernel Support
Before configuring IPv6, confirm it is not disabled at the kernel level via sysctl or kernel boot parameters. RHEL 8 enables IPv6 by default, but it may have been disabled in custom deployments. Check both the sysctl values and any existing link-local addresses assigned automatically by the kernel.
# Check if IPv6 is disabled globally:
sysctl net.ipv6.conf.all.disable_ipv6
sysctl net.ipv6.conf.default.disable_ipv6
# Should output 0 (enabled). If disabled, re-enable:
sysctl -w net.ipv6.conf.all.disable_ipv6=0
echo 'net.ipv6.conf.all.disable_ipv6 = 0' >> /etc/sysctl.d/99-ipv6.conf
# Check for existing link-local addresses (fe80:: prefix):
ip -6 addr show
ip link show
Step 2 — Assign a Static IPv6 Address with nmcli
Use nmcli to assign a static IPv6 address to your network interface. Replace ens3 with your actual interface name, and substitute the address and gateway with values appropriate for your network. After modifying the connection, bring it down and up to apply the new configuration, then verify the address was applied.
# Replace ens3 with your interface name:
nmcli con mod ens3 ipv6.method manual
ipv6.addresses "2001:db8::10/64"
ipv6.gateway "2001:db8::1"
ipv6.dns "2001:4860:4860::8888"
nmcli con down ens3
nmcli con up ens3
# Verify the IPv6 address was applied:
ip -6 addr show ens3
nmcli con show ens3 | grep ipv6
Step 3 — Configure firewalld for IPv6 Traffic
By default, firewalld manages both IPv4 and IPv6 using ip6tables under the hood. ICMPv6 messages are essential for IPv6 to function — neighbor discovery, router advertisements, and path MTU discovery all rely on specific ICMPv6 types. Ensure they are permitted, and add rich rules to allow specific IPv6 services as needed.
# Allow essential ICMPv6 types for neighbor discovery (usually allowed by default):
firewall-cmd --permanent --add-icmp-block-inversion
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" icmp-type name="neighbour-advertisement" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" icmp-type name="neighbour-solicitation" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" icmp-type name="router-advertisement" accept'
# Allow SSH over IPv6 from a specific subnet:
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address="2001:db8::/64" service name="ssh" accept'
firewall-cmd --reload
firewall-cmd --list-rich-rules
Step 4 — Test IPv6 Connectivity
Use ping6 (or ping -6 on newer systems) to test local and remote IPv6 connectivity. Test the loopback address first, then the local link-local address, then a remote IPv6 host. Use traceroute6 to diagnose routing issues if pings to external addresses fail.
# Test IPv6 loopback:
ping6 -c 4 ::1
# Test your newly assigned address:
ping6 -c 4 2001:db8::10
# Test external IPv6 connectivity (requires working upstream IPv6 routing):
ping6 -c 4 2001:4860:4860::8888
# Trace the IPv6 path to a remote host:
traceroute6 2001:4860:4860::8888
# Verify IPv6 routing table:
ip -6 route show
Step 5 — Enable Services to Listen on IPv6
Applications must be explicitly configured to bind to IPv6 addresses. For Nginx, add listen [::]:80 directives. For Apache, ensure Listen directives include the IPv6 address format. For SSH, verify the AddressFamily setting in sshd_config. After configuration changes, restart the relevant service and confirm it is listening on the IPv6 interface.
# For Nginx — add inside the server {} block in /etc/nginx/nginx.conf:
# listen [::]:80;
# listen [::]:443 ssl;
# For OpenSSH — ensure IPv6 is not restricted:
grep AddressFamily /etc/ssh/sshd_config
# Should be: AddressFamily any (or inet6)
# Restart services after config changes:
systemctl restart nginx
systemctl restart sshd
# Verify services are listening on IPv6 (denoted by :::port or [::]:port):
ss -tlnp6
ss -6 -tlnp | grep -E 'nginx|sshd'
Step 6 — Make IPv6 Configuration Persistent After Reboot
Configurations applied with nmcli con mod are already persistent — NetworkManager stores them in /etc/NetworkManager/system-connections/. Confirm the connection file reflects your IPv6 settings, and verify the sysctl settings that re-enable IPv6 (if you needed to change them) are in the /etc/sysctl.d/ drop-in directory so they survive reboots.
# Verify the NetworkManager connection file:
cat /etc/NetworkManager/system-connections/ens3.nmconnection | grep -A5 '[ipv6]'
# Confirm sysctl settings persist:
cat /etc/sysctl.d/99-ipv6.conf
# Reboot and verify IPv6 is still configured correctly:
ip -6 addr show ens3
ping6 -c 2 ::1
Conclusion
You have verified IPv6 kernel support on RHEL 8, assigned a static IPv6 address using nmcli, configured firewalld to allow essential ICMPv6 traffic and IPv6 service access, and enabled network services to accept IPv6 connections. All configuration changes made through NetworkManager persist across reboots without additional steps. As you expand IPv6 usage, pay close attention to ICMPv6 filtering — blocking too many ICMPv6 types can break neighbor discovery and prevent IPv6 from functioning even when addresses are correctly configured.
Next steps: How to Configure IPv6 DHCPv6 and SLAAC on RHEL 8, How to Set Up a Dual-Stack (IPv4 and IPv6) Web Server on RHEL 8, and How to Configure IPv6 Routing with FRRouting on RHEL 8.