Skip to content

omr-admin.py writes invalid OMR_ADDR=fd00::a00:2/126 to /etc/shorewall6/params.vpn, breaks shorewall6 compile and IPv6 path #4288

@LadaBr

Description

@LadaBr

Expected Behavior

omr-admin.py writes /etc/shorewall6/params.vpn with a syntactically valid value for OMR_ADDR whenever it regenerates the file (whether triggered by initial IPv6 activation, switching the VPN backend, modifying users, or any other code path that calls the regen function). Shorewall6 then compiles its ruleset cleanly, IPv6 NAT66 + forwarding remain functional, and the 6in4 tunnel works bidirectionally.

For Shorewall6 DNAT rules, OMR_ADDR must be a single host specification (e.g. fd00::a00:2 or fd00::a00:2/128), since it is referenced as vpn:$OMR_ADDR in /etc/shorewall6/rules (single-host context, not a network).

Current Behavior

Every time omr-admin.py regenerates /etc/shorewall6/params.vpn, it deterministically writes a malformed value:

OMR_ADDR=fd00::a00:2/126

This is an invalid host specification because the host bits are non-zero (::a00:2) while the netmask declares a network (/126). Any subsequent shorewall6 start/reload/restart then fails to compile its ruleset with:

Compiling /etc/shorewall6/rules...
   ERROR: Unknown Host (fd00::a00:2/126) /etc/shorewall6/rules (line 63)

Line 63 is the auto-generated DNAT rule:

DNAT  net  vpn:$OMR_ADDR  udp  51820  # OMR openmptcprouter redirect router 51820 port udp

Result: Shorewall6 stays in Cleared / stopped state. Because IP_FORWARDING=On is configured in /etc/shorewall6/shorewall6.conf and is applied by Shorewall6 at start, with Shorewall6 stopped net.ipv6.conf.all.forwarding falls to 0 and the IPv6 path collapses:

  • 6in4 tunnel omr-6in4-user0 becomes a one-way blackhole (TX > 0, RX = 0). Decapsulated IPv6 packets from clients cannot be forwarded out ens18, and replies (which would arrive via the default IPv6 route on ens18) cannot be forwarded back into the tunnel.
  • NAT66 / SNAT rules from /etc/shorewall6/snat (which would normally MASQUERADE fd00::/8 and fe80::/10 out $NET_IFACE) are not active.
  • LAN clients lose IPv6 internet access via the VPS path.
  • On OMR, Unbound recursive DNS attempts queries to authoritative servers over IPv6 (do-ip6: yes by default), which time out repeatedly through the broken tunnel before falling back to IPv4. Cold-cache lookups exhibit ~10s latency, hitting default upstream timeout.
  • End-user symptom: very slow page loads ("first byte" stalls of 5–10s), even though bandwidth and connectivity tests appear normal.

shorewall6 status confirms the failure mode:

Shorewall6 5.2.8 Status at vps - <date> 2026
Shorewall6 is stopped
State:Cleared <timestamp matching the most recent params.vpn regeneration>

The bug is reproducible across multiple unrelated triggers — manually fixing params.vpn once does not prevent it from coming back the next time omr-admin.py regenerates the file.

Possible Solution

In /usr/bin/omr-admin.py, the four lines that write OMR_ADDR and OMR_ADDR_USERn to /etc/shorewall6/params.vpn hardcode the /126 suffix. Lines 3465, 3468, 3472, 3474 (in current head):

n.write('OMR_ADDR_USER' + str(userid) + '=fd00::a0' + hex(userid)[2:] + ':2/126' + '\n')
n.write('OMR_ADDR=fd00::a0' + hex(userid)[2:] + ':2/126' + '\n')
n.write('OMR_ADDR_USER' + str(userid) + '=fd00::a0' + hex(userid)[2:] + ':2/126' + '\n')
n.write('OMR_ADDR=fd00::a0' + hex(userid)[2:] + ':2/126' + '\n')

Suggested fix: drop the /126 suffix on these four lines so the value is a bare host address, consistent with how the IPv4 sibling code at line 3448 writes OMR_ADDR= (no prefix):

n.write('OMR_ADDR_USER' + str(userid) + '=fd00::a0' + hex(userid)[2:] + ':2' + '\n')
n.write('OMR_ADDR=fd00::a0' + hex(userid)[2:] + ':2' + '\n')
n.write('OMR_ADDR_USER' + str(userid) + '=fd00::a0' + hex(userid)[2:] + ':2' + '\n')
n.write('OMR_ADDR=fd00::a0' + hex(userid)[2:] + ':2' + '\n')

Important: line 3423 in the same file writes REMOTEIP6=fd00::a0X:2/126 — that one is correct and must NOT be changed, since the /126 is the legitimate prefix length for the 6in4 tunnel network.

A targeted sed is safe and leaves REMOTEIP6 untouched:

sed -i "/OMR_ADDR/s|':2/126'|':2'|g" /usr/bin/omr-admin.py
systemctl restart omr-admin

After applying the patch, shorewall6 start succeeds, IPv6 forwarding is enabled by Shorewall6, the 6in4 tunnel becomes bidirectional, and IPv6 / DNS recursion latency normalizes (~200–400ms cold-cache instead of ~10s).

Steps to Reproduce the Problem

The bug fires on any code path that calls the function regenerating /etc/shorewall6/params.vpn. Confirmed triggers:

  1. Initial IPv6 activation — first time the 6in4 tunnel and IPv6 path are set up on a fresh OMR + VPS install.
  2. Switching the VPN backend — e.g. changing from glorytun-udp to mlvpn and applying.
  3. (Likely also) modifying user IPv6 config or any other action that calls the same regen path.

After any of the above:

  1. On VPS, cat /etc/shorewall6/params.vpn contains OMR_ADDR=fd00::a00:2/126.
  2. On VPS, shorewall6 status reports stopped.
  3. On VPS, shorewall6 start fails with ERROR: Unknown Host (fd00::a00:2/126) /etc/shorewall6/rules (line 63).
  4. From OMR, ping6 -c 4 2606:4700:4700::1111 fails 100%; from LAN clients, IPv6 connectivity is broken (or only works through other accidental fallback paths); cold-cache DNS lookups stall ~10s.

Manually editing /etc/shorewall6/params.vpn to remove /126 and starting shorewall6 resolves the immediate breakage, but the file is overwritten with the broken value on the next regeneration trigger, so the manual fix does not persist.

Context (Environment)

I have hit this bug at least twice independently:

  1. First time, when initially activating IPv6 on the OMR + VPS setup. I fixed params.vpn by hand and didn't realize the root cause was in omr-admin.py at the time.
  2. Second time, after switching the VPN backend from glorytun-udp to mlvpn to address bonding behavior on my multi-WAN setup. The regen wrote /126 again and Shorewall6 stayed down for ~22 hours before I noticed the cascading symptom of slow DNS / web browsing (multi-second TTFB stalls while bandwidth tested fine). Tracing led from "slow DNS" → "Unbound recursion timing out on IPv6" → "OMR IPv6 outbound dead" → "Shorewall6 stopped on VPS" → this bug.

That this happens on entirely unrelated triggers and produces an identical broken output strongly suggests the regenerator function is unconditionally formatting the address with /126, regardless of caller.

Specifications

  • OpenMPTCProuter version: openmptcprouter v0.63-6.12 r0+30806-070d8eb
  • OpenMPTCProuter VPS version: 0.16+20260113
  • OpenMPTCProuter VPS provider: zonercloud.cz
  • OpenMPTCProuter platform: x86_64
  • Country: CZ

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions