Установка и настройка BIRD (BGP)

Для примера выполню установку BIRD в Ubuntu Server 20.04 и покажу пример настройки BGP.

Переключимся на root пользователя:

sudo -i

Для установки выполним команду (в Ubuntu Server 20.04 установилась версия BIRD 1.6.8):

apt install bird

Разрешим пересылку IPv4 пакетов между сетевыми интерфейсами (например если сервер будет использоваться как маршрутизатор):

sysctl net.ipv4.conf.all.forwarding
cat /proc/sys/net/ipv4/ip_forward

sysctl -w net.ipv4.conf.all.forwarding=1

nano /etc/sysctl.conf
net.ipv4.conf.all.forwarding=1
sysctl -p

Настроим логи как я описывал в статье:
Настройка логов BIRD

Переименуем оригинальный файл конфигурации BIRD:

mv /etc/bird/bird.conf /etc/bird/bird.conf.original

Создадим новый и откроем его в текстовом редакторе:

touch /etc/bird/bird.conf
nano /etc/bird/bird.conf

Укажем глобально router id — ID маршрутизатора, IP адрес сервера который смотрит в мир, потом в секциях bgp, ospf и т.д. можно будет указывать дополнительно другие router id, если не указать глобально этот, то будет выбран случайный IP адрес на интерфейсе:

router id X.X.X.X;

Чтобы в конфигурации несколько раз не указывать свою AS, определим для нее переменную my_as, которую будем указывать в дальнейшем:

define my_as=XXXXX;

protocol direct определяет сетевые интерфейсы которые будут мониторится (символ * означает все, я указал те что смотрят в мир к другим BGP соседям):

protocol direct {
#       interface "*";
        interface "ens1f0", "ens1f1";
}

protocol kernel синхронизирует маршруты bird с маршрутами ядра операционной системы:

protocol kernel {
        persist off;
        scan time 20;
        learn;
        import all;
        export none;
}

Опишу некоторые параметры:
persist — не удалять маршруты после остановки bird (persist off — удалять).
scan time 20 — сканировать таблицу маршрутов ядра каждые 20 секунд.
learn — изучение маршрутов ядра
import all — по умолчанию
export none — по умолчанию (так как uplink один, я указал none, так как маршрут по умолчанию 0.0.0.0 я указал вручную в netplan и не использую аналогичный который присылает uplink. Если указать вручную и принимать его, то будет предупреждение Netlink: File exists, если uplink соседей несколько, то маршрут по умолчанию указанный вручную необходимо убрать).

protocol device необходим для сканирования состояния интерфейсов (up/down), например каждые 10 секунд, если интерфейсов очень много, то можно увеличить время:

protocol device {
        scan time 10;
}

protocol static позволяет указать статические маршруты (я указал свою белую сеть которую буду отдавать Uplink соседу):

protocol static {
#   import all;
    preference 254;
    route X.X.X.0/23 blackhole;
}

Пример функции определяющей свои сети с белыми IP:

function my_nets()
prefix set my_nets;
{
my_nets = [ X.X.X.0/23+, X.X.2.0/24+ ];
if net ~ my_nets then return true;
return false;
}

Определим сети с серыми IP:

function bogons()
prefix set bogons;
{
bogons = [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+, 10.0.0.0/8+,
224.0.0.0/4+, 240.0.0.0/4+, 0.0.0.0/32-, 0.0.0.0/0{25,32}, 0.0.0.0/0{0,7} ];
# Avoid RFC1918 and similar networks
if net ~ bogons then return true;
return false;
}

Создадим фильтр в котором запретим принимать свою сеть и серые сети, все остальное разрешим:

filter PROVIDER1_IN {
if bogons() || my_nets() then reject;
#bgp_local_pref = 205;
accept;
}

Еще пример фильтра который разрешает только маршрут по умолчанию, то есть default, а все остальное запрещает:

filter DEFAULT {
   if net ~ [ 0.0.0.0/0 ] then {
       accept;
   }
   else reject;
}

Если провайдеров несколько, то создадим еще фильтры:

filter PROVIDER2_IN {
#bgp_local_pref = 200;
   if net ~ [ 0.0.0.0/0 ] then {
       accept;
   }
   else reject;
}

bgp_local_pref позволяет балансировать исходящую нагрузку, чем меньше — тем лучше, применить изменения без разрыва сессии можно перечитав конфигурацию провайдера:

birdc
reload IXNFO_COM

Создадим фильтр в котором разрешим экспортировать только свою сеть, приведу несколько примеров:

