aca9d757dc4b2d4a53a3ede247c37dad902f6b34
howto/Bird2.md
| ... | ... | @@ -0,0 +1,198 @@ |
| 1 | +This guide is similar to the normal [Bird](/howto/Bird) guide in that it provides you with help setting up the BIRD routing daemon, with the difference that this page is dedicated to versions 2.x. |
|
| 2 | + |
|
| 3 | +# Arch Linux |
|
| 4 | + |
|
| 5 | +The `extra/bird` package in the arch repositories will usually have a relatively recent version and there is (usually) no need for a manual install over the usual `# pacman -S bird'. |
|
| 6 | + |
|
| 7 | +# Example configuration |
|
| 8 | + |
|
| 9 | +Please note: This example configuration is made for use with IPv4 and IPv6 (Really, there is no excuse not to get started with IPv6 networking! :) ) |
|
| 10 | + |
|
| 11 | +The default config location in bird version 2.x is `/etc/bird.conf`, but this may vary depending on how your distribution compiled bird. |
|
| 12 | + |
|
| 13 | +When copying the configuration below onto your system, you will have to enter the following values in the file header: |
|
| 14 | + |
|
| 15 | +* Replace `<OWNAS>` with your autonomous system number, e.g. `4242421234` |
|
| 16 | +* Replace `<OWNIP>` with the ip that your router is going to have, this is usually the first non-zero ip in your subnet. (E.g. x.x.x.65 in an x.x.x.64/28 network) |
|
| 17 | +* Similarly, replace `<OWNIPv6>` with the first non-zero ip in your ipv6 subnet. |
|
| 18 | +* Then replace `<OWNNET>` with the IPv4 subnet that was assigned to you. |
|
| 19 | +* The same goes for `<OWNNETv6>`, but it takes an IPv6 subnet (Who'd have thought). |
|
| 20 | +* Keep in mind that you'll have to enter both networks in the OWNNET{,v6} and OWNNETSET{,v6}, the two variables are required due to set parsing difficulties with variables. |
|
| 21 | +``` |
|
| 22 | +################################################ |
|
| 23 | +# Variable header # |
|
| 24 | +################################################ |
|
| 25 | + |
|
| 26 | +define OWNAS = <OWNAS>; |
|
| 27 | +define OWNIP = <OWNIP>; |
|
| 28 | +define OWNIPv6 = <OWNIPv6>; |
|
| 29 | +define OWNNET = <OWNNET>; |
|
| 30 | +define OWNNETv6 = <OWNNETv6>; |
|
| 31 | +define OWNNETSET = [<OWNNET>+]; |
|
| 32 | +define OWNNETSETv6 = [<OWNNETv6>+]; |
|
| 33 | + |
|
| 34 | +################################################ |
|
| 35 | +# Header end # |
|
| 36 | +################################################ |
|
| 37 | + |
|
| 38 | +router id OWNIP; |
|
| 39 | + |
|
| 40 | +protocol device { |
|
| 41 | + scan time 10; |
|
| 42 | +} |
|
| 43 | + |
|
| 44 | +/* |
|
| 45 | + * Utility functions |
|
| 46 | + */ |
|
| 47 | + |
|
| 48 | +function is_self_net() { |
|
| 49 | + return net ~ OWNNETSET; |
|
| 50 | +} |
|
| 51 | + |
|
| 52 | +function is_self_net_v6() { |
|
| 53 | + return net ~ OWNNETSETv6; |
|
| 54 | +} |
|
| 55 | + |
|
| 56 | +function is_valid_network() { |
|
| 57 | + return net ~ [ |
|
| 58 | + 172.20.0.0/14{21,29}, # dn42 |
|
| 59 | + 172.20.0.0/24{28,32}, # dn42 Anycast |
|
| 60 | + 172.21.0.0/24{28,32}, # dn42 Anycast |
|
| 61 | + 172.22.0.0/24{28,32}, # dn42 Anycast |
|
| 62 | + 172.23.0.0/24{28,32}, # dn42 Anycast |
|
| 63 | + 172.31.0.0/16+, # ChaosVPN |
|
| 64 | + 10.100.0.0/14+, # ChaosVPN |
|
| 65 | + 10.0.0.0/8{15,24} # Freifunk.net |
|
| 66 | + ]; |
|
| 67 | +} |
|
| 68 | + |
|
| 69 | +roa4 table dn42_roa; |
|
| 70 | +roa6 table dn42_roa_v6; |
|
| 71 | + |
|
| 72 | +protocol static { |
|
| 73 | + roa4 { table dn42_roa; }; |
|
| 74 | + include "/etc/bird/roa_dn42.conf"; |
|
| 75 | +}; |
|
| 76 | + |
|
| 77 | +protocol static { |
|
| 78 | + roa6 { table dn42_roa_v6; }; |
|
| 79 | + include "/etc/bird/roa_dn42_v6.conf"; |
|
| 80 | +}; |
|
| 81 | + |
|
| 82 | +function is_valid_network_v6() { |
|
| 83 | + return net ~ [ |
|
| 84 | + fd00::/8{44,64} # ULA address space as per RFC 4193 |
|
| 85 | + ]; |
|
| 86 | +} |
|
| 87 | + |
|
| 88 | +protocol kernel { |
|
| 89 | + scan time 20; |
|
| 90 | + |
|
| 91 | + ipv6 { |
|
| 92 | + import none; |
|
| 93 | + export filter { |
|
| 94 | + if source = RTS_STATIC then reject; |
|
| 95 | + krt_prefsrc = OWNIPv6; |
|
| 96 | + accept; |
|
| 97 | + }; |
|
| 98 | + }; |
|
| 99 | +}; |
|
| 100 | + |
|
| 101 | +protocol kernel { |
|
| 102 | + scan time 20; |
|
| 103 | + |
|
| 104 | + ipv4 { |
|
| 105 | + import none; |
|
| 106 | + export filter { |
|
| 107 | + if source = RTS_STATIC then reject; |
|
| 108 | + krt_prefsrc = OWNIP; |
|
| 109 | + accept; |
|
| 110 | + }; |
|
| 111 | + }; |
|
| 112 | +} |
|
| 113 | + |
|
| 114 | +protocol static { |
|
| 115 | + route OWNNET reject; |
|
| 116 | + |
|
| 117 | + ipv4 { |
|
| 118 | + import all; |
|
| 119 | + export none; |
|
| 120 | + }; |
|
| 121 | +} |
|
| 122 | + |
|
| 123 | +protocol static { |
|
| 124 | + route OWNNETv6 reject; |
|
| 125 | + |
|
| 126 | + ipv6 { |
|
| 127 | + import all; |
|
| 128 | + export none; |
|
| 129 | + }; |
|
| 130 | +} |
|
| 131 | + |
|
| 132 | +template bgp dnpeers { |
|
| 133 | + local as OWNAS; |
|
| 134 | + path metric 1; |
|
| 135 | + |
|
| 136 | + ipv4 { |
|
| 137 | + import filter { |
|
| 138 | + if is_valid_network() && !is_self_net() then { |
|
| 139 | + if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then { |
|
| 140 | + print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; |
|
| 141 | + reject; |
|
| 142 | + } else accept; |
|
| 143 | + } else reject; |
|
| 144 | + }; |
|
| 145 | + |
|
| 146 | + export filter { if is_valid_network() then accept; else reject; }; |
|
| 147 | + import limit 1000 action block; |
|
| 148 | + }; |
|
| 149 | + |
|
| 150 | + ipv6 { |
|
| 151 | + import filter { |
|
| 152 | + if is_valid_network_v6() && !is_self_net_v6() then { |
|
| 153 | + if (roa_check(dn42_roa_v6, net, bgp_path.last) = ROA_INVALID) then { |
|
| 154 | + print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; |
|
| 155 | + reject; |
|
| 156 | + } else accept; |
|
| 157 | + } else reject; |
|
| 158 | + }; |
|
| 159 | + export filter { if is_valid_network_v6() then accept; else reject; }; |
|
| 160 | + import limit 1000 action block; |
|
| 161 | + }; |
|
| 162 | +} |
|
| 163 | + |
|
| 164 | + |
|
| 165 | +include "/etc/bird/peers/*"; |
|
| 166 | +``` |
|
| 167 | + |
|
| 168 | +# Route Origin Authorization |
|
| 169 | + |
|
| 170 | +He example config above relies on ROA configuration files in `/etc/bird/roa_dn42{,_v6}.conf`. These should be automatically downloaded and updated every so often to prevent BGP highjacking, which can be achieved using a simple cronjob: |
|
| 171 | + |
|
| 172 | + */30 * * * * root curl -sfSLR {-o,-z}/etc/bird/roa_dn42_v6.conf https://dn42.tech9.io/roa/bird6_roa_dn42.conf && curl -sfSLR {-o,-z}/etc/bird/roa_dn42.conf https://dn42.tech9.io/roa/bird_roa_dn42.conf && sed -i 's/roa/route/g' /etc/bird/roa_dn42{,_v6}.conf && birdc configure |
|
| 173 | + |
|
| 174 | +Also make sure the /etc/bird directory exists: |
|
| 175 | + |
|
| 176 | + # mkdir -p /etc/bird |
|
| 177 | + |
|
| 178 | +# Setting up peers |
|
| 179 | + |
|
| 180 | +Please note: This section assumes that you've already got a tunnel to your peering partner setup. |
|
| 181 | + |
|
| 182 | +First, make sure the /etc/bird/peers directory exists: |
|
| 183 | + |
|
| 184 | + # mkdir -p /etc/bird/peers |
|
| 185 | + |
|
| 186 | +Then for each peer, create a configuration file similar to this one: |
|
| 187 | + |
|
| 188 | +``` |
|
| 189 | +protocol bgp <name> from dnpeers { |
|
| 190 | + neighbor <NEIGHBOR_IP> as <NEIGHBOR_ASN>; |
|
| 191 | +} |
|
| 192 | + |
|
| 193 | +protocol bgp <name>_v6 from dnpeers { |
|
| 194 | + neighbor <NEIGHBOR_IPv6>%<NEIGHBOR_INTERFACE> as <NEIGHBOR_ASN>; |
|
| 195 | +} |
|
| 196 | +``` |
|
| 197 | + |
|
| 198 | +Due to the special link local addresses of IPv6, an interface has to be specified using the %<if> syntax if a link local address is used (Which is recommended) |
|
| ... | ... | \ No newline at end of file |