Для примера выполню установку 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 секунд (если на сервере десятки тысяч маршрутов которые постоянно меняются и bird сильно нагружает CPU, например работает сервер accel-ppp, то можно увеличить значение на 120)
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;
}
Так как вся сеть для NAT X.X.X.0/23 указана в blackhole, то это позволит создать и передать маршрут к Uplink соседу, а маршруты из этой же сети с меньшей маской «more specific», будут иметь больше приоритет чем /23 и трафик пойдет через них.
Пример функции определяющей свои сети с белыми 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;
connect 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;
connect 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";
Если не указывать Preference, то его значение по умолчанию будет 100.
Откроем консоль 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
- Настройка iBGP в Bird
- Настройка iBGP на Juniper MX
- Настройка BGP в Quagga
- Taskset — привязка процесса к ядрам CPU
- Миграция с Quagga на Bird