Build log · MikroTik RB5009 · VPS-routed /48 · VyOS relay

VyOS relay for routed IPv6 over CGNAT

Same VPS-routed /48 design as the Ubuntu/BIRD path, implemented with VyOS WireGuard, BGP policy, and relay firewall rules.

Overview

This is the VyOS variant of the VPS path in the RB5009 CGNAT series: a self-operated VPS still routes a provider-delegated /48 over WireGuard and eBGP, but the relay is VyOS instead of Ubuntu + bird2 + nftables.

The MikroTik side is intentionally the same shape as the Linux VPS recipe: WireGuard is transport, BGP is routing intent, and the RB5009 advertises the home aggregate while learning only ::/0 from the VPS. The VyOS side replaces systemd services and hand-written config files with configure, commit, and save.

Use this when the VPS itself is becoming a router appliance. If the VPS is a general-purpose Linux host that merely relays IPv6, the Ubuntu/BIRD recipe is simpler to inspect with ordinary Linux tools.

Design decisions

Do not put the routed prefix on the VyOS WAN as /48. Some providers configure one address from the routed prefix on the public NIC with a /48 mask. On a relay, that creates a connected route for the entire home aggregate on the WAN. The route you actually want is the BGP-learned route to the RB5009 over WireGuard. In this VyOS variant, any address from the routed prefix on the VPS uses /128; the aggregate itself is learned from the MikroTik.

Use VyOS BGP policy instead of BIRD filters. The import side permits only <LAN_PREFIX>::/48 from the RB5009. The export side uses BGP default-originate, so the MikroTik sees a default route and not the VPS's provider-connected prefixes.

Keep the VPS firewall interface-based. The relay is still pure transit: SSH and WireGuard are allowed on the WAN, BGP is allowed only on wg0, and forwarded IPv6 can enter or leave wg0. Application policy remains on the RB5009.

1. Topology recap

                       Internet (IPv4 + IPv6)
                              │
                ┌─────────────┴─────────────┐
                │  VPS — VyOS, routed /48   │
                │  <VPS_IP> on <WAN_IF>     │
                │  wg0: <LAN_PREFIX>:0::1   │
                │  FRR: eBGP to RB5009      │
                └─────────────┬─────────────┘
                              │ WireGuard / UDP 51820
                              │ (IPv6 transit + eBGP)
                              │
                          RB5009 wg-vps
                          <LAN_PREFIX>:0::2

2. Conventions and placeholders

Series-wide placeholders (<ULA_PREFIX>) live in the index §2. This variant adds:

PlaceholderMeaning
<WAN_IF>VyOS public interface. On this VPS it is eth0; cloud-init may call the same MAC ens3.
<VPS_IP> / <VPS_PREFIXLEN>Provider IPv4 address and prefix length, e.g. 160.187.141.53/24.
<VPS_GW4>Provider IPv4 gateway.
<VPS_LINK_GUA>Provider IPv6 link address, if supplied as a /128.
<VPS_GW6>Provider IPv6 gateway.
<LAN_PREFIX>Routed IPv6 /48. Drop trailing zeros, e.g. 2001:db8 for 2001:db8::/48.
<VPS_PUBKEY> / <MT_PUBKEY>WireGuard public keys, one per side.
<VPS_AS> / <MT_AS>Private ASNs (RFC 6996, 64512–65534) for the eBGP session.
<VPS_ROUTER_ID>Any unique 32-bit router ID written like an IPv4 address.

If your provider metadata says the routed prefix address is <LAN_PREFIX>::a/48, configure it as <LAN_PREFIX>::a/128 on VyOS. The provider still routes the /48 to the VPS; VyOS does not need a connected WAN route for the whole aggregate.

3. Baseline VyOS networking

These commands assume you are on the provider console or already have a working SSH session. Keep console access open while applying firewall rules.

VyOS — provider addressing and SSH

bash

1configure 2 3set interfaces ethernet <WAN_IF> address <VPS_IP>/<VPS_PREFIXLEN> 4set interfaces ethernet <WAN_IF> address <VPS_LINK_GUA>/128 5set interfaces ethernet <WAN_IF> address <LAN_PREFIX>::a/128 6 7# Add the host routes only if your provider metadata declares the gateways 8# as on-link routes. They are harmless when the IPv4 gateway is already 9# inside the interface prefix. 10set protocols static route <VPS_GW4>/32 interface <WAN_IF> 11set protocols static route 0.0.0.0/0 next-hop <VPS_GW4> 12set protocols static route6 <VPS_GW6>/128 interface <WAN_IF> 13set protocols static route6 ::/0 next-hop <VPS_GW6> 14 15set service ssh port 22 16commit 17save 18exit

