Compare commits

..

No commits in common. "7dc53046f860b1ff913019234a2fa7c2ea1b2be5" and "4ae6407239669b2bb178020383dc2ef121c00f80" have entirely different histories.

5 changed files with 5 additions and 531 deletions

View file

@ -1,20 +1,16 @@
# What the scripts are used for # What the scripts are used for
* `/usr/local/sbin/update-irr-filters.sh` has to be put in a cron `/usr/local/sbin/update-irr-filters.sh` Has to be put in a cron
* `/usr/local/sbin/update-check-import.sh` is used to do generate the stuff `/usr/local/sbin/update-check-import.sh` Is used to do generate the stuff common to all peers
common to all peers `/usr/local/sbin/generate-irr-filter.sh` Is used to generate each peer configuration
* `/usr/local/sbin/generate-irr-filter.sh` is used to generate each peer
configuration
# Configuration files # Configuration files
`/usr/local/etc/bird-peers-update.conf` is sourced for three variables: `/usr/local/etc/bird-peers-update.conf` is sourced for three variables:
* `PDB_API_KEY` which will be used to query the peeringdb api * `PDB_API_KEY` which will be used to query the peeringdb api
* `BIRD_CONF_PATH` for the base dir of bird (freebsd and linux have * `BIRD_CONF_PATH` for the base dir of bird (freebsd and linux have different ones)
different ones)
* `IXP_ASN` the ixp asn for the communities * `IXP_ASN` the ixp asn for the communities
# Override some peers configuration # Override some peers configuration
If you want to add some configuration for some particular peers, you can do it If you want to add some configuration for some particular peers, you can do it like that:
like that:
``` ```
root@lillix-rs2:~# cat /usr/local/etc/bird-override/bgp_208627_ALARIG_193_34_197_135.conf root@lillix-rs2:~# cat /usr/local/etc/bird-override/bgp_208627_ALARIG_193_34_197_135.conf
bfd on; bfd on;

208
bird.conf
View file

