fc8388bdbddc24118c347f2b72d47de23a2952d0
howto/mikrotik/modern-style-WIP.md
| ... | ... | @@ -1 +1,174 @@ |
| 1 | -This page is a scratchpad for a fully modernised (2026) config running on the latest version of RouterOS (7.22.1). It will use wireguard, BGP with Multihop and Extended Nexthop, and link-local addressing for address space efficiency. |
|
| ... | ... | \ No newline at end of file |
| 0 | +This page is a scratchpad for a fully modernised (2026) config running on the latest version of RouterOS (7.22.1). It will use wireguard, BGP with Multihop and Extended Nexthop, and link-local addressing for address space efficiency. |
|
| 1 | + |
|
| 2 | + |
|
| 3 | +Wireguard tunnel setup |
|
| 4 | +==== |
|
| 5 | + |
|
| 6 | +Wireguard seems to be the most popular option for peering now, so we'll use that. The first step is to setup a Wireguard interface. You can use a single interface for all connections if you want, but I prefer to make one for each peer, as it can make problems easier to debug. |
|
| 7 | + |
|
| 8 | +For the sake of this example we'll pretend we're peering with Kioubit, one of the most-connected and easiest to connect-with systems on DN42. |
|
| 9 | + |
|
| 10 | +Create the interface |
|
| 11 | +---- |
|
| 12 | + |
|
| 13 | +We have to do this first so we can gather the connection details, which will be used to setup the peering. |
|
| 14 | + |
|
| 15 | +The standard port for Wireguard listeners is 51820, but you can use anything you like. An MTU of 1420 is recommended to avoid fragmentation and firewall issues. |
|
| 16 | + |
|
| 17 | +``` |
|
| 18 | +/interface wireguard |
|
| 19 | +add name=DN42-KIOUBIT listen-port=51820 mtu=1420 |
|
| 20 | +``` |
|
| 21 | + |
|
| 22 | +Without any extra parameters, it'll automatically generate a new private and public key for you. Grab the public key, you'll need that to setup your peering connection. |
|
| 23 | +``` |
|
| 24 | +/interface/wireguard/print where name="DN42-KIOUBIT" |
|
| 25 | + |
|
| 26 | +[furinkan@helian] > /interface/wireguard/print where name="DN42-KIOUBIT" |
|
| 27 | + 0 R name="DN42-KIOUBIT" mtu=1420 listen-port=51820 public-key="mGRGoKPl6fRffzUovFp/8AoOtHjCrWeEMN9/9NsVp2Q=" |
|
| 28 | +``` |
|
| 29 | + |
|
| 30 | +Exchange connection parameters |
|
| 31 | +---- |
|
| 32 | + |
|
| 33 | +If connecting to a system with a self-serve automatic peering interface, now is the time to use it. |
|
| 34 | + |
|
| 35 | +You will need: |
|
| 36 | +* Your AS number |
|
| 37 | +* Your public IP address that they can connect to |
|
| 38 | +* Your listening port for Wireguard, eg. 51820 as above |
|
| 39 | +* Your public key for your Wireguard interface |
|
| 40 | +* An IPv4 address for your local end of the tunnel, this is often an address in your DN42 address allocation, but can also be any private-range address like 192.168.x.x; however this may be optional if you use... |
|
| 41 | +* An IPv6 address for your local end of the tunnel. Unlike IPv4, it's possible to use a pure link-local address, like `fe80::1234` |
|
| 42 | +* To know if your BGP daemon supports the Multihop and Extended Next Hop capabilities |
|
| 43 | + |
|
| 44 | +You will receive: |
|
| 45 | +* Their AS number |
|
| 46 | +* Their public IP address and port to use for the wireguard connection |
|
| 47 | +* Their Wireguard public key |
|
| 48 | +* The IPv4 and/or IPv6 address for the remote end of the tunnel |
|
| 49 | + |
|
| 50 | +Add the Wireguard peer |
|
| 51 | +---- |
|
| 52 | + |
|
| 53 | +``` |
|
| 54 | +/interface wireguard peers |
|
| 55 | +add name=DN42-KIOUBIT interface=<THE_INTERFACE_YOU_CREATED_EARLIER> endpoint-address=<THEIR_PUBLIC_ADDRESS> endpoint-port=<THEIR_WIREGUARD_PORT> public-key="<THEIR_WIREGUARD_PUBLIC_KEY>" allowed-address=fd00::/8,fe80::/10,172.20.0.0/14 |
|
| 56 | +``` |
|
| 57 | + |
|
| 58 | +At this point the tunnel should come up on its own, assuming the other end is already configured. However, it's not useful yet without an IP address attached to it. |
|
| 59 | + |
|
| 60 | +Add an IP address to your end of the tunnel |
|
| 61 | +---- |
|
| 62 | + |
|
| 63 | +Once the tunnel is established you will need an address at each end of the link for routing to work. In this Kioubit example we only need an IPv6 address, because we can route IPv4 traffic between IPv6 BGP peers. |
|
| 64 | + |
|
| 65 | +Kioubit is using fe80::ade0 on the remote end of the tunnel. We also chose a link-local address for our end of the tunnel, it's `fe80::` plus the last four digits of our AS number. You'll notice that the remote address does not need to be adjacent at all - this is the beauty of IPv6 link-local addressing. |
|
| 66 | +``` |
|
| 67 | +/ipv6 address |
|
| 68 | +add address=fe80::2762/128 interface=DN42-KIOUBIT advertise=no |
|
| 69 | +``` |
|
| 70 | + |
|
| 71 | +If you're using an IPv4 address, you can attach it to the loopback interface. This allows the address to be reused for multiple peering connections, without being "owned" by any of the wireguard interfaces. |
|
| 72 | +``` |
|
| 73 | +/ip/address |
|
| 74 | +add address=172.31.254.254 interface=lo |
|
| 75 | +``` |
|
| 76 | + |
|
| 77 | +Test connectivity |
|
| 78 | +---- |
|
| 79 | + |
|
| 80 | +You should be able to ping the remote end of the tunnel now. If so, packets can make it there and back, correctly routed. Notice that we're appending the interface name to the IP address. This is necessary for IPv6 link-local addresses because the system doesn't know which interface to send the pings out of. |
|
| 81 | +``` |
|
| 82 | +[furinkan@helian] > ping fe80::ade0%DN42-KIOUBIT |
|
| 83 | + SEQ HOST SIZE TTL TIME STATUS |
|
| 84 | + 0 fe80::ade0 56 64 133ms383us echo reply |
|
| 85 | + 1 fe80::ade0 56 64 136ms229us echo reply |
|
| 86 | + sent=2 received=2 packet-loss=0% min-rtt=133ms383us avg-rtt=134ms806us max-rtt=136ms229us |
|
| 87 | +``` |
|
| 88 | + |
|
| 89 | +If you're using IPv4 inside the tunnel, it'll look something like this: |
|
| 90 | +``` |
|
| 91 | +[furinkan@helian] > ping 172.20.53.105%DN42-KIOUBIT |
|
| 92 | + SEQ HOST SIZE TTL TIME STATUS |
|
| 93 | + 0 172.20.53.105 56 64 133ms544us |
|
| 94 | + 1 172.20.53.105 56 64 131ms672us |
|
| 95 | + 2 172.20.53.105 56 64 133ms521us |
|
| 96 | + sent=3 received=3 packet-loss=0% min-rtt=131ms672us avg-rtt=132ms912us max-rtt=133ms544us |
|
| 97 | +``` |
|
| 98 | + |
|
| 99 | +Notice that we specified the egress interface again, you don't normally do this with IPv4 addresses. The router doesn't know how to get to the destination because it doesn't belong to a known subnet - it doesn't have a route! |
|
| 100 | + |
|
| 101 | +We'll add a static route to fix this: |
|
| 102 | +``` |
|
| 103 | +/ip route |
|
| 104 | +add dst-address=172.20.53.105/32 gateway=DN42-KIOUBIT |
|
| 105 | + |
|
| 106 | +[furinkan@helian] > ping 172.20.53.105 |
|
| 107 | + SEQ HOST SIZE TTL TIME STATUS |
|
| 108 | + 0 172.20.53.105 56 64 131ms152us |
|
| 109 | + 1 172.20.53.105 56 64 131ms128us |
|
| 110 | + sent=2 received=2 packet-loss=0% min-rtt=131ms128us avg-rtt=131ms140us max-rtt=131ms152us |
|
| 111 | +``` |
|
| 112 | + |
|
| 113 | +That's better. Now we're ready for some BGP peering. |
|
| 114 | + |
|
| 115 | + |
|
| 116 | +Setup BGP |
|
| 117 | +==== |
|
| 118 | + |
|
| 119 | +We'll create an instance for DN42, some basic route filters for security, a template to hold common DN42 peering settings, then finally the actual peering connection. |
|
| 120 | + |
|
| 121 | +Instance |
|
| 122 | +---- |
|
| 123 | + |
|
| 124 | +An important part of the routing protocols is your router's ID, a 32-bit value usually written like an IPv4 address. It's common convention to use your router's IP address as the router ID, so we'll do that here too. I've picked the highest IP address in our IPv4 allocation as the router's IP, which we'll also use as the router's ID. |
|
| 125 | + |
|
| 126 | +This gives a text label to our router ID: |
|
| 127 | +``` |
|
| 128 | +/routing id |
|
| 129 | +add id=172.22.124.62 name=my-DN42-router select-dynamic-id="" |
|
| 130 | +``` |
|
| 131 | + |
|
| 132 | +Create the BGP instance, which will identify itself with your AS number: |
|
| 133 | +``` |
|
| 134 | +/routing bgp instance |
|
| 135 | +add as=424242<YOUR_ASN> name=DN42 router-id=my-DN42-router |
|
| 136 | +``` |
|
| 137 | + |
|
| 138 | +Route filters |
|
| 139 | +---- |
|
| 140 | + |
|
| 141 | +Filters are necessary to prevent other people from hijacking our routing table. A malicious peer could send routes that override your default route to public internet services like Google, government services, your online banking, etc. |
|
| 142 | + |
|
| 143 | +These rules are reasonably tight, you can tighten or relax them as desired. [Interconnected networks'](/internal/Interconnections) IPv4 ranges are included as well, if you don't want then you can ignore that rule. |
|
| 144 | +``` |
|
| 145 | +/routing filter rule |
|
| 146 | +add chain=dn42-in comment="reject prefixes clashing with home network" disabled=no rule="if (dst in 192.168.0.0/16 && dst-len >= 16) { reject }" |
|
| 147 | +add chain=dn42-in comment="reject v4 auto-addressing prefixes" rule="if (dst in 169.254.0.0/16 && dst-len >= 16) { reject }" |
|
| 148 | +add chain=dn42-in comment="accept DN42 v4 prefixes" disabled=no rule="if (dst in 172.20.0.0/14) { accept }" |
|
| 149 | +add chain=dn42-in comment="accept DN42 interconnected network v4 prefixes" disabled=no rule="if (dst in 10.0.0.0/8) { accept }" |
|
| 150 | +add chain=dn42-in comment="accept DN42 and interconnected v6 prefixes" disabled=no rule="if (dst in fd00::/8) { accept }" |
|
| 151 | +``` |
|
| 152 | + |
|
| 153 | +``` |
|
| 154 | +/routing filter rule |
|
| 155 | +add chain=dn42-out comment="don't advertise our home network" rule="if (dst in 192.168.0.0/16 && dst-len >= 16) { reject }" |
|
| 156 | +add chain=dn42-out comment="don't advertise v4 auto-addressing prefixes" rule="if (dst in 169.254.0.0/16 && dst-len >= 16) { reject }" |
|
| 157 | +add chain=dn42-out comment="tag my prefixes with community" disabled=no rule="if ( dst in 172.20.0.0/14 && bgp-communities-empty ) { append bgp-communities DN42-communities; }" |
|
| 158 | +add chain=dn42-out comment="advertise DN42 v4 prefixes" disabled=no rule="if (dst in 172.20.0.0/14) { accept }" |
|
| 159 | +add chain=dn42-out comment="advertise DN42 interconnected network v4 prefixes" disabled=no rule="if (dst in 10.0.0.0/8) { accept }" |
|
| 160 | +add chain=dn42-out comment="tag my IPv6 prefixes with community" disabled=no rule="if ( dst in fd00::/8 && bgp-communities-empty ) { append bgp-communities DN42-communities; }" |
|
| 161 | +add chain=dn42-out comment="advertise DN42 and interconnected v6 prefixes" disabled=no rule="if (dst in fd00::/8) { accept }" |
|
| 162 | +``` |
|
| 163 | + |
|
| 164 | +Connection template |
|
| 165 | +---- |
|
| 166 | + |
|
| 167 | +WIP |
|
| 168 | + |
|
| 169 | +Create a template with the common BGP settings used for DN42: |
|
| 170 | +``` |
|
| 171 | +/routing bgp template |
|
| 172 | +set DN42-thighhighs afi=ip,ipv6 as=424242<YOUR_ASN> input.filter=dn42-in multihop=yes name=DN42-thighhighs output.filter-chain=dn42-out .redistribute=connected,bgp routing-table=main |
|
| 173 | +``` |