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.
Build log · MikroTik RB5009 · VPS-routed /48 · VyOS relay
Same VPS-routed /48 design as the Ubuntu/BIRD path, implemented with VyOS WireGuard, BGP policy, and relay firewall rules.
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.
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.
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
Series-wide placeholders (<ULA_PREFIX>) live in the
index §2. This variant adds:
| Placeholder | Meaning |
|---|---|
<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.
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
18exitVerification 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::1111Create 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
15saveThe 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
19saveThis 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
39saveIf 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.
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-vpsAt 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.
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=3The 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.
Comments
Comments are powered by GitHub Discussions and require a free GitHub account to post.