@ -1,208 +0,0 @@
# Configure logging
#log syslog { warning, error, fatal, bug };
log syslog all;
# Turn on global debugging of all protocols
#debug protocols all;
debug protocols { states };
# Override router ID and store ASN
router id 193.34.197.192;
define myasn = 47214;
#####################
# GENERAL PROTOCOLS #
#####################
# This pseudo-protocol watches all interface up/down events.
protocol device {
# Scan interfaces every 5 seconds
scan time 5;
}
protocol bfd {
interface "ens19" {
passive on;
};
}
roa4 table r4;
roa6 table r6;
protocol rpki rpki_alarig {
remote "msi.no.swordarmor.fr";
roa4 { table r4; };
roa6 { table r6; };
}
protocol rpki rpki_cf {
remote "rtr.rpki.cloudflare.com";
port 8282;
roa4 { table r4; };
roa6 { table r6; };
}
###############
# BGP FILTERS #
###############
include "/etc/bird/check_import.conf";
function check_ipv4(int peeras; ip nexthop)
prefix set martians;
prefix set our_prefixes;
{
check_import(peeras, nexthop);
martians = [
10.0.0.0/8+, 100.64.0.0/10+, 127.0.0.0/8+, 169.254.0.0/16+,
172.16.0.0/12+, 192.0.0.0/24+, 192.0.2.0/24+, 192.168.0.0/16+,
198.18.0.0/15+, 198.51.100.0/24+, 203.0.113.0/24+,
224.0.0.0/4+, 240.0.0.0/4+, 255.255.255.255/32
];
# Avoid reserved networks
if net ~ martians then return false;
# Avoid too short and too long prefixes
if (net.len < 8) || (net.len > 24) then return false;
# Avoid 0.0.0.0/X (default route + 0.0.0.0/8)
if net.ip = 0.0.0.0 then return false;
# Remove our prefixes. Only us can announce them
# Remove also our interconnection prefixes. We are directly connected.
if net ~ [ 185.1.89.0/24+ ] then return false;
# scrub Origin Validation State Extended Community
bgp_ext_community.delete((unknown 0x4300, 0, 0));
bgp_ext_community.delete((unknown 0x4300, 0, 1));
bgp_ext_community.delete((unknown 0x4300, 0, 2));
# set RPKI Origin Validation State Extended Community
case roa_check(r4, net, bgp_path.last_nonaggregated) {
ROA_VALID:
# add rfc8097 marker to routes for which a valid
# matching ROA exists
bgp_ext_community.add((unknown 0x4300, 0, 0));
ROA_INVALID:
bgp_ext_community.add((unknown 0x4300, 0, 2));
return false;
else:
# add rfc8097 marker to routes for which no covering
# ROA exists
bgp_ext_community.add((unknown 0x4300, 0, 1));
}
return true;
};
function check_ipv6(int peeras; ip nexthop)
prefix set martians;
prefix set our_prefixes;
{
check_import(peeras, nexthop);
martians = [ ::1/128, ::/128, ::ffff:0:0/96+, 100::/64+,
2001:db8::/32+, 2001::/23, 2001:2::/48+, 2001:10::/28+, 2002::/17+,
fc00::/7, fe80::/10, ff00::/8+, 3FFE::/16+, 5F00::/8+
];
# Avoid reserved networks
if net ~ martians then return false;
# Avoid too short and too long prefixes
if (net.len < 16) || (net.len > 48) then return false;
# Avoid bogons. IANA didn't allocate outside of 2000::/3
# but there are already announces there
if ! (net.ip ~ 2000::/3) then return false;
# Avoid 0.0.0.0/X (default route + 0.0.0.0/8)
if net.ip = ::/0 then return false;
# Remove our prefixes. Only us can announce them
# Remove also our interconnection prefixes. We are directly connected.
if net ~ 2001:7f8:b1::/48 then return false;
# scrub Origin Validation State Extended Community
bgp_ext_community.delete((unknown 0x4300, 0, 0));
bgp_ext_community.delete((unknown 0x4300, 0, 1));
bgp_ext_community.delete((unknown 0x4300, 0, 2));
# set RPKI Origin Validation State Extended Community
case roa_check(r6, net, bgp_path.last_nonaggregated) {
ROA_VALID:
# add rfc8097 marker to routes for which a valid
# matching ROA exists
bgp_ext_community.add((unknown 0x4300, 0, 0));
ROA_INVALID:
bgp_ext_community.add((unknown 0x4300, 0, 2));
return false;
else:
# add rfc8097 marker to routes for which no covering
# ROA exists
bgp_ext_community.add((unknown 0x4300, 0, 1));
}
return true;
};
#############
# Templates #
#############
template bgp PEERS_IPv4 {
local as myasn;
rs client;
passive;
local role rs_server;
#bfd on;
prefer older;
ipv4 {
import table on;
export table on;
rpki reload;
add paths tx;
import keep filtered;
import all;
export all;
import limit 100 action block;
receive limit 1000 action disable;
};
}
template bgp PEERS_IPv6 {
local as myasn;
rs client;
passive;
local role rs_server;
#bfd on;
prefer older;
ipv6 {
import table on;
export table on;
rpki reload;
add paths tx;
import keep filtered;
import all;
export all;
import limit 100 action block;
receive limit 1000 action disable;
};
}
#########
# PEERS #
#########
include "/etc/bird/google.conf";
include "/etc/bird/functions/*.conf";
include "/etc/bird/peers/*.conf";

View file

