NeuroAgent

IPv6 Routing Configuration on OpenWrt with WireGuard

Solving IPv6 routing issues on OpenWrt with WireGuard tunnel. Configuring proper interface metrics and route settings for IPv6 traffic through the tunnel.

Why isn’t the IPv6 route working on OpenWrt?

I have a router with OpenWrt (latest firmware 24.10.2) with a real IPv6 address. I have configured a WireGuard tunnel to MikroTik (which doesn’t have a real IPv6 address), and I’m trying to route traffic through OpenWrt.

The network behind MikroTik: fd03:0:0:1::/64 for MikroTik clients
WireGuard interfaces: fd02:0:0:1::1 (OpenWrt) and fd02:0:0:1::2 (MikroTik)

From the OpenWrt router, I can ping the MikroTik network and the WireGuard tunnel interfaces, and everything works. Also, from MikroTik, ping and traceroute work without any issues.

However, from the network behind OpenWrt, pings only reach the WireGuard tunnel interfaces on both sides (from the OpenWrt side and MikroTik side), but when trying to ping the network behind MikroTik, the route goes to the internet. That is, the configured IPv6 traffic routing rules only work directly from the OpenWrt router and are ignored for clients.

It seems like the reason for ignoring IPv6 routing is related to the metric number, but I can’t figure out how to configure this.

Current routing:

ip -6 route
fd03:0:0:1::/64 from fd02:0:0:1::1 via fd02:0:0:1::2 dev wg0 proto static metric 1 mtu 1420 pref medium
NeuroAgent

IPv6 Routing Problem with WireGuard on OpenWrt: Interface Metric Issues

The IPv6 routing issue with WireGuard on OpenWrt is related to incorrect interface metric settings. By default, the WireGuard interface has a metric of 1024, making it less prioritized than standard IPv6 routes with a metric of 512. This causes traffic from the local network to go directly to the internet instead of through the tunnel.

Table of Contents

Understanding the Metric Problem

The main issue with IPv6 routing in your configuration lies in the interface metric parameters. As research shows, in OpenWrt by default:

  • The WireGuard interface has a metric of 1024
  • The standard provider IPv6 gateway has a metric of 512
  • The standard provider IPv4 gateway has a metric of 0

Because of this, the router prefers to use the provider’s IPv6 gateway with a lower metric (512) rather than the WireGuard tunnel with a metric of 1024. This explains why IPv6 through WireGuard works from the router itself (where a static route with metric 1 is used), but traffic from the local network goes directly to the internet.

Important: Metric is a route priority value. The lower the metric value, the higher the priority of the route.

Configuring Correct Metrics for WireGuard

To fix the metric issue, you need to configure the WireGuard interface with a lower metric than the standard IPv6 gateway. Here’s a step-by-step guide:

1. Check Current Metrics

bash
ip -6 route show

You should see something like:

default via fe80::xxx dev eth0 proto ra metric 512 expires ...
fd03:0:0:1::/64 from fd02:0:0:1::1 via fd02:0:0:1::2 dev wg0 proto static metric 1 mtu 1420 pref medium

2. Change WireGuard Interface Metric

Add the metric for the WireGuard interface to the OpenWrt network configuration:

bash
uci set network.wg0.metric='1024'

However, as shown in research on WireGuard issues on OpenWrt, simply changing the WireGuard metric to 1024 doesn’t solve the problem, as the provider’s IPv6 gateway has a metric of 512. You need to set the WireGuard metric lower:

bash
uci set network.wg0.metric='512'

3. Configure Route with Correct Metric

Ensure that the route to the MikroTik network has a lower metric than the standard IPv6 gateway:

bash
# Add route with metric 100 (lower than 512)
ip -6 route add fd03:0:0:1::/64 via fd02:0:0:1::2 dev wg0 metric 100

Verifying and Configuring AllowedIPs

As noted in research, proper configuration of AllowedIPs is critical for IPv6 to work through WireGuard. On the MikroTik side, ensure that the correct prefix is specified in the WireGuard peer settings:

AllowedIPs = fd03:0:0:1::/64, fd02:0:0:1::/64

Critically Important: Be sure to include the /64 suffix, otherwise the server will treat this as a single address rather than a subnet.

On the OpenWrt side, the MikroTik network should also be specified in the WireGuard configuration:

[Interface]
Address = fd02:0:0:1::1/64
PrivateKey = ...

[Peer]
PublicKey = ...
AllowedIPs = fd03:0:0:1::/64

Additional IPv6 Configuration Parameters

Sometimes the issue may be related to additional IPv6 configuration parameters. Let’s look at several important settings:

1. Disable IPv6 Source Routing

If you’re experiencing routing issues, try disabling IPv6 source routing:

bash
uci set network.ipv6.sourcefilter='0'
uci commit network
/etc/init.d/network restart

As one user noted in a setup experience report, this can help with routing problems.

2. Configure RA (Router Advertisement)

Sometimes the issue may be related to Router Advertisement. Check your interface settings:

bash
# Disable RA on WireGuard interface if not needed
uci set network.wg0.ra='0'

3. Check Firewall Rules

Ensure that IPv6 traffic through the WireGuard interface is allowed in the firewall:

bash
# Allow IPv6 on WireGuard interface
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-WireGuard-IPv6'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest='wg0'
uci set firewall.@rule[-1].proto='all'
uci set firewall.@rule[-1].family='ipv6'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart

Complete Configuration Example

Here’s a complete example of /etc/config/network configuration for your situation:

config interface 'loopback'
    option ifname 'lo'
    option proto 'static'
    option ipaddr '127.0.0.1'
    option netmask '255.0.0.0'

config globals 'globals'
    option ula_prefix 'fd12:3456:789a::/48'

config interface 'lan'
    option type 'bridge'
    option ifname 'eth0'
    option proto 'static'
    option ipaddr '192.168.1.1'
    option netmask '255.255.255.0'
    option ip6assign '60'

config interface 'wan'
    option ifname 'eth1'
    option proto 'dhcp'
    option peerdns '0'
    option dns '192.168.1.1 8.8.8.8 1.1.1.1'

config interface 'wan6'
    option ifname 'eth1'
    option proto 'dhcpv6'
    option reqaddress 'try'
    option reqprefix 'auto'
    option peerdns '0'
    option dns '192.168.1.1 2001:4860:4860::8888 2606:4700:4700::1111'

config interface 'wg0'
    option proto 'wireguard'
    option private_key 'YOUR_PRIVATE_KEY'
    option metric '100'
    list addresses 'fd02:0:0:1::1/64'
    list addresses '192.168.9.1/24'

config wireguard_wg0
    option public_key 'MIKROTIK_PUBLIC_KEY'
    option allowedips 'fd03:0:0:1::/64, 192.168.88.0/24'
    option endpoint_host 'YOUR_MIKROTIK_IP'
    option endpoint_port '51820'
    option persistent_keepalive '25'

The corresponding firewall configuration:

config defaults
    option syn_flood '1'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'REJECT'

config zone
    option name 'lan'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'
    option network 'lan wg0'

config zone
    option name 'wan'
    option input 'REJECT'
    option output 'ACCEPT'
    option forward 'REJECT'
    option masq '1'
    option mtu_fix '1'
    option network 'wan wan6'

config forwarding
    option src 'lan'
    option dest 'wan'

Troubleshooting

If the problem persists, perform the following diagnostic steps:

1. Check Routes

bash
# Show all IPv6 routes
ip -6 route show

# Show routing table for specific prefix
ip -6 route get fd03:0:0:1::1

2. Check Interface Status

bash
# Show WireGuard interface status
wg show

# Show IPv6 addresses of interfaces
ip -6 addr show

3. Check Ping and Traceroute

bash
# From a device on the OpenWrt network
ping6 fd03:0:0:1::1
ping6 8.8.8.8

# traceroute for path diagnostics
traceroute6 fd03:0:0:1::1

4. Check Firewall Rules

bash
# Show active firewall rules for IPv6
iptables -t filter -L -v -n -6

5. Error Logging

Enable detailed logging for diagnostics:

bash
# Check network logs
logread | grep -i wireguard

# Check IPv6 logs
logread | grep -i ipv6

Sources

  1. GitHub Issue: Metric of Wireguard interface is 1024
  2. OpenWrt Forum: How to setup Wireguard with IPv6-PD
  3. LowEndTalk: Unable to route IPv6 through Wireguard on OpenWRT router
  4. hrna.moe: My experience with setting up IPv6 only Wireguard client on OpenWrt
  5. aparcar.org: OpenWrt with Wireguard VPN (IPv6)
  6. Reddit: IPv6 and WireGuard help

Conclusion

To resolve the IPv6 routing issue on OpenWrt with WireGuard, perform the following key steps:

  1. Configure correct metrics: Set the WireGuard interface metric lower than the standard IPv6 gateway (e.g., 100 instead of 512)
  2. Check AllowedIPs: Ensure that IPv6 prefixes with /64 suffix are correctly specified on both sides of the tunnel
  3. Disable IPv6 source routing: This can help with routing issues
  4. Configure firewall: Allow IPv6 traffic through the WireGuard interface
  5. Use static routes: Add an explicit route with a lower metric

The main reason for your problem is that the standard provider IPv6 gateway has a higher priority (lower metric) than the WireGuard tunnel. After configuring the correct metrics, routing should work correctly.