filter PROVIDER1_OUT {
    if bogons() then reject;
    if my_nets() then
    {
        bgp_community.delete([(my_as,*)]);
        accept;
    }
    reject;
}


filter PROVIDER1_OUT {
    if bogons() then reject;
#   if net.len = 32 then reject;
    if my_nets() then
    {
#       bgp_path.prepend(my_as);
#       bgp_path.prepend(my_as);bgp_path.prepend(my_as);bgp_path.prepend(my_as);
        bgp_community.empty;
        accept;
    }
    reject;
}

Теперь настроим BGP для первого провайдера:

protocol bgp IXNFO_COM {
    debug { states, events };
    #table master;
    router id X.X.X.X;
    description "IXNFO_COM";
    local as my_as;
    neighbor X.X.X.X as XXXXX;

    hold time 60;
    startup hold time 60;
    connect retry time 120;
    keepalive time 20;
    start delay time 5;
    error wait time 60, 300;
    error forget time 300;
    next hop self;
    path metric 1;
    default bgp_med 0;

    source address X.X.X.X;

    export where net = X.X.X.0/23;
#   export filter PROVIDER1_OUT;
    import filter PROVIDER1_IN;
#   import none;

#    gateway direct;
}

Опишу некоторые параметры:
hold time — время ожидания keepalive сообщения от соседа, по умолчанию 240 секунд.
connect retry time — время ожидания в секундах перед повторной неудачной попыткой подключения.
error wait time — минимальная и максимальная задержка в секундах между сбоем протокола и автоматическим перезапуском, по умолчанию 60, 300.
error forget time — максимальное время в секундах между двумя сбоями протокола, что приводит к экспоненциальному увеличению времени ожидания ошибки, по умолчанию 300.
keepalive time — задержка в секундах между отправкой двух последовательных сообщений keepalive.
path metric — сравнение длины путей при выборе наилучшего маршрута BGP, по умолчанию включено.
export where net — так как сеть одна, я прямо указал что можно экспортировать, без использования фильтра.
import none — если провайдер один, а маршрут по умолчанию указан вручную в настройках сети, то импортировать от провайдера ничего не нужно.

Аналогичным образом настроим второго провайдера:

protocol bgp PROVIDER2 {
...
}

Можно создать шаблон для BGP, чтобы не дублировать параметры для разных провайдеров:

template bgp EXTERNAL {
debug { states, events };
local as my_as;
keepalive time 30;
hold time 240;
interpret communities no;
import keep filtered;
startup hold time 240;
connect retry time 120;
start delay time 5;
error wait time 60, 300;
error forget time 300;
path metric 1;
default bgp_med 0;
default bgp_local_pref 150;
}

И потом указать этот шаблон:

protocol bgp IXNFO_COM from EXTERNAL{
description "IXNFO_COM";
neighbor X.X.X.X as XXXXX;
source address X.X.X.X;
export filter PROVIDER1_OUT;
import filter PROVIDER1_IN;
}

protocol bgp IXNFO_COM2 from EXTERNAL{
description "IXNFO_COM2";
neighbor X.X.X.X as XXXXX;
source address X.X.X.X;
export filter PROVIDER2_OUT;
import filter PROVIDER2_IN;
}

Еще несколько примеров экспорта:

export where (net = 0.0.0.0/0) || ((my_as,XXXXX) ~ bgp_community) || ((my_as,XXXXX) ~ bgp_community);


protocol static static_bgp { 
        import all;
        route X.X.X.0/24 reject;
}
export where proto = "static_bgp";

Откроем консоль BIRD:

birdc

Убедимся что сессия поднялась и посмотрим маршруты:

show protocols
show protocols all

show route
show route all
show route export IXNFO_COM
show route advertising-protocol bgp X.X.X.X
show static

show memory
show ?
exit
ip route | grep -E "(default|nexthop)"

Версию BIRD можно посмотреть так:

show status

Можно также выполнять команды BIRD из Linux, например чтобы мониторить результат через Zabbix:

birdc show route|less
birdc show protocols

Проверим активирован ли автозапуск bird при запуске операционной системы:

systemctl is-enabled bird.service
systemctl is-enabled bird6.service

systemctl enable bird.service
systemctl disable bird6.service

systemctl restart bird.service
systemctl stop bird6.service

systemctl status bird.service
systemctl status bird6.service

Смотрите также мои статьи:
IPTables правила для BGP
Настройка OSPF в BIRD
Настройка BGP в Quagga
Taskset — привязка процесса к ядрам CPU

Оставьте комментарий

Добавить комментарий