@ -1,220 +0,0 @@
#!/bin/sh
set -e
# for iconv below
export LC_ALL=en_US.utf8
# 1st argument must be an ASN registered to peeringdb
# 2nd argument must be the IPv4 peering address
# 3rd argument must be the IPv6 peering address
if [ ! -f /usr/local/etc/bird-peers-update.conf ]; then
printf "Write /usr/local/etc/bird-peers-update.conf with at least "
printf "PDB_API_KEY, IXP_ASN and BIRD_CONF_PATH vars\n"
exit 1
else
. /usr/local/etc/bird-peers-update.conf
fi
PEER_AS=$1
IPv4=$2
IPv6=$3
if [ -z "${PEER_AS}" -o -z "${IPv4}" -o -z "${IPv6}" ]; then
echo "1st argument must be an ASN registered to peeringdb"
echo "2nd argument must be the IPv4 peering address"
echo "3rd argument must be the IPv6 peering address"
exit 1
fi
CACHE_DIR=/var/local/cache/peeringdb
if [ ! -d "${CACHE_DIR}" ]; then
mkdir -p "${CACHE_DIR}"
fi
# re-fetch data if it's too old
if [ -z "$(find ${CACHE_DIR} -mmin -720 -name ${PEER_AS}.json)" ]; then
curl -s -H 'Authorization: Api-Key '"${PDB_API_KEY}" \
-X GET "https://www.peeringdb.com/api/net?asn=${PEER_AS}" \
> "${CACHE_DIR}/${PEER_AS}.json"
fi
# test if the data is valid, -e will exit the script
jq -r '.data[] | .irr_as_set' "${CACHE_DIR}/${PEER_AS}.json" 1>/dev/null
IRRASSET=$(jq -r '.data[] | .irr_as_set' "${CACHE_DIR}/${PEER_AS}.json")
MAXPREF4=$(jq -r '.data[] | .info_prefixes4' "${CACHE_DIR}/${PEER_AS}.json")
MAXPREF6=$(jq -r '.data[] | .info_prefixes6' "${CACHE_DIR}/${PEER_AS}.json")
AS_NAME=$(jq -r '.data[] | .name' "${CACHE_DIR}/${PEER_AS}.json")
if [ -z "${IRRASSET}" ]; then
IRRASSET="AS${PEER_AS}"
fi
# Remove diacritic first as potential question marks will remove afterward
AS_NAME="$(echo ${AS_NAME} | iconv -f utf-8 -t ascii//TRANSLIT)"
AS_NAME="$(echo ${AS_NAME} | tr '[:punct:]' '_')"
AS_NAME="$(echo ${AS_NAME} | tr '[:space:]' '_')"
AS_NAME="$(echo ${AS_NAME} | tr '[:lower:]' '[:upper:]')"
AS_NAME="$(echo ${AS_NAME} | sed -E 's/^_+//;s/_+$//;s/_+/_/g')"
IPv4_PFL="$(bgpq4 -4 -b -A -l AS${PEER_AS}_v4 -R 24 ${IRRASSET})"
IPv6_PFL="$(bgpq4 -6 -b -A -l AS${PEER_AS}_v6 -R 48 ${IRRASSET})"
if [ -z "${MAXPREF4}" ] || [ ${MAXPREF4} -eq 0 ]; then
MAXPREF4=$(echo "${IPv4_PFL}" | wc -l)
fi
if [ "${MAXPREF4}" -lt 10 ]; then
MAXPREF4=10
fi
if [ -z "${MAXPREF6}" ] || [ ${MAXPREF6} -eq 0 ]; then
MAXPREF6=$(echo "${IPv6_PFL}" | wc -l)
fi
if [ "${MAXPREF6}" -lt 10 ]; then
MAXPREF6=10
fi
# do we really trust peeringdb? we may want to limit maxpref
mkdir -p "${BIRD_CONF_PATH}"/functions
# AS16 - AS32 from whois AS47214
if [ "${PEER_AS}" -gt 65535 ]; then
# la t'es bien
eval $(whois AS47214 | awk '/AS32 to AS16/ { print "AS"$5"="$7";" }' | sed -E 's/AS([0-9]+)/\1/g')
if [ -n "${PEER_AS}" ]; then
eval COMMU_PEER_AS=\$AS${PEER_AS}
else
echo "AS16 - AS32 from whois AS${IXP_ASN} not found"
exit 1
fi
else
COMMU_PEER_AS=${PEER_AS}
fi
echo "# generated by $0 $@
function check_import_${PEER_AS}_ipv4(int peeras; ip nexthop)
prefix set AS${PEER_AS}_v4;
{
${IPv4_PFL}
# check if the announced prefix is in the bgpq set
if net !~ AS${PEER_AS}_v4 then return false;
# reject the route if the first as is not the peer
# or if the nexthop is not the peer as well
# we also check the rpki status there
return check_ipv4(peeras, nexthop);
}
filter bgp_filters_${PEER_AS}_out {
if ! (source = RTS_BGP) then reject;
if (${IXP_ASN},${COMMU_PEER_AS}) ~ bgp_community then accept;
if (0,${COMMU_PEER_AS}) ~ bgp_community then reject;
if (0,${IXP_ASN}) ~ bgp_community then reject;
if (${IXP_ASN},${IXP_ASN}) ~ bgp_community then accept;
else accept;
}
" > "${BIRD_CONF_PATH}/functions/${PEER_AS}_v4.conf"
mkdir -p "${BIRD_CONF_PATH}"/peers
# bird does not support dots in the filters name, it must be dashes
DASH_IPv4="$(echo ${IPv4} | tr '.' '_')"
if [ -f "/usr/local/etc/bird-override/bgp_${PEER_AS}_${AS_NAME}_${DASH_IPv4}.conf" ]; then
BIRD_OVERRIDE_AFI_V4="include \"/usr/local/etc/bird-override/bgp_${PEER_AS}_${AS_NAME}_${DASH_IPv4}.conf\";"
else
BIRD_OVERRIDE_AFI_V4=""
fi
echo "# generated by $0 $@
filter bgp_filters_${DASH_IPv4}_in_ipv4 {
if (check_import_${PEER_AS}_ipv4(${PEER_AS}, ${IPv4})) then {
# Here we can set localpref or remove a prefix, for example
accept;
}
else {
reject \"Prefix \", net, \" filtered IN from ${IPv4}\";
}
}
protocol bgp bgp_${PEER_AS}_${AS_NAME}_${DASH_IPv4} from PEERS_IPv4 {
description \"${AS_NAME} ${IRRASSET}\";
neighbor ${IPv4} as ${PEER_AS};
${BIRD_OVERRIDE_AFI_V4}
ipv4 {
receive limit ${MAXPREF4} action restart;
import limit ${MAXPREF4} action disable;
import filter bgp_filters_${DASH_IPv4}_in_ipv4;
export filter bgp_filters_${PEER_AS}_out;
};
}
" > "${BIRD_CONF_PATH}/peers/${PEER_AS}_${IPv4}.conf"
echo "# generated by $0 $@
function check_import_${PEER_AS}_ipv6(int peeras; ip nexthop)
prefix set AS${PEER_AS}_v6;
{
${IPv6_PFL}
# check if the announced prefix is in the bgpq set
if net !~ AS${PEER_AS}_v6 then return false;
# reject the route if the first as is not the peer
# or if the nexthop is not the peer as well
# we also check the rpki status there
return check_ipv6(peeras, nexthop);
}
" > "${BIRD_CONF_PATH}/functions/${PEER_AS}_v6.conf"
# bird does not support semicollons in the filters name, it must be dashes
DASH_IPv6="$(echo ${IPv6} | tr ':' '_')"
if [ -f "/usr/local/etc/bird-override/bgp_${PEER_AS}_${AS_NAME}_${DASH_IPv6}.conf" ]; then
BIRD_OVERRIDE_AFI_V6="include \"/usr/local/etc/bird-override/bgp_${PEER_AS}_${AS_NAME}_${DASH_IPv6}.conf\";"
else
BIRD_OVERRIDE_AFI_V6=""
fi
echo "# generated by $0 $@
filter bgp_filters_${DASH_IPv6}_in_ipv6 {
if (check_import_${PEER_AS}_ipv6(${PEER_AS}, ${IPv6})) then {
# Here we can set localpref or remove a prefix, for example
accept;
}
else {
reject \"Prefix \", net, \" filtered IN from ${IPv6}\";
}
}
protocol bgp bgp_${PEER_AS}_${AS_NAME}_${DASH_IPv6} from PEERS_IPv6 {
description \"${AS_NAME} ${IRRASSET}\";
neighbor ${IPv6} as ${PEER_AS};
${BIRD_OVERRIDE_AFI_V6}
ipv6 {
receive limit ${MAXPREF6} action restart;
import limit ${MAXPREF6} action disable;
import filter bgp_filters_${DASH_IPv6}_in_ipv6;
export filter bgp_filters_${PEER_AS}_out;
};
}
" > "${BIRD_CONF_PATH}/peers/${PEER_AS}_${IPv6}.conf"
echo "# generated by $0 $@
function check_import_${PEER_AS}_ipv6(int peeras; ip nexthop)
prefix set AS${PEER_AS}_v6;
{
${IPv6_PFL}
if net !~ AS${PEER_AS}_v6 then return false;
return check_ipv6(peeras, nexthop);
}
" > "${BIRD_CONF_PATH}/functions/${PEER_AS}_v6.conf"