Verification before touching WireGuard:

VyOS — baseline checks

bash

1show interfaces ethernet 2show ip route 3show ipv6 route 4ping 1.1.1.1 5ping 2606:4700:4700::1111

4. VyOS — WireGuard and BGP

Create wg0, commit it once, then let VyOS generate and install the private key. The public key printed by show interfaces wireguard wg0 public-key becomes <VPS_PUBKEY> on the MikroTik.

VyOS — WireGuard relay

bash

1configure 2set interfaces wireguard wg0 address <LAN_PREFIX>:0::1/64 3set interfaces wireguard wg0 address fe80::1/64 4set interfaces wireguard wg0 mtu 1420 5set interfaces wireguard wg0 port 51820 6commit 7 8run generate pki wireguard key-pair install interface wg0 9run show interfaces wireguard wg0 public-key 10 11set interfaces wireguard wg0 peer rb5009 public-key <MT_PUBKEY> 12set interfaces wireguard wg0 peer rb5009 allowed-ips <LAN_PREFIX>:0::2/128 13set interfaces wireguard wg0 peer rb5009 allowed-ips <LAN_PREFIX>::/48 14commit 15save

The BGP policy accepts only the home aggregate from the RB5009 and sends only a default route back.

VyOS — BGP route exchange

bash

1configure 2 3set policy prefix-list6 MT-HOME-V6 rule 10 action permit 4set policy prefix-list6 MT-HOME-V6 rule 10 prefix <LAN_PREFIX>::/48 5 6set policy route-map MT-IN rule 10 action permit 7set policy route-map MT-IN rule 10 match ipv6 address prefix-list MT-HOME-V6 8set policy route-map MT-IN rule 100 action deny 9 10set protocols bgp system-as <VPS_AS> 11set protocols bgp parameters router-id <VPS_ROUTER_ID> 12set protocols bgp neighbor <LAN_PREFIX>:0::2 remote-as <MT_AS> 13set protocols bgp neighbor <LAN_PREFIX>:0::2 update-source wg0 14set protocols bgp neighbor <LAN_PREFIX>:0::2 address-family ipv6-unicast route-map import MT-IN 15set protocols bgp neighbor <LAN_PREFIX>:0::2 address-family ipv6-unicast default-originate 16set protocols bgp neighbor <LAN_PREFIX>:0::2 address-family ipv6-unicast nexthop-self 17 18commit 19save

5. VyOS — relay firewall

This is the equivalent of the Ubuntu recipe's nftables block. It keeps the public input surface small while letting the VPS route through wg0.

VyOS — minimal relay firewall

bash

1configure 2 3set firewall global-options state-policy established action accept 4set firewall global-options state-policy related action accept 5set firewall global-options state-policy invalid action drop 6 7set firewall ipv4 input filter default-action drop 8set firewall ipv4 input filter rule 10 action accept 9set firewall ipv4 input filter rule 10 protocol tcp 10set firewall ipv4 input filter rule 10 destination port 22 11set firewall ipv4 input filter rule 10 description SSH 12set firewall ipv4 input filter rule 20 action accept 13set firewall ipv4 input filter rule 20 protocol udp 14set firewall ipv4 input filter rule 20 destination port 51820 15set firewall ipv4 input filter rule 20 description WireGuard 16set firewall ipv4 input filter rule 30 action accept 17set firewall ipv4 input filter rule 30 protocol icmp 18set firewall ipv4 input filter rule 30 description ICMP 19 20set firewall ipv6 input filter default-action drop 21set firewall ipv6 input filter rule 10 action accept 22set firewall ipv6 input filter rule 10 protocol icmpv6 23set firewall ipv6 input filter rule 10 description ICMPv6 24set firewall ipv6 input filter rule 20 action accept 25set firewall ipv6 input filter rule 20 inbound-interface name wg0 26set firewall ipv6 input filter rule 20 protocol tcp 27set firewall ipv6 input filter rule 20 destination port 179 28set firewall ipv6 input filter rule 20 description 'BGP from RB5009' 29 30set firewall ipv6 forward filter default-action drop 31set firewall ipv6 forward filter rule 10 action accept 32set firewall ipv6 forward filter rule 10 inbound-interface name wg0 33set firewall ipv6 forward filter rule 10 description 'LAN to internet' 34set firewall ipv6 forward filter rule 20 action accept 35set firewall ipv6 forward filter rule 20 outbound-interface name wg0 36set firewall ipv6 forward filter rule 20 description 'internet return to LAN' 37 38commit 39save

