IPv6 breaks differently than IPv4. There’s no NAT hiding your mistakes, no single DHCP server controlling everything, and a whole new set of protocols (RA, ND, DHCPv6) that must work together. When IPv6 stops working, it’s rarely “magic” — it’s almost always Router Advertisements or firewall rules.
This guide covers practical IPv6 deployment on VyOS, including the debugging steps that will save you hours of frustration.
IPv6 Addressing: What You Actually Get
Most ISPs provide one of these:
- Static prefix: You get a /48 or /56 that doesn’t change
- DHCPv6-PD (Prefix Delegation): Router requests a prefix dynamically
- Single /64: Bare minimum, limits your options
For home use, DHCPv6-PD is most common. Let’s configure for that scenario.
WAN Configuration: Getting Your Prefix
configure
# Request address via DHCPv6 for WAN interfaceset interfaces ethernet eth0 ipv6 address autoconf
# Request delegated prefix for LANset interfaces ethernet eth0 dhcpv6-options pd 0 interface eth1 sla-id '0'set interfaces ethernet eth0 dhcpv6-options pd 0 length '56'
commitThe sla-id lets you create multiple /64s from your delegated prefix. If you get a /56, you have 256 possible /64 subnets. sla-id ‘0’ means use the first one on eth1.
Validation step:
show interfaces ethernet eth0show interfaces ethernet eth1eth0 should have a global IPv6 address. eth1 should have an address from your delegated prefix (something like 2001:db8:1234::/64 depending on your ISP).
LAN Configuration: Router Advertisements
Unlike IPv4 where DHCP does everything, IPv6 clients learn about the network through Router Advertisements (RA). The router periodically broadcasts “I exist, here’s the prefix, here’s how to get addresses.”
configure
# Enable router advertisements on LANset service router-advert interface eth1 prefix ::/64set service router-advert interface eth1 name-server 2606:4700:4700::1111set service router-advert interface eth1 name-server 2001:4860:4860::8888
commitThe ::/64 prefix means “use whatever prefix is assigned to this interface.” VyOS automatically advertises the correct prefix.
Validation step: On a LAN client, check for IPv6 address.
# Linuxip -6 addr show
# macOSifconfig | grep inet6
# Windowsipconfig | findstr IPv6Clients should have a global IPv6 address (not just fe80:: link-local).
SLAAC vs DHCPv6: Understanding the Options
Two ways for clients to get IPv6 addresses:
SLAAC (Stateless Address Autoconfiguration)
- Client generates its own address from the prefix
- No server tracks who has what address
- Simple, but no central lease database
DHCPv6 (Stateful)
- Server assigns specific addresses
- Tracks leases like IPv4 DHCP
- More control, more complexity
For home networks, SLAAC is usually sufficient. The RA configuration above uses SLAAC by default.
If you need DHCPv6 (for address tracking or specific assignments):
configure
# Tell clients to also use DHCPv6 for addressesset service router-advert interface eth1 managed-flag
# DHCPv6 serverset service dhcpv6-server shared-network-name LAN subnet 2001:db8:1234::/64 range 0 start 2001:db8:1234::100set service dhcpv6-server shared-network-name LAN subnet 2001:db8:1234::/64 range 0 stop 2001:db8:1234::1ffset service dhcpv6-server shared-network-name LAN subnet 2001:db8:1234::/64 subnet-id 1
commitNote: Replace 2001:db8:1234::/64 with your actual delegated prefix.
The Firewall Problem
Here’s where most IPv6 setups break. IPv4 NAT accidentally provided security — nothing could reach internal hosts without explicit port forwards. IPv6 has no NAT (normally), so every device is directly addressable from the internet.
You MUST have proper firewall rules.
configure
# IPv6 firewall: WAN to LANset firewall ipv6 name WANv6-TO-LANv6 default-action 'drop'set firewall ipv6 name WANv6-TO-LANv6 rule 10 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 10 state 'established'set firewall ipv6 name WANv6-TO-LANv6 rule 10 state 'related'
# ICMPv6 is REQUIRED for IPv6 to functionset firewall ipv6 name WANv6-TO-LANv6 rule 20 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 20 protocol 'ipv6-icmp'
# IPv6 firewall: WAN to router (local)set firewall ipv6 name WANv6-LOCAL default-action 'drop'set firewall ipv6 name WANv6-LOCAL rule 10 action 'accept'set firewall ipv6 name WANv6-LOCAL rule 10 state 'established'set firewall ipv6 name WANv6-LOCAL rule 10 state 'related'set firewall ipv6 name WANv6-LOCAL rule 20 action 'accept'set firewall ipv6 name WANv6-LOCAL rule 20 protocol 'ipv6-icmp'set firewall ipv6 name WANv6-LOCAL rule 30 action 'accept'set firewall ipv6 name WANv6-LOCAL rule 30 protocol 'udp'set firewall ipv6 name WANv6-LOCAL rule 30 destination port '546'set firewall ipv6 name WANv6-LOCAL rule 30 source port '547'
# LAN to WAN: allow outboundset firewall ipv6 name LANv6-TO-WANv6 default-action 'accept'
# Apply to forward/input chainsset firewall ipv6 forward filter default-action 'accept'set firewall ipv6 forward filter rule 10 inbound-interface name 'eth0'set firewall ipv6 forward filter rule 10 action 'jump'set firewall ipv6 forward filter rule 10 jump-target 'WANv6-TO-LANv6'
set firewall ipv6 input filter default-action 'drop'set firewall ipv6 input filter rule 10 inbound-interface name 'eth0'set firewall ipv6 input filter rule 10 action 'jump'set firewall ipv6 input filter rule 10 jump-target 'WANv6-LOCAL'
commitCritical: ICMPv6 Must Be Allowed
Unlike IPv4 where you could (unwisely) block all ICMP, IPv6 requires ICMPv6 for:
- Neighbor Discovery (ND): IPv6’s replacement for ARP
- Router Advertisements: How clients find the gateway
- Path MTU Discovery: Essential for connectivity
- Duplicate Address Detection: Prevents IP conflicts
Blocking ICMPv6 = broken IPv6. Rule 20 in the firewall above allows all ICMPv6. You can be more restrictive:
# More restrictive ICMPv6 (still functional)set firewall ipv6 name WANv6-TO-LANv6 rule 20 icmpv6 type 'echo-request'set firewall ipv6 name WANv6-TO-LANv6 rule 21 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 21 protocol 'ipv6-icmp'set firewall ipv6 name WANv6-TO-LANv6 rule 21 icmpv6 type 'destination-unreachable'set firewall ipv6 name WANv6-TO-LANv6 rule 22 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 22 protocol 'ipv6-icmp'set firewall ipv6 name WANv6-TO-LANv6 rule 22 icmpv6 type 'packet-too-big'set firewall ipv6 name WANv6-TO-LANv6 rule 23 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 23 protocol 'ipv6-icmp'set firewall ipv6 name WANv6-TO-LANv6 rule 23 icmpv6 type 'time-exceeded'NAT66: When You Actually Need It
Pure IPv6 doesn’t need NAT. But sometimes you’re stuck:
- ISP only gives you a /64 and you need multiple subnets
- Privacy concerns about exposing internal addressing
- Translating between different IPv6 ranges
NAT66 (IPv6-to-IPv6 NAT) is available but should be a last resort:
configure
# NAT66 - use only if absolutely necessaryset nat66 source rule 100 outbound-interface name 'eth0'set nat66 source rule 100 source prefix 'fd00::/64'set nat66 source rule 100 translation address 'masquerade'
commitThis would NAT your ULA (fd00::/64) internal addresses to your public prefix. Again, avoid this if possible — it defeats IPv6’s end-to-end connectivity benefits.
Debugging IPv6 Issues
When IPv6 breaks, here’s the diagnostic flow:
1. Check Interface Addressing
show interfacesBoth WAN and LAN need global IPv6 addresses (not just fe80:: link-local).
2. Verify Router Advertisements
# On VyOSshow ipv6 route
# On Linux clientrdisc6 eth0If RA isn’t working, clients won’t get addresses or know the default gateway.
3. Check Neighbor Discovery
# On VyOSshow ipv6 neighbors
# On Linux clientip -6 neigh showND is like ARP for IPv6. Missing entries mean L2 connectivity issues or firewall blocking.
4. Test Connectivity Layer by Layer
# From VyOS: can we reach the internet?ping 2600:: -c 3
# From client: can we reach the gateway?ping6 fe80::1%eth0
# From client: can we reach the internet?ping6 google.com5. Check Firewall Counters
show firewall ipv6 name WANv6-TO-LANv6show firewall ipv6 name WANv6-LOCALHigh drop counts on specific rules indicate what’s being blocked.
Common Issues and Fixes
| Symptom | Likely Cause | Fix |
|---|---|---|
| No global address on LAN client | RA not working | Check router-advert config, verify eth1 has global address |
| Can ping gateway but not internet | Missing default route or firewall | Check show ipv6 route, verify firewall allows outbound |
| Intermittent connectivity | ICMPv6 blocked | Allow ICMPv6 in firewall |
| Works then stops after minutes | DAD failure or RA timeout | Check RA interval, look for duplicate addresses |
| DHCPv6 not assigning addresses | Missing managed-flag in RA | Set managed-flag on router-advert interface |
Privacy Extensions
By default, SLAAC creates addresses based on MAC address — potentially trackable. Modern systems use Privacy Extensions (RFC 4941) to generate random addresses.
VyOS can control this via RA:
# Suggest clients use privacy addressesset service router-advert interface eth1 prefix ::/64 preferred-lifetime '14400'set service router-advert interface eth1 prefix ::/64 valid-lifetime '86400'Shorter lifetimes encourage address rotation. Client OS controls whether to actually use privacy extensions.
Complete IPv6 Configuration
# WAN: DHCPv6-PDset interfaces ethernet eth0 ipv6 address autoconfset interfaces ethernet eth0 dhcpv6-options pd 0 interface eth1 sla-id '0'set interfaces ethernet eth0 dhcpv6-options pd 0 length '56'
# LAN: Router Advertisementsset service router-advert interface eth1 prefix ::/64set service router-advert interface eth1 name-server 2606:4700:4700::1111set service router-advert interface eth1 name-server 2001:4860:4860::8888
# Firewall: WAN inboundset firewall ipv6 name WANv6-TO-LANv6 default-action 'drop'set firewall ipv6 name WANv6-TO-LANv6 rule 10 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 10 state 'established'set firewall ipv6 name WANv6-TO-LANv6 rule 10 state 'related'set firewall ipv6 name WANv6-TO-LANv6 rule 20 action 'accept'set firewall ipv6 name WANv6-TO-LANv6 rule 20 protocol 'ipv6-icmp'
# Firewall: WAN to localset firewall ipv6 name WANv6-LOCAL default-action 'drop'set firewall ipv6 name WANv6-LOCAL rule 10 action 'accept'set firewall ipv6 name WANv6-LOCAL rule 10 state 'established'set firewall ipv6 name WANv6-LOCAL rule 10 state 'related'set firewall ipv6 name WANv6-LOCAL rule 20 action 'accept'set firewall ipv6 name WANv6-LOCAL rule 20 protocol 'ipv6-icmp'set firewall ipv6 name WANv6-LOCAL rule 30 action 'accept'set firewall ipv6 name WANv6-LOCAL rule 30 protocol 'udp'set firewall ipv6 name WANv6-LOCAL rule 30 destination port '546'set firewall ipv6 name WANv6-LOCAL rule 30 source port '547'
# Firewall: LAN outboundset firewall ipv6 name LANv6-TO-WANv6 default-action 'accept'
# Apply firewall to forward/input chainsset firewall ipv6 forward filter default-action 'accept'set firewall ipv6 forward filter rule 10 inbound-interface name 'eth0'set firewall ipv6 forward filter rule 10 action 'jump'set firewall ipv6 forward filter rule 10 jump-target 'WANv6-TO-LANv6'
set firewall ipv6 input filter default-action 'drop'set firewall ipv6 input filter rule 10 inbound-interface name 'eth0'set firewall ipv6 input filter rule 10 action 'jump'set firewall ipv6 input filter rule 10 jump-target 'WANv6-LOCAL'The Lesson
IPv6 doesn’t break mysteriously. When it fails, check in order:
- RA configuration: Is the router advertising the prefix?
- Firewall rules: Is ICMPv6 allowed? Is DHCPv6 (port 546/547) allowed for WAN-local?
- Prefix delegation: Did the router actually receive a prefix from the ISP?
Once you understand that RA replaces much of what DHCP does in IPv4, and that ICMPv6 is mandatory (not optional), IPv6 becomes predictable. The debugging is different, but the methodology is the same: verify each layer, check what’s being blocked, and read the counters.