View file

@ -1,53 +0,0 @@
#!/bin/sh
set -e
if [ ! -f /usr/local/etc/bird-peers-update.conf ]; then
printf "Write /usr/local/etc/bird-peers-update.conf with at least "
printf "PDB_API_KEY and BIRD_CONF_PATH vars\n"
exit 1
else
. /usr/local/etc/bird-peers-update.conf
fi
# comma list
NEVER_VIA_RS_LIST="$(
curl -H 'Authorization: Api-Key '"${PDB_API_KEY}" \
-s 'https://www.peeringdb.com/api/net?info_never_via_route_servers=1' | \
jq '.data[].asn' | sort -n | tr '\n' ',' | sed 's/,/, /g;s/, $//'
)"
# bird set
NEVER_VIA_RS_SET="$(
printf "[ ${NEVER_VIA_RS_LIST} ]"
)"
if [ -n "${NEVER_VIA_RS_SET}" ]; then
printf "# generated by $0 $@
function check_import(int peeras; ip nexthop)
int set reserved_asn;
int set never_via_rs;
{
reserved_asn = [ 0, 64297..131071, 4200000000..4294967294, 4294967295 ];
never_via_rs = ${NEVER_VIA_RS_SET};
# Check that the next AS is our neighbour's.
# Same for next-hop
if bgp_path.first != peeras then return false;
if bgp_next_hop != nexthop then return false;
# AS_PATH too long (8 because a member could re-annonce its clients, and
# the clients of it clients, and prepend on the IXP)
if bgp_path.len > 8 then return false;
# Don't accept if path contains a reserved AS
# Disabled because it removes legit prefixes
if bgp_path ~ reserved_asn then return false;
if bgp_path ~ never_via_rs then return false;
return true;
}
" > "${BIRD_CONF_PATH}"/check_import.conf
fi