If you also want the WireGuard listener reachable over IPv6 on the VPS public address, add a matching UDP/51820 rule under firewall ipv6 input filter. The CGNAT home line only needs outbound IPv4 UDP to the VPS, so the IPv4 rule is enough for the base build.

6. MikroTik — WireGuard client and BGP

This is the same RouterOS shape as the Ubuntu VPS post. The interface names below use wg-vps and vyos-vps so the VyOS relay stays easy to distinguish from the Ubuntu/BIRD variant in exports, logs, and follow-up BFD snippets. The home router initiates to the VPS, so the local listen port is not part of the provider-facing contract.

MikroTik — WireGuard + BGP to VyOS VPS

bash

1/interface/wireguard add name=wg-vps listen-port=51820 mtu=1420 2/interface/wireguard/peers add interface=wg-vps name=vyos-vps \ 3 public-key="<VPS_PUBKEY>" \ 4 endpoint-address=<VPS_IP> endpoint-port=51820 \ 5 allowed-address=::/0 \ 6 persistent-keepalive=25s 7 8/ipv6/address add address=<LAN_PREFIX>:0::2/64 interface=wg-vps advertise=no 9 10/ipv6/route add dst-address=<LAN_PREFIX>::/48 blackhole distance=254 \ 11 comment="aggregate-for-bgp" 12 13/ipv6/firewall/address-list add list=bgp-networks-vyos-vps \ 14 address=<LAN_PREFIX>::/48 comment="aggregate to VPS" 15 16/routing/filter/rule add chain=bgp-in-vyos-vps \ 17 rule="if (dst == ::/0) { accept } reject" 18/routing/filter/rule add chain=bgp-out-vyos-vps \ 19 rule="if (dst == <LAN_PREFIX>::/48) { accept } reject" 20 21/routing/bgp/instance add name=default-bgp as=<MT_AS> router-id=<MT_ROUTER_ID> 22/routing/bgp/template add name=tpl-vps as=<MT_AS> 23/routing/bgp/connection add name=vyos-vps instance=default-bgp \ 24 remote.address=<LAN_PREFIX>:0::1 remote.as=<VPS_AS> \ 25 local.address=<LAN_PREFIX>:0::2 local.role=ebgp \ 26 templates=tpl-vps afi=ipv6 \ 27 input.filter=bgp-in-vyos-vps \ 28 output.network=bgp-networks-vyos-vps output.filter-chain=bgp-out-vyos-vps

At this point the RB5009 should learn a BGP ::/0 over wg-vps, but LAN clients still need the Per-VLAN IPv6 post to receive GUAs. Use the same substitution as the Ubuntu VPS path: <GUA_LAN>=<LAN_PREFIX>:1, <GUA_IOT>=<LAN_PREFIX>:10, <GUA_GUEST>=<LAN_PREFIX>:20.

7. Verification

VyOS and MikroTik smoke tests

bash

1# VyOS: 2show interfaces wireguard 3show bgp ipv6 summary 4show bgp ipv6 <LAN_PREFIX>::/48 5show ipv6 route <LAN_PREFIX>::/48 6ping <LAN_PREFIX>:0::2 7 8# MikroTik: 9/interface/wireguard/peers/print detail where name=vyos-vps 10/routing/bgp/session/print 11/ipv6/route/print where dst-address=::/0 12/ping 2606:4700:4700::1111 count=3

The important return-routing check is on VyOS:

VyOS — return route should use wg0

bash

1run ip -6 route get <client-IPv6-addr>

Expect dev wg0, not dev <WAN_IF>. If the route points to the WAN, check that the VPS address from the routed prefix is configured as /128, not /48, and that the BGP session is importing <LAN_PREFIX>::/48 from the MikroTik.

References

Share

Comments

Comments are powered by GitHub Discussions and require a free GitHub account to post.