View file

@ -1,41 +0,0 @@
#!/bin/sh
# Update the 'never on rs' from peeringdb
/usr/local/sbin/update-check-import.sh
# Genereate the filters and peers using data from peeringdb
/usr/local/sbin/generate-irr-filter.sh 16347 193.34.197.130 2001:7f8:6d::1:6347:1
#/usr/local/sbin/generate-irr-filter.sh 200780 193.34.197.148 2001:7f8:6d::20:0780:1 # Appliwave a degage
/usr/local/sbin/generate-irr-filter.sh 199917 193.34.197.157 2001:7f8:6d::19:9917:1
/usr/local/sbin/generate-irr-filter.sh 209823 193.34.197.145 2001:7f8:6d::20:9823:1
/usr/local/sbin/generate-irr-filter.sh 35625 193.34.197.129 2001:7f8:6d::3:5625:1
#/usr/local/sbin/generate-irr-filter.sh 30781 193.34.197.154 2001:7f8:6d::3:0781:1 # FreePro pas sur les RS
/usr/local/sbin/generate-irr-filter.sh 35360 193.34.197.144 2001:7f8:6d::3:5360:1
/usr/local/sbin/generate-irr-filter.sh 34019 193.34.197.156 2001:7f8:6d::3:4019:1
/usr/local/sbin/generate-irr-filter.sh 29075 193.34.197.140 2001:7f8:6d::2:9075:1
/usr/local/sbin/generate-irr-filter.sh 25091 193.34.197.153 2001:7f8:6d::2:5091:1
/usr/local/sbin/generate-irr-filter.sh 8298 193.34.197.143 2001:7f8:6d::8298:1
/usr/local/sbin/generate-irr-filter.sh 2027 193.34.197.151 2001:7f8:6d::2027:1
/usr/local/sbin/generate-irr-filter.sh 9036 193.34.197.132 2001:7f8:6d::1:9036:1
/usr/local/sbin/generate-irr-filter.sh 199758 193.34.197.146 2001:7f8:6d::19:9758:1
/usr/local/sbin/generate-irr-filter.sh 16276 193.34.197.142 2001:7f8:6d::1:6276:1
/usr/local/sbin/generate-irr-filter.sh 2200 193.34.197.158 2001:7f8:6d::2200:1
/usr/local/sbin/generate-irr-filter.sh 62119 193.34.197.162 2001:7f8:6d::6:2119:1
/usr/local/sbin/generate-irr-filter.sh 206002 193.34.197.163 2001:7f8:6d::20:6002:1
/usr/local/sbin/generate-irr-filter.sh 31235 193.34.197.133 2001:7f8:6d::3:1235:1
/usr/local/sbin/generate-irr-filter.sh 210879 193.34.197.161 2001:7f8:6d::21:0879:1
/usr/local/sbin/generate-irr-filter.sh 197922 193.34.197.131 2001:7f8:6d::19:7922:1
/usr/local/sbin/generate-irr-filter.sh 210165 193.34.197.152 2001:7f8:6d::21:165:1
/usr/local/sbin/generate-irr-filter.sh 35661 193.34.197.155 2001:7f8:6d::3:5661:1
/usr/local/sbin/generate-irr-filter.sh 8218 193.34.197.141 2001:7f8:6d::8218:1
/usr/local/sbin/generate-irr-filter.sh 6461 193.34.197.149 2001:7f8:6d::6461:1
/usr/local/sbin/generate-irr-filter.sh 44097 193.34.197.134 2001:7f8:6d::4:4097:1
/usr/local/sbin/generate-irr-filter.sh 208627 193.34.197.135 2001:7f8:6d::20:8627:1
/usr/local/sbin/generate-irr-filter.sh 207910 193.34.197.136 2001:7f8:6d::20:7910:1
/usr/local/sbin/generate-irr-filter.sh 205068 193.34.197.137 2001:7f8:6d::20:5068:1
# Check if the config is valid and reload
STATUS=$(birdc configure | grep -v BIRD)
if [ -z "$(echo ${STATUS} | grep 'Reconfigured')" ]; then
echo ${STATUS}
fi