2 Commits
32 changed files with 897 additions and 3465 deletions
-32
View File
@@ -1,32 +0,0 @@
name: Build and Push Docker Image
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Private Registry
uses: docker/login-action@v2
with:
registry: git.shts.su
username: ${{ gitea.actor }}
password: ${{ secrets.ACTIONS_PAT }}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: git.shts.su/infra/bgp-server:latest
-47
View File
@@ -1,47 +0,0 @@
# Logs
logs/
*.log
# Docker
.dockerignore
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
env/
ENV/
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Temporary files
*.tmp
*.temp
-533
View File
@@ -1,533 +0,0 @@
# Инструкция по запуску BGP Server из Docker Registry
## Быстрый старт
### 1. Создание файлов с префиксами
Создайте папку `data` и файл с префиксами:
```powershell
# Создание папки для данных
mkdir data
# Создание файла с префиксами
@"
# Основные префиксы
192.168.1.0/24
192.168.2.0/24
10.0.0.0/8
172.16.0.0/12
# Дополнительные префиксы
203.0.113.0/24
198.51.100.0/24
"@ | Out-File -FilePath "data/prefixes.txt" -Encoding UTF8
# Проверка создания файла
Get-Content data/prefixes.txt
```
### 2. Запуск контейнера из registry
```powershell
# Запуск BGP сервера из registry с переменными окружения
docker run -d `
--name bgp-server `
--restart unless-stopped `
-p 179:179 `
-v ${PWD}/data:/app/data:ro `
-v ${PWD}/logs:/app/logs `
-e BGP_LOCAL_AS=65000 `
-e BGP_ROUTER_ID=192.168.1.100 `
-e BGP_NEIGHBOR_IP=192.168.1.1 `
-e BGP_NEIGHBOR_AS=65001 `
-e BGP_HOLD_TIME=90 `
-e BGP_KEEPALIVE=30 `
git.shts.su/infra/bgp-server:latest
# Простой запуск с настройками по умолчанию
docker run -d `
--name bgp-server `
--restart unless-stopped `
-p 179:179 `
-v ${PWD}/data:/app/data:ro `
-v ${PWD}/logs:/app/logs `
git.shts.su/infra/bgp-server:latest
# Пример с кастомными настройками
docker run -d `
--name bgp-server-custom `
--restart unless-stopped `
-p 179:179 `
-v ${PWD}/data:/app/data:ro `
-v ${PWD}/logs:/app/logs `
-e BGP_LOCAL_AS=65000 `
-e BGP_ROUTER_ID=10.0.0.100 `
-e BGP_NEIGHBOR_IP=10.0.0.1 `
-e BGP_NEIGHBOR_AS=65001 `
-e BGP_HOLD_TIME=180 `
-e BGP_LOG_LEVEL=DEBUG `
-e BGP_MD5_PASSWORD="your-secure-password" `
git.shts.su/infra/bgp-server:latest
```
### 3. Проверка работы
```powershell
# Просмотр логов
docker logs -f bgp-server
# Проверка статуса контейнера
docker ps
# Проверка BGP сессии
docker exec bgp-server exabgpcli show neighbor
```
## Подробная настройка
### Структура файлов
```
your-project/
├── data/
│ ├── prefixes.txt # Основные префиксы
│ └── additional_prefixes.txt # Дополнительные префиксы
├── logs/ # Логи (создается автоматически)
└── DOCKER_RUN.md # Эта инструкция
```
### Формат файла с префиксами
**data/prefixes.txt:**
```
# Основные префиксы
192.168.1.0/24
192.168.2.0/24
10.0.0.0/8
172.16.0.0/12
# Комментарии начинаются с #
# Пустые строки игнорируются
# Можно добавлять дополнительные префиксы
203.0.113.0/24
198.51.100.0/24
```
**data/additional_prefixes.txt:**
```
# Дополнительные префиксы
172.20.0.0/16
172.21.0.0/16
```
### Полная команда запуска с настройками
```powershell
docker run -d `
--name bgp-server `
--restart unless-stopped `
-p 179:179 `
-v ${PWD}/data:/app/data:ro `
-v ${PWD}/logs:/app/logs `
-e BGP_LOCAL_AS=65000 `
-e BGP_ROUTER_ID=192.168.1.100 `
-e BGP_NEIGHBOR_IP=192.168.1.1 `
-e BGP_NEIGHBOR_AS=65001 `
-e BGP_HOLD_TIME=90 `
-e BGP_KEEPALIVE=30 `
git.shts.su/infra/bgp-server:latest
```
### Переменные окружения
| Переменная | Описание | По умолчанию |
|------------|----------|--------------|
| `BGP_LOCAL_AS` | AS номер сервера | 65000 |
| `BGP_ROUTER_ID` | Router ID сервера | 192.168.1.100 |
| `BGP_NEIGHBOR_IP` | IP адрес BGP пира | 192.168.1.1 |
| `BGP_NEIGHBOR_AS` | AS номер пира | 65001 |
| `BGP_HOLD_TIME` | Hold time в секундах | 90 |
| `BGP_KEEPALIVE` | Keepalive в секундах | 30 |
| `BGP_MD5_PASSWORD` | MD5 пароль для аутентификации | (не используется) |
| `BGP_LOG_LEVEL` | Уровень логирования (DEBUG, INFO, WARNING, ERROR) | INFO |
### Просмотр сгенерированной конфигурации
```powershell
# Просмотр текущей конфигурации ExaBGP
docker exec bgp-server cat /app/exabgp.conf
# Просмотр переменных окружения
docker exec bgp-server env | findstr BGP_
```
## Управление контейнером
### Основные команды
```powershell
# Запуск контейнера
docker start bgp-server
# Остановка контейнера
docker stop bgp-server
# Перезапуск контейнера
docker restart bgp-server
# Удаление контейнера
docker rm -f bgp-server
# Просмотр логов
docker logs bgp-server
# Логи в реальном времени
docker logs -f bgp-server
```
### Обновление контейнера
```powershell
# Безопасное обновление (рекомендуется)
docker stop bgp-server
docker rm bgp-server
docker pull git.shts.su/infra/bgp-server:latest
docker run -d `
--name bgp-server `
--restart unless-stopped `
-p 179:179 `
-v ${PWD}/data:/app/data:ro `
-v ${PWD}/logs:/app/logs `
git.shts.su/infra/bgp-server:latest
# Быстрое обновление (если настройки не изменились)
docker pull git.shts.su/infra/bgp-server:latest
docker restart bgp-server
# Использование скрипта обновления
.\scripts\update-container.ps1
# Принудительное обновление без подтверждения
.\scripts\update-container.ps1 -Force
```
### Обновление префиксов
```powershell
# 1. Отредактируйте файл prefixes.txt
notepad data/prefixes.txt
# 2. Перезапустите контейнер
docker restart bgp-server
# 3. Проверьте логи
docker logs bgp-server
```
### Проверка работы
```powershell
# Статус контейнера
docker ps
# Проверка BGP сессии
docker exec bgp-server exabgpcli show neighbor
# Проверка загруженных префиксов
docker exec bgp-server cat /app/logs/prefixes.log
# Проверка содержимого файлов
docker exec bgp-server cat /app/data/prefixes.txt
# Использование ресурсов
docker stats bgp-server
```
## Настройка RouterOS (клиент)
### Определение версии RouterOS
Сначала определите, какой синтаксис поддерживает ваша версия RouterOS:
```routeros
# Проверка версии RouterOS
/system resource print
# Проверка доступных команд BGP
/routing/bgp/print
/routing bgp print
```
**Если команда `/routing/bgp/print` работает** - используйте новый синтаксис (RouterOS 7.14+)
**Если команда `/routing bgp print` работает** - используйте старый синтаксис
### Адаптация конфигурации под ваши настройки
Замените следующие параметры в командах на ваши значения:
| Параметр | Описание | Ваше значение |
|----------|----------|---------------|
| `as=65001` | Ваш AS номер | Ваш AS номер |
| `router-id=192.168.0.254` | Ваш Router ID | IP адрес вашего роутера |
| `local.address=192.168.0.254` | Ваш локальный IP | IP адрес вашего роутера |
| `remote.address=192.168.100.99` | IP BGP сервера | IP адрес Docker контейнера |
| `remote.as=65000` | AS BGP сервера | AS номер BGP сервера (по умолчанию 65000) |
### Команды для RouterOS 7.14+
**Используйте рабочую конфигурацию с template и connection (см. ниже)**
### Настройка RouterOS 7.14 (рабочая конфигурация)
**Использование template и connection:**
```routeros
# Создать шаблон BGP с вашим AS и router-id
/routing bgp template
add as=65001 disabled=no name=bgp-server output.network=bgp-networks .no-client-to-client-reflection=yes router-id=192.168.0.254 routing-table=main
# Фильтр на запрет экспорта маршрутов (подстраховка)
/routing filter rule
add chain=discard disabled=no rule="reject;"
# Фильтр на импорт маршрутов с изменением next-hop
/routing filter rule
add chain=bgp-server-in disabled=no rule="set gw 192.168.100.99; accept;"
# Настройка BGP пира
/routing bgp connection
add connect=yes disabled=no input.filter=bgp-server-in listen=yes local.address=192.168.0.254 .role=ebgp multihop=yes name=bgp-server.network output.filter-chain=discard remote.address=192.168.100.99/32 .as=65000 .port=179 routing-table=main templates=bgp-server
# Проверка статуса
/routing bgp connection print
/routing bgp route print
```
### Объяснение параметров конфигурации
**BGP Template:**
- `as=65001` - ваш AS номер
- `router-id=192.168.0.254` - ваш Router ID (IP адрес роутера)
- `output.network=bgp-networks` - сеть для экспорта (создается автоматически)
- `.no-client-to-client-reflection=yes` - отключение отражения между клиентами
**Routing Filter Rules:**
- `chain=discard` - цепочка для отклонения экспортируемых маршрутов
- `chain=bgp-server-in` - цепочка для обработки входящих маршрутов
- `set gw 192.168.100.99` - установка next-hop на IP BGP сервера
**BGP Connection:**
- `connect=yes` - активное подключение
- `listen=yes` - ожидание входящих подключений
- `local.address=192.168.0.254` - ваш локальный IP
- `remote.address=192.168.100.99/32` - IP BGP сервера
- `remote.as=65000` - AS номер BGP сервера
- `templates=bgp-server` - использование созданного шаблона
### Команды для удаления конфигурации
Если нужно удалить конфигурацию и начать заново:
```routeros
# Удаление BGP connection
/routing bgp connection remove bgp-server.network
# Удаление фильтров
/routing filter rule remove [find chain=bgp-server-in]
/routing filter rule remove [find chain=discard]
# Удаление BGP template
/routing bgp template remove bgp-server
# Проверка удаления
/routing bgp connection print
/routing filter rule print
/routing bgp template print
```
## Устранение неполадок
### Проблема: Контейнер не запускается
```powershell
# Проверьте логи
docker logs bgp-server
# Проверьте, не занят ли порт 179
netstat -an | findstr :179
# Проверьте права доступа к папкам
ls -la data/
ls -la logs/
```
### Проблема: BGP сессия не устанавливается
```powershell
# Проверьте сетевое подключение
docker exec bgp-server ping 192.168.1.1
# Проверьте конфигурацию
docker exec bgp-server cat /app/exabgp.conf
# Проверьте логи BGP
docker logs bgp-server | findstr "BGP"
```
### Проблема: Префиксы не анонсируются
```powershell
# Проверьте файлы с префиксами
docker exec bgp-server cat /app/data/prefixes.txt
# Проверьте логи процесса загрузки
docker exec bgp-server cat /app/logs/prefixes.log
# Проверьте статус процесса
docker exec bgp-server ps aux | findstr load_prefixes
```
### Проблема: Ошибки ExaBGP конфигурации
```powershell
# Проверьте конфигурацию ExaBGP
docker exec bgp-server cat /app/exabgp.conf
# Валидация конфигурации
docker exec bgp-server exabgp --validate /app/exabgp.conf
# Проверьте named pipes
docker exec bgp-server ls -la /run/exabgp/
docker exec bgp-server ls -la /var/run/exabgp/
# Проверьте логи ExaBGP
docker exec bgp-server cat /app/logs/exabgp.log
# Проверьте переменные окружения
docker exec bgp-server env | findstr BGP_
```
### Проблема: Файл prefixes.txt не найден
```powershell
# Проверьте монтирование volume
docker exec bgp-server ls -la /app/data/
# Создайте файл вручную
docker exec bgp-server bash -c "echo '192.168.1.0/24' > /app/data/prefixes.txt"
# Перезапустите контейнер
docker restart bgp-server
```
### Проблема: BGP сессия не устанавливается в RouterOS
```routeros
# Проверьте доступные команды BGP
/routing/bgp/print
# Проверьте экземпляры BGP
/routing/bgp/instance/print
# Проверьте пиры
/routing/bgp/peer/print
# Проверьте маршруты
/routing/bgp/route/print
# Проверьте логи BGP
/log print where topics~"bgp"
```
### Проблема: Неправильный синтаксис команд RouterOS
Если команды `/routing/bgp/` не работают, попробуйте старый синтаксис:
```routeros
# Старый синтаксис RouterOS
/routing bgp instance add name=bgp-server as=65001 router-id=192.168.1.1
/routing bgp peer add name=bgp-server remote-address=192.168.1.100 remote-as=65000 instance=bgp-server
/routing bgp instance set bgp-server disabled=no
```
### Диагностика версии RouterOS
```routeros
# Проверка версии RouterOS
/system resource print
# Проверка доступных команд BGP
/routing/bgp/print
/routing bgp print
# Проверка доступных подкоманд
/routing/bgp/instance/print
/routing bgp instance print
# Если команды не найдены, используйте старый синтаксис
```
## Примеры использования
### Пример 1: Простой запуск
```powershell
# Создание файла с префиксами
"192.168.1.0/24`n10.0.0.0/8" | Out-File -FilePath "data/prefixes.txt" -Encoding UTF8
# Запуск контейнера
docker run -d --name bgp-server -p 179:179 -v ${PWD}/data:/app/data:ro git.shts.su/infra/bgp-server:latest
```
### Пример 2: Запуск с кастомными настройками
```powershell
docker run -d `
--name bgp-server `
-p 179:179 `
-v ${PWD}/data:/app/data:ro `
-v ${PWD}/logs:/app/logs `
-e BGP_LOCAL_AS=65000 `
-e BGP_ROUTER_ID=10.0.0.100 `
-e BGP_NEIGHBOR_IP=10.0.0.1 `
-e BGP_NEIGHBOR_AS=65001 `
git.shts.su/infra/bgp-server:latest
```
### Пример 3: Запуск с несколькими файлами префиксов
```powershell
# Создание нескольких файлов
"192.168.1.0/24`n192.168.2.0/24" | Out-File -FilePath "data/prefixes.txt" -Encoding UTF8
"10.0.0.0/8`n172.16.0.0/12" | Out-File -FilePath "data/additional_prefixes.txt" -Encoding UTF8
# Запуск контейнера
docker run -d --name bgp-server -p 179:179 -v ${PWD}/data:/app/data:ro git.shts.su/infra/bgp-server:latest
```
## Безопасность
### Рекомендации
1. **Ограничение доступа**: Настройте firewall для ограничения доступа к порту 179
2. **Аутентификация**: Используйте MD5 аутентификацию в BGP
3. **Логирование**: Включите детальное логирование для аудита
4. **Обновления**: Регулярно обновляйте Docker образы
### Настройка MD5 аутентификации
Добавьте переменную окружения:
```powershell
-e BGP_MD5_PASSWORD="your-secure-password"
```
В RouterOS:
```routeros
# Для RouterOS 7.14+ (новый синтаксис)
/routing/bgp/peer set bgp-server password="your-secure-password"
# Для старых версий RouterOS
/routing bgp peer set bgp-server password="your-secure-password"
```
-51
View File
@@ -1,51 +0,0 @@
FROM ubuntu:22.04
# Установка системных зависимостей и FRR
RUN apt-get update && apt-get install -y \
frr \
frr-pythontools \
python3 \
python3-pip \
iproute2 \
iputils-ping \
net-tools \
procps \
vim \
curl \
&& rm -rf /var/lib/apt/lists/*
# Установка Python зависимостей
RUN pip3 install watchdog
# Создание структуры директорий
RUN mkdir -p /app/scripts /app/data /app/logs /etc/frr
# Копирование файлов
COPY frr.conf /etc/frr/frr.conf
COPY scripts/ /app/scripts/
COPY data/ /app/data/
# Установка прав доступа
RUN chmod +x /app/scripts/start.sh
RUN chmod +x /app/scripts/load_prefixes.py
RUN chmod +x /app/scripts/generate_config.py
RUN chmod +x /app/scripts/monitor.py
# Рабочая директория
WORKDIR /app
# Открытие BGP порта
EXPOSE 179
# Установка переменных окружения по умолчанию
ENV BGP_LOCAL_AS=65000
ENV BGP_ROUTER_ID=192.168.100.99
ENV BGP_NEIGHBOR_IP=192.168.0.254
ENV BGP_NEIGHBOR_AS=65001
ENV BGP_HOLD_TIME=90
ENV BGP_KEEPALIVE=30
ENV BGP_LOG_LEVEL=info
ENV FRR_DAEMONS="bgpd zebra"
# Команда запуска
ENTRYPOINT ["/app/scripts/start.sh"]
-324
View File
@@ -1,324 +0,0 @@
# Быстрый старт BGP Server (FRR)
Этот документ поможет вам быстро запустить BGP сервер на базе FRR для раздачи префиксов.
## Предварительные требования
- Docker Desktop для Windows
- PowerShell
- RouterOS 7.14+ (для клиентской стороны)
## Шаг 1: Подготовка файлов
### Создание файла с префиксами
Создайте файл `data/prefixes.txt` с вашими префиксами:
```
# Основные префиксы
192.168.1.0/24
192.168.2.0/24
10.0.0.0/8
172.16.0.0/12
# Дополнительные префиксы
203.0.113.0/24
198.51.100.0/24
```
### Создание дополнительного файла (опционально)
Создайте файл `data/additional_prefixes.txt` для дополнительных префиксов:
```
# Дополнительные префиксы
192.168.100.0/24
192.168.200.0/24
```
## Шаг 2: Запуск сервера
### Вариант A: Использование PowerShell скрипта (рекомендуется)
```powershell
# Запуск с автоматической сборкой образа
.\scripts\start-server.ps1 -Build
# Или запуск без пересборки
.\scripts\start-server.ps1
```
### Вариант B: Использование Docker Compose
```powershell
# Сборка и запуск
docker-compose up -d --build
# Или только запуск
docker-compose up -d
```
### Вариант C: Ручной запуск
```powershell
# Сборка образа
docker build -t bgp-server-frr .
# Запуск контейнера
docker run -d \
--name bgp-server \
--restart unless-stopped \
-p 179:179 \
-v ${PWD}/data:/app/data:ro \
-v ${PWD}/logs:/app/logs \
--cap-add NET_ADMIN \
--privileged \
bgp-server-frr
```
## Шаг 3: Проверка работы
### Проверка статуса контейнера
```powershell
# Статус контейнера
docker ps
# Логи контейнера
docker logs bgp-server
```
### Проверка FRR
```powershell
# Версия FRR
docker exec bgp-server vtysh -c "show version"
# Статус BGP
docker exec bgp-server vtysh -c "show ip bgp summary"
# Анонсированные маршруты
docker exec bgp-server vtysh -c "show ip bgp"
```
### Проверка загруженных префиксов
```powershell
# Логи загрузки префиксов
docker exec bgp-server tail -f /app/logs/prefixes.log
# Тестирование загрузки
docker exec bgp-server python3 /app/scripts/load_prefixes.py --test
```
## Шаг 4: Настройка RouterOS
### Базовая настройка BGP
```routeros
# Создание BGP экземпляра
/routing bgp instance
add name=bgp-server as=65001 router-id=192.168.0.254
# Настройка BGP сети
/routing bgp network
add network=192.168.0.0/24
# Настройка BGP пира
/routing bgp peer
add name=bgp-server remote-address=192.168.100.99 remote-as=65000 instance=bgp-server
# Включение BGP
/routing bgp instance set bgp-server disabled=no
```
### Проверка BGP сессии
```routeros
# Статус BGP
/routing bgp peer print
# Полученные маршруты
/routing bgp route print
```
## Шаг 5: Мониторинг
### Просмотр логов
```powershell
# Логи FRR
docker exec bgp-server tail -f /app/logs/frr.log
# Логи загрузки префиксов
docker exec bgp-server tail -f /app/logs/prefixes.log
# Логи мониторинга
docker exec bgp-server tail -f /app/logs/monitor.log
```
### Статус системы
```powershell
# Статус в JSON формате
docker exec bgp-server cat /app/logs/status.json
# Запуск мониторинга
docker exec bgp-server python3 /app/scripts/monitor.py
```
### Команды vtysh
```powershell
# Подключение к FRR CLI
docker exec -it bgp-server vtysh
# Полезные команды внутри vtysh:
show ip bgp summary # Сводка BGP
show ip bgp # Все BGP маршруты
show ip route # Таблица маршрутизации
show interface # Интерфейсы
show running-config # Конфигурация
```
## Управление
### Остановка сервера
```powershell
# Остановка с сохранением контейнера
.\scripts\stop-server.ps1
# Остановка с удалением контейнера
.\scripts\stop-server.ps1 -Force
```
### Перезагрузка префиксов
```powershell
# Перезагрузка без перезапуска сервера
docker exec bgp-server python3 /app/scripts/reload_prefixes.py
```
### Обновление контейнера
```powershell
# Обновление с пересборкой
.\scripts\update-container.ps1 -Force
```
## Диагностика
### Проблема: Контейнер не запускается
```powershell
# Проверка логов
docker logs bgp-server
# Проверка портов
netstat -an | findstr :179
# Проверка Docker
docker system info
```
### Проблема: BGP сессия не устанавливается
```powershell
# Проверка сетевой связности
docker exec bgp-server ping 192.168.0.254
# Проверка конфигурации FRR
docker exec bgp-server vtysh -c "show running-config"
# Проверка статуса BGP
docker exec bgp-server vtysh -c "show ip bgp summary"
```
### Проблема: Префиксы не анонсируются
```powershell
# Проверка файлов префиксов
docker exec bgp-server cat /app/data/prefixes.txt
# Проверка логов загрузки
docker exec bgp-server tail -f /app/logs/prefixes.log
# Проверка статических маршрутов
docker exec bgp-server vtysh -c "show ip route static"
```
## Настройка переменных окружения
Вы можете настроить BGP параметры через переменные окружения:
```powershell
# Запуск с кастомными настройками
docker run -d \
--name bgp-server \
-p 179:179 \
-v ${PWD}/data:/app/data:ro \
-v ${PWD}/logs:/app/logs \
-e BGP_LOCAL_AS=65000 \
-e BGP_ROUTER_ID=192.168.100.99 \
-e BGP_NEIGHBOR_IP=192.168.0.254 \
-e BGP_NEIGHBOR_AS=65001 \
-e BGP_HOLD_TIME=90 \
-e BGP_KEEPALIVE=30 \
--cap-add NET_ADMIN \
--privileged \
bgp-server-frr
```
## Полезные команды
### Мониторинг в реальном времени
```powershell
# Логи в реальном времени
docker logs -f bgp-server
# Статус BGP каждые 5 секунд
while ($true) {
docker exec bgp-server vtysh -c "show ip bgp summary"
Start-Sleep 5
Clear-Host
}
```
### Резервное копирование
```powershell
# Копирование файлов префиксов
Copy-Item data/prefixes.txt data/prefixes.txt.backup
# Экспорт конфигурации FRR
docker exec bgp-server vtysh -c "show running-config" > frr-config.backup
```
### Очистка
```powershell
# Остановка и удаление контейнера
docker stop bgp-server
docker rm bgp-server
# Удаление образа
docker rmi bgp-server-frr
# Очистка логов
Remove-Item logs/* -Recurse -Force
```
## Следующие шаги
1. **Настройка мониторинга**: Настройте алерты для критических событий
2. **Резервное копирование**: Настройте автоматическое резервное копирование конфигурации
3. **Безопасность**: Настройте firewall и аутентификацию BGP
4. **Масштабирование**: Рассмотрите использование нескольких экземпляров для высокой доступности
## Поддержка
- Документация FRR: https://frrouting.org/
- GitHub проекта: https://github.com/FRRouting/frr
- Сообщество: https://lists.frrouting.org/
+123
View File
@@ -0,0 +1,123 @@
# Быстрый старт BGP сервера на Linux
## Минимальная установка
### Вариант 1: С Docker Compose
```bash
# 1. Клонируйте или скачайте проект
git clone <repository-url>
cd bgp-server
# 2. Установите зависимости
./install-dependencies.sh
# 3. Запустите BGP сервер
./start-bgp-server.sh
```
### Вариант 2: Только Docker (рекомендуется)
```bash
# 1. Клонируйте или скачайте проект
git clone <repository-url>
cd bgp-server
# 2. Сделайте скрипты исполняемыми
chmod +x *.sh
# 3. Быстрый запуск одной командой
./quick-run.sh
```
## Проверка работы
```bash
# Проверить статус
./check-bgp-status.sh
# Подключиться к консоли управления
docker exec -it bgp-server vtysh
# Посмотреть логи
docker-compose logs -f bgp-server
```
## Управление
### С Docker Compose
```bash
# Остановить сервер
./stop-bgp-server.sh
# Обновить префиксы
./update-prefixes.sh
# Перезапустить сервер
./stop-bgp-server.sh && ./start-bgp-server.sh
```
### Только Docker
```bash
# Остановить сервер
./quick-stop.sh
# Полное управление контейнером
./run-bgp-container.sh start
./run-bgp-container.sh stop
./run-bgp-container.sh restart
./run-bgp-container.sh status
./run-bgp-container.sh logs
```
## Основные команды vtysh
```bash
# Войти в консоль
docker exec -it bgp-server vtysh
# Показать статус BGP
show ip bgp summary
# Показать анонсированные префиксы
show ip bgp
# Показать соседей
show ip bgp neighbors
# Показать community
show ip bgp community
```
## Настройки по умолчанию
- **ASN**: 65000
- **Router ID**: 192.168.1.1
- **BGP порт**: 179
- **vtysh порт**: 2601
- **Пароль vtysh**: zebra
## Подключение клиентов
Клиенты могут подключаться к BGP серверу по IP адресу сервера на порту 179.
Пример конфигурации клиента:
```
router bgp 65001
neighbor <SERVER_IP> remote-as 65000
neighbor <SERVER_IP> send-community
```
## Troubleshooting
```bash
# Проверить, что Docker работает
docker version
# Проверить, что контейнер запущен
docker ps
# Проверить логи
docker-compose logs bgp-server
# Проверить сетевые порты
netstat -tuln | grep :179
```
+158 -300
View File
@@ -1,359 +1,217 @@
# BGP Server для раздачи префиксов (FRR)
# BGP Server с FRRouting
Этот проект представляет собой BGP сервер на базе FRR (Free Range Routing), который раздает префиксы из текстовых файлов. Сервер работает в Docker контейнере и предназначен для интеграции с RouterOS 7.14+.
Этот проект предоставляет готовое решение для запуска BGP сервера с использованием контейнера FRRouting, который анонсирует префиксы всем подключенным клиентам с разделением по community.
## Архитектура решения
## Требования
- **BGP Server**: FRR (Free Range Routing) в Docker контейнере
- **Источник данных**: Текстовые файлы с префиксами
- **Клиент**: RouterOS 7.14+ для получения префиксов
- **Протокол**: BGP (только исходящие анонсы)
## Преимущества FRR
- **Стабильность**: Производственный уровень надежности
- **Производительность**: Оптимизирован для высоких нагрузок
- **Функциональность**: Полная поддержка BGP функций
- **Мониторинг**: Встроенные инструменты диагностики
- **Сообщество**: Активная поддержка и развитие
- Docker Engine
- Docker Compose
- Bash shell
## Структура проекта
```
bgp-server/
├── docker-compose.yml # Конфигурация Docker
├── Dockerfile # Образ Docker с FRR
├── frr.conf # Конфигурация FRR
├── scripts/
├── start.sh # Скрипт запуска FRR
│ ├── load_prefixes.py # Загрузка префиксов в FRR
│ ├── generate_config.py # Генерация конфигурации FRR
│ └── monitor.py # Мониторинг FRR
── data/
│ ├── prefixes.txt # Основной файл с префиксами
│ └── additional_prefixes.txt # Дополнительные префиксы
├── logs/ # Логи FRR
└── README.md # Эта инструкция
├── docker-compose.yml # Конфигурация Docker контейнера
├── frr.conf # Конфигурация FRRouting
├── prefixes.txt # Файл с префиксами и community
├── start-bgp-server.sh # Скрипт запуска для Linux
├── stop-bgp-server.sh # Скрипт остановки для Linux
├── check-bgp-status.sh # Скрипт проверки статуса для Linux
├── update-prefixes.sh # Скрипт обновления префиксов для Linux
├── install-dependencies.sh # Скрипт установки зависимостей
── README.md # Эта инструкция
```
## Быстрый старт
## Быстрый запуск
### 1. Подготовка файлов с префиксами
1. **Установите зависимости (если не установлены):**
```bash
./install-dependencies.sh
```
Создайте файл `data/prefixes.txt` с префиксами в формате:
```
192.168.1.0/24
10.0.0.0/8
172.16.0.0/12
```
2. **Сделайте скрипты исполняемыми:**
```bash
chmod +x *.sh
```
### 2. Запуск сервера
3. **Запустите BGP сервер:**
```bash
./start-bgp-server.sh
```
```powershell
# Клонирование репозитория (если нужно)
git clone <repository-url>
cd bgp-server
## Ручной запуск
# Запуск с Docker Compose
docker-compose up -d
```
Если вы предпочитаете запускать вручную:
### 3. Проверка работы
```bash
# Остановить существующие контейнеры
docker-compose down
```powershell
# Просмотр логов
docker-compose logs -f bgp-server
# Проверка статуса контейнера
docker-compose ps
# Проверка BGP сессии через vtysh
docker exec bgp-server vtysh -c "show ip bgp summary"
```
## Подробная настройка
### Требования
- Docker Desktop для Windows
- PowerShell
- RouterOS 7.14+ на стороне клиента
### Шаг 1: Настройка файлов с префиксами
Создайте файлы с префиксами в папке `data/`:
**data/prefixes.txt:**
```
# Основные префиксы
192.168.1.0/24
192.168.2.0/24
10.0.0.0/8
172.16.0.0/12
# Комментарии начинаются с #
# Пустые строки игнорируются
```
**data/additional_prefixes.txt:**
```
# Дополнительные префиксы
203.0.113.0/24
198.51.100.0/24
```
### Шаг 2: Конфигурация BGP сервера
Конфигурация FRR генерируется автоматически из переменных окружения в `docker-compose.yml`:
```yaml
environment:
- BGP_LOCAL_AS=65000
- BGP_ROUTER_ID=192.168.1.100
- BGP_NEIGHBOR_IP=192.168.1.1
- BGP_NEIGHBOR_AS=65001
- BGP_HOLD_TIME=90
- BGP_KEEPALIVE=30
- BGP_LOG_LEVEL=info
```
### Шаг 3: Настройка Docker
**docker-compose.yml:**
```yaml
version: '3.8'
services:
bgp-server:
build: .
container_name: bgp-server
restart: unless-stopped
ports:
- "179:179" # BGP порт
volumes:
- ./data:/app/data:ro
- ./logs:/app/logs
environment:
- BGP_LOCAL_AS=65000
- BGP_ROUTER_ID=192.168.100.99
- BGP_NEIGHBOR_IP=192.168.0.254
- BGP_NEIGHBOR_AS=65001
networks:
- bgp-network
cap_add:
- NET_ADMIN
privileged: true
networks:
bgp-network:
driver: bridge
ipam:
config:
- subnet: 192.168.100.0/24
```
### Шаг 4: Настройка RouterOS
На стороне RouterOS 7.14+ выполните следующие команды:
```routeros
# Создание BGP экземпляра
/routing bgp instance
add name=bgp-server as=65001 router-id=192.168.0.254
# Настройка BGP сети
/routing bgp network
add network=192.168.0.0/24
# Настройка BGP пира
/routing bgp peer
add name=bgp-server remote-address=192.168.100.99 remote-as=65000 instance=bgp-server
# Включение BGP
/routing bgp instance set bgp-server disabled=no
```
### Шаг 5: Запуск и мониторинг
```powershell
# Запуск сервера
# Запустить BGP сервер
docker-compose up -d
# Проверить статус
docker ps
# Посмотреть логи
docker-compose logs bgp-server
```
## Конфигурация
### Префиксы (prefixes.txt)
Файл содержит префиксы в формате:
```
prefix community1:community2:community3
```
Пример:
```
192.168.1.0/24 65000:100:65000:200
10.0.0.0/8 65000:101:65000:201
```
### BGP настройки (frr.conf)
- **ASN**: 65000
- **Router ID**: 192.168.1.1
- **Порт BGP**: 179
- **Порт vtysh**: 2601
## Управление сервером
### Подключение к vtysh (консоль управления)
```bash
docker exec -it bgp-server vtysh
```
### Полезные команды vtysh
```bash
# Показать статус BGP
show ip bgp summary
# Показать анонсированные префиксы
show ip bgp
# Показать community
show ip bgp community
# Показать соседей
show ip bgp neighbors
# Показать IPv6 информацию
show ipv6 bgp summary
```
### Просмотр логов
```bash
# Просмотр логов в реальном времени
docker-compose logs -f bgp-server
# Проверка статуса BGP сессии
docker exec bgp-server vtysh -c "show ip bgp summary"
# Проверка анонсированных маршрутов
docker exec bgp-server vtysh -c "show ip bgp"
# Просмотр последних логов
docker-compose logs bgp-server
```
## Управление и мониторинг
### Остановка сервера
### Команды vtysh
```powershell
# Подключение к FRR CLI
docker exec -it bgp-server vtysh
# Просмотр BGP соседей
show ip bgp neighbors
# Просмотр BGP маршрутов
show ip bgp
# Просмотр статических маршрутов
show ip route
# Просмотр конфигурации
show running-config
```bash
docker-compose down
```
### Мониторинг через скрипты
## Подключение клиентов
```powershell
# Запуск мониторинга
docker exec bgp-server python3 /app/scripts/monitor.py
### Настройка BGP клиента
# Просмотр статуса
docker exec bgp-server cat /app/logs/status.json
Клиенты могут подключаться к BGP серверу по адресу:
- **IP**: IP адрес хоста, где запущен контейнер
- **Порт**: 179
- **ASN**: 65000 (внешний ASN)
# Перезагрузка префиксов
docker exec bgp-server python3 /app/scripts/load_prefixes.py --test
### Пример конфигурации клиента (Cisco)
```
router bgp 65001
neighbor 192.168.1.1 remote-as 65000
neighbor 192.168.1.1 send-community
network 192.168.2.0/24
```
### Логи
### Пример конфигурации клиента (Juniper)
```powershell
# Логи FRR
docker exec bgp-server tail -f /app/logs/frr.log
# Логи загрузки префиксов
docker exec bgp-server tail -f /app/logs/prefixes.log
# Логи мониторинга
docker exec bgp-server tail -f /app/logs/monitor.log
```
protocols {
bgp {
group external {
type external;
peer-as 65000;
neighbor 192.168.1.1 {
send-community;
}
}
}
}
```
## Диагностика
## Мониторинг
### Проверка статуса FRR
### Проверка статуса контейнера
```powershell
# Проверка процессов
docker exec bgp-server ps aux | grep -E "(zebra|bgpd)"
# Проверка версии FRR
docker exec bgp-server vtysh -c "show version"
# Проверка сетевых интерфейсов
docker exec bgp-server vtysh -c "show interface"
```bash
docker ps --filter "name=bgp-server"
```
### Проверка BGP сессии
### Проверка сетевых портов
```powershell
# Статус BGP соседей
docker exec bgp-server vtysh -c "show ip bgp summary"
# Детальная информация о соседе
docker exec bgp-server vtysh -c "show ip bgp neighbors 192.168.0.254"
```bash
netstat -tuln | grep :179
netstat -tuln | grep :2601
```
### Проверка маршрутов
### Проверка логов FRRouting
```powershell
# Все BGP маршруты
docker exec bgp-server vtysh -c "show ip bgp"
# Статические маршруты
docker exec bgp-server vtysh -c "show ip route static"
# Таблица маршрутизации
docker exec bgp-server vtysh -c "show ip route"
```bash
docker exec bgp-server cat /var/log/frr/frr.log
```
## Обновление префиксов
## Troubleshooting
### Автоматическое обновление
### Проблема: Контейнер не запускается
Скрипт `load_prefixes.py` автоматически отслеживает изменения в файлах префиксов и обновляет маршруты в FRR.
1. Проверьте, что Docker Desktop запущен
2. Проверьте логи: `docker-compose logs bgp-server`
3. Убедитесь, что порты 179 и 2601 не заняты
### Ручное обновление
### Проблема: BGP сессии не устанавливаются
```powershell
# Перезагрузка всех префиксов
docker exec bgp-server python3 /app/scripts/load_prefixes.py
# Тестирование загрузки префиксов
docker exec bgp-server python3 /app/scripts/load_prefixes.py --test
```
## Устранение неполадок
### Проблема: BGP сессия не устанавливается
1. Проверьте сетевую связность:
```powershell
docker exec bgp-server ping 192.168.0.254
```
2. Проверьте конфигурацию BGP:
```powershell
docker exec bgp-server vtysh -c "show running-config"
```
3. Проверьте логи FRR:
```powershell
docker exec bgp-server tail -f /app/logs/frr.log
```
1. Проверьте настройки firewall
2. Убедитесь, что клиент правильно настроен
3. Проверьте логи BGP: `docker exec -it bgp-server vtysh -c "show ip bgp summary"`
### Проблема: Префиксы не анонсируются
1. Проверьте файлы с префиксами:
```powershell
docker exec bgp-server cat /app/data/prefixes.txt
```
2. Проверьте логи загрузки префиксов:
```powershell
docker exec bgp-server tail -f /app/logs/prefixes.log
```
3. Проверьте статические маршруты:
```powershell
docker exec bgp-server vtysh -c "show ip route static"
```
### Проблема: Высокое потребление ресурсов
1. Проверьте использование памяти:
```powershell
docker exec bgp-server free -h
```
2. Проверьте количество маршрутов:
```powershell
docker exec bgp-server vtysh -c "show ip bgp summary"
```
1. Проверьте конфигурацию в `frr.conf`
2. Убедитесь, что префиксы правильно прописаны
3. Проверьте community настройки
## Безопасность
- FRR работает в привилегированном контейнере для доступа к сетевым интерфейсам
- Используйте route-maps для фильтрации трафика
- Ограничьте доступ к vtysh CLI
- Регулярно обновляйте образ Docker
⚠️ **Важно**: Этот BGP сервер настроен для тестирования и разработки. Для продакшена:
## Производительность
- FRR оптимизирован для обработки большого количества маршрутов
- Поддерживает до 1 миллиона маршрутов
- Эффективное использование памяти
- Быстрое время сходимости
1. Измените пароли по умолчанию
2. Настройте firewall правила
3. Используйте более строгие настройки безопасности
4. Ограничьте доступ к vtysh
## Поддержка
- Документация FRR: https://frrouting.org/
- GitHub проекта: https://github.com/FRRouting/frr
- Сообщество: https://lists.frrouting.org/
При возникновении проблем:
1. Проверьте логи контейнера
2. Убедитесь в правильности конфигурации
3. Проверьте сетевые настройки
4. Обратитесь к документации FRRouting: https://frrouting.org/
-338
View File
@@ -1,338 +0,0 @@
# Тестирование BGP сервера
## Подготовка к тестированию
### Требования для тестирования
- Docker Desktop для Windows
- PowerShell
- RouterOS 7.14+ (физический или виртуальный)
- Сетевое подключение между сервером и RouterOS
### Схема тестирования
```
[Windows Host] ←→ [RouterOS Device]
192.168.1.100 192.168.1.1
AS: 65000 AS: 65001
```
## Пошаговое тестирование
### Шаг 1: Подготовка окружения
```powershell
# Клонирование репозитория
git clone <repository-url>
cd bgp-server
# Создание директорий
mkdir logs
# Проверка файлов
Get-ChildItem -Recurse
```
### Шаг 2: Настройка тестовых префиксов
Отредактируйте `data/prefixes.txt`:
```
# Тестовые префиксы
192.168.100.0/24
192.168.200.0/24
10.10.10.0/24
172.16.100.0/24
```
### Шаг 3: Запуск BGP сервера
```powershell
# Запуск с автоматической сборкой
.\scripts\start-server.ps1 -Build
# Проверка статуса
docker-compose ps
```
Ожидаемый результат:
```
Name Command State Ports
bgp-server /app/script Up 0.0.0.0:179->179/tcp
```
### Шаг 4: Проверка логов сервера
```powershell
# Просмотр логов
docker-compose logs bgp-server
# Проверка логов в реальном времени
docker-compose logs -f bgp-server
```
Ожидаемые сообщения:
```
Starting BGP Server...
Validating ExaBGP configuration...
Starting ExaBGP...
ExaBGP started successfully with PID: XXX
```
### Шаг 5: Проверка загрузки префиксов
```powershell
# Проверка логов загрузки префиксов
docker exec bgp-server cat /app/logs/prefixes.log
```
Ожидаемый результат:
```
[2024-01-01 12:00:00] Starting prefix loader...
[2024-01-01 12:00:00] Loaded 4 prefixes from prefixes.txt
[2024-01-01 12:00:00] Total prefixes loaded: 4
[2024-01-01 12:00:00] Announced prefix: 10.10.10.0/24
[2024-01-01 12:00:00] Announced prefix: 172.16.100.0/24
[2024-01-01 12:00:00] Announced prefix: 192.168.100.0/24
[2024-01-01 12:00:00] Announced prefix: 192.168.200.0/24
[2024-01-01 12:00:00] All prefixes announced successfully
```
### Шаг 6: Настройка RouterOS
Выполните в RouterOS:
```routeros
# Создание BGP экземпляра
/routing bgp instance add name=bgp-server as=65001 router-id=192.168.1.1
# Настройка BGP сети
/routing bgp network add network=192.168.1.0/24
# Настройка BGP пира
/routing bgp peer add name=bgp-server remote-address=192.168.1.100 remote-as=65000 instance=bgp-server
# Включение BGP экземпляра
/routing bgp instance set bgp-server disabled=no
```
### Шаг 7: Проверка BGP сессии
В RouterOS:
```routeros
# Проверка статуса BGP пира
/routing bgp peer print
```
Ожидаемый результат:
```
Flags: X - disabled, I - invalid, D - dynamic, E - established
0 name="bgp-server" instance=bgp-server remote-address=192.168.1.100 remote-as=65000
state=established uptime=1m30s prefix-count=4 updates-sent=4 updates-received=0
withdrawn-sent=0 withdrawn-received=0
```
### Шаг 8: Проверка полученных маршрутов
В RouterOS:
```routeros
# Просмотр полученных BGP маршрутов
/routing bgp routes print
```
Ожидаемый результат:
```
Flags: * - best, b - backup
0 * dst-address=10.10.10.0/24 gateway=192.168.1.100 immediate-gw=192.168.1.100
bgp-local-pref=100 bgp-origin=igp bgp-as-path="" bgp-community="" bgp-ext-community=""
bgp-large-community="" bgp-med="" bgp-prepend="" bgp-atomic-aggregate=no bgp-aggregator-as=""
bgp-aggregator-id="" bgp-nexthop=192.168.1.100 bgp-identifier=192.168.1.100
bgp-cluster-list="" bgp-dampening=no bgp-peer=bgp-server
1 * dst-address=172.16.100.0/24 gateway=192.168.1.100 immediate-gw=192.168.1.100
bgp-local-pref=100 bgp-origin=igp bgp-as-path="" bgp-community="" bgp-ext-community=""
bgp-large-community="" bgp-med="" bgp-prepend="" bgp-atomic-aggregate=no bgp-aggregator-as=""
bgp-aggregator-id="" bgp-nexthop=192.168.1.100 bgp-identifier=192.168.1.100
bgp-cluster-list="" bgp-dampening=no bgp-peer=bgp-server
2 * dst-address=192.168.100.0/24 gateway=192.168.1.100 immediate-gw=192.168.1.100
bgp-local-pref=100 bgp-origin=igp bgp-as-path="" bgp-community="" bgp-ext-community=""
bgp-large-community="" bgp-med="" bgp-prepend="" bgp-atomic-aggregate=no bgp-aggregator-as=""
bgp-aggregator-id="" bgp-nexthop=192.168.1.100 bgp-identifier=192.168.1.100
bgp-cluster-list="" bgp-dampening=no bgp-peer=bgp-server
3 * dst-address=192.168.200.0/24 gateway=192.168.1.100 immediate-gw=192.168.1.100
bgp-local-pref=100 bgp-origin=igp bgp-as-path="" bgp-community="" bgp-ext-community=""
bgp-large-community="" bgp-med="" bgp-prepend="" bgp-atomic-aggregate=no bgp-aggregator-as=""
bgp-aggregator-id="" bgp-nexthop=192.168.1.100 bgp-identifier=192.168.1.100
bgp-cluster-list="" bgp-dampening=no bgp-peer=bgp-server
```
### Шаг 9: Тестирование обновления префиксов
```powershell
# Добавление нового префикса
echo "192.168.300.0/24" >> data/prefixes.txt
# Перезагрузка префиксов
docker exec bgp-server python3 /app/scripts/reload_prefixes.py
```
Проверьте в RouterOS:
```routeros
/routing bgp routes print
```
Должен появиться новый маршрут `192.168.300.0/24`.
### Шаг 10: Тестирование отзыва префиксов
```powershell
# Удаление префикса из файла
# Отредактируйте data/prefixes.txt и удалите одну строку
# Перезагрузка префиксов
docker exec bgp-server python3 /app/scripts/reload_prefixes.py
```
Проверьте в RouterOS:
```routeros
/routing bgp routes print
```
Удаленный префикс должен исчезнуть из таблицы маршрутов.
## Автоматизированное тестирование
### Скрипт тестирования
Создайте файл `test-bgp.ps1`:
```powershell
# Скрипт автоматизированного тестирования
Write-Host "=== BGP Server Testing ===" -ForegroundColor Green
# Проверка Docker
Write-Host "1. Checking Docker..." -ForegroundColor Yellow
try {
docker --version | Out-Null
Write-Host "✓ Docker is available" -ForegroundColor Green
} catch {
Write-Host "✗ Docker is not available" -ForegroundColor Red
exit 1
}
# Проверка контейнера
Write-Host "2. Checking container status..." -ForegroundColor Yellow
$containerStatus = docker ps --filter name=bgp-server --format "{{.Status}}"
if ($containerStatus) {
Write-Host "✓ Container is running: $containerStatus" -ForegroundColor Green
} else {
Write-Host "✗ Container is not running" -ForegroundColor Red
exit 1
}
# Проверка BGP процесса
Write-Host "3. Checking BGP process..." -ForegroundColor Yellow
$bgpProcess = docker exec bgp-server pgrep -f exabgp
if ($bgpProcess) {
Write-Host "✓ BGP process is running" -ForegroundColor Green
} else {
Write-Host "✗ BGP process is not running" -ForegroundColor Red
}
# Проверка префиксов
Write-Host "4. Checking prefixes..." -ForegroundColor Yellow
$prefixCount = docker exec bgp-server cat /app/data/prefixes.txt | Select-String -Pattern "^\d" | Measure-Object | Select-Object -ExpandProperty Count
Write-Host "✓ Found $prefixCount prefixes" -ForegroundColor Green
# Проверка логов
Write-Host "5. Checking logs..." -ForegroundColor Yellow
$logEntries = docker exec bgp-server cat /app/logs/prefixes.log | Measure-Object -Line | Select-Object -ExpandProperty Lines
Write-Host "✓ Found $logEntries log entries" -ForegroundColor Green
Write-Host "=== Testing Complete ===" -ForegroundColor Green
```
### Запуск тестирования
```powershell
.\test-bgp.ps1
```
## Тестирование производительности
### Тест с большим количеством префиксов
```powershell
# Создание файла с большим количеством префиксов
$prefixes = @()
for ($i = 1; $i -le 1000; $i++) {
$prefixes += "192.168.$i.0/24"
}
$prefixes | Out-File -FilePath "data/large_prefixes.txt" -Encoding UTF8
# Замена основного файла
Move-Item "data/prefixes.txt" "data/prefixes_backup.txt"
Move-Item "data/large_prefixes.txt" "data/prefixes.txt"
# Перезагрузка префиксов
docker exec bgp-server python3 /app/scripts/reload_prefixes.py
```
### Мониторинг производительности
```powershell
# Мониторинг ресурсов
docker stats bgp-server
# Проверка времени загрузки
Measure-Command { docker exec bgp-server python3 /app/scripts/load_prefixes.py }
```
## Тестирование отказоустойчивости
### Тест перезапуска контейнера
```powershell
# Перезапуск контейнера
docker-compose restart
# Ожидание восстановления
Start-Sleep -Seconds 30
# Проверка статуса
docker-compose ps
```
### Тест сетевых сбоев
```powershell
# Симуляция сетевого сбоя (требует настройки)
# Отключение сетевого интерфейса на RouterOS
# Проверка восстановления
# Включение сетевого интерфейса
# Проверка BGP сессии
docker exec bgp-server exabgpcli show neighbor
```
## Очистка после тестирования
```powershell
# Остановка сервера
.\scripts\stop-server.ps1
# Удаление контейнера
docker-compose down
# Очистка образов (опционально)
docker system prune -f
```
## Заключение
После успешного прохождения всех тестов BGP сервер готов к продакшн использованию. Регулярно выполняйте тестирование для обеспечения стабильной работы.
-293
View File
@@ -1,293 +0,0 @@
# Альтернативные решения для BGP сервера
## Обзор решений
В данном документе представлены альтернативные решения для создания BGP сервера, который раздает префиксы из текстовых файлов.
## 1. Bird BGP Daemon
### Преимущества
- Высокая производительность
- Поддержка IPv6
- Гибкая конфигурация
- Активная разработка
### Недостатки
- Сложная конфигурация
- Меньше документации на русском языке
### Dockerfile
```dockerfile
FROM ubuntu:20.04
# Установка Bird
RUN apt-get update && apt-get install -y bird
# Создание директорий
RUN mkdir -p /etc/bird /var/log/bird
# Копирование конфигурации
COPY bird.conf /etc/bird/bird.conf
# Открытие BGP порта
EXPOSE 179
# Запуск Bird
CMD ["bird", "-f", "-d"]
```
### Конфигурация (bird.conf)
```
# Основная конфигурация Bird
log stderr all;
log "/var/log/bird.log" all;
# Настройки BGP
router id 192.168.1.100;
# Протокол для загрузки префиксов из файла
protocol static {
route 192.168.1.0/24 via 192.168.1.100;
route 10.0.0.0/8 via 192.168.1.100;
route 172.16.0.0/12 via 192.168.1.100;
}
# BGP протокол
protocol bgp bgp_peer {
local as 65000;
neighbor 192.168.1.1 as 65001;
export where proto = "static";
import none;
}
```
## 2. FRRouting (FRR)
### Преимущества
- Полная совместимость с Cisco IOS
- Поддержка множества протоколов
- Хорошая документация
- Активное сообщество
### Недостатки
- Больший размер образа
- Более сложная настройка
### Dockerfile
```dockerfile
FROM ubuntu:20.04
# Установка FRR
RUN apt-get update && apt-get install -y frr
# Создание директорий
RUN mkdir -p /etc/frr /var/log/frr
# Копирование конфигурации
COPY frr.conf /etc/frr/frr.conf
# Открытие BGP порта
EXPOSE 179
# Запуск FRR
CMD ["/usr/lib/frr/frrinit", "start"]
```
### Конфигурация (frr.conf)
```
! FRR configuration
hostname bgp-server
password zebra
enable password zebra
! BGP configuration
router bgp 65000
bgp router-id 192.168.1.100
neighbor 192.168.1.1 remote-as 65001
neighbor 192.168.1.1 description RouterOS
!
address-family ipv4 unicast
network 192.168.1.0/24
network 10.0.0.0/8
network 172.16.0.0/12
neighbor 192.168.1.1 activate
exit-address-family
```
## 3. GoBGP
### Преимущества
- Современный подход
- Высокая производительность
- Поддержка gRPC API
- Легкая интеграция с Go приложениями
### Недостатки
- Меньше готовых примеров
- Требует знания Go для расширения
### Dockerfile
```dockerfile
FROM golang:1.19-alpine
# Установка GoBGP
RUN go install github.com/osrg/gobgp/cmd/gobgpd@latest
# Создание директорий
RUN mkdir -p /etc/gobgp
# Копирование конфигурации
COPY gobgpd.conf /etc/gobgpd.conf
# Открытие BGP порта
EXPOSE 179
# Запуск GoBGP
CMD ["gobgpd", "-f", "/etc/gobgpd.conf"]
```
### Конфигурация (gobgpd.conf)
```toml
[global.config]
as = 65000
router-id = "192.168.1.100"
[[neighbors]]
[neighbors.config]
neighbor-address = "192.168.1.1"
peer-as = 65001
[[neighbors.afi-safis]]
[neighbors.afi-safis.config]
afi-safi-name = "ipv4-unicast"
[[defined-sets.prefix-sets]]
prefix-set-name = "prefixes"
[[defined-sets.prefix-sets.prefix-list]]
ip-prefix = "192.168.1.0/24"
[[defined-sets.prefix-sets.prefix-list]]
ip-prefix = "10.0.0.0/8"
[[defined-sets.prefix-sets.prefix-list]]
ip-prefix = "172.16.0.0/12"
```
## 4. Quagga (устаревший)
### Преимущества
- Простая конфигурация
- Много документации
- Стабильность
### Недостатки
- Устаревший проект
- Отсутствие обновлений
- Проблемы с безопасностью
### Dockerfile
```dockerfile
FROM ubuntu:18.04
# Установка Quagga
RUN apt-get update && apt-get install -y quagga
# Создание директорий
RUN mkdir -p /etc/quagga /var/log/quagga
# Копирование конфигурации
COPY zebra.conf /etc/quagga/zebra.conf
COPY bgpd.conf /etc/quagga/bgpd.conf
# Открытие BGP порта
EXPOSE 179
# Запуск Quagga
CMD ["/usr/lib/quagga/zebra", "-f", "/etc/quagga/zebra.conf"]
```
## 5. Собственное решение на Python
### Преимущества
- Полный контроль
- Легкая кастомизация
- Простота отладки
### Недостатки
- Требует разработки
- Меньше производительность
- Необходимость поддержки
### Пример реализации
```python
import asyncio
import ipaddress
from pybgp import BGP
class BGPServer:
def __init__(self, local_as, router_id, neighbor_ip, neighbor_as):
self.local_as = local_as
self.router_id = router_id
self.neighbor_ip = neighbor_ip
self.neighbor_as = neighbor_as
self.prefixes = set()
async def load_prefixes(self, filename):
"""Загрузка префиксов из файла"""
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
try:
ipaddress.ip_network(line)
self.prefixes.add(line)
except ValueError:
print(f"Invalid prefix: {line}")
async def announce_prefixes(self):
"""Анонсирование префиксов"""
for prefix in self.prefixes:
# Логика анонсирования
pass
async def main():
server = BGPServer(65000, "192.168.1.100", "192.168.1.1", 65001)
await server.load_prefixes("prefixes.txt")
await server.announce_prefixes()
if __name__ == "__main__":
asyncio.run(main())
```
## Сравнение решений
| Решение | Простота | Производительность | Документация | Поддержка |
|---------|----------|-------------------|--------------|-----------|
| ExaBGP | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| Bird | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| FRR | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| GoBGP | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Quagga | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ |
| Python | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
## Рекомендации
### Для простых задач
- **ExaBGP** - лучший выбор для быстрого прототипирования
- **Python решение** - для полного контроля
### Для продакшн использования
- **Bird** - для высокой производительности
- **FRR** - для совместимости с Cisco
### Для современных проектов
- **GoBGP** - для интеграции с микросервисами
- **ExaBGP** - для простых сценариев
## Заключение
Выбор решения зависит от конкретных требований:
- Простота настройки → ExaBGP
- Производительность → Bird/FRR
- Современность → GoBGP
- Контроль → Python решение
Для большинства случаев ExaBGP является оптимальным выбором благодаря простоте настройки и достаточной производительности.
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
# Bash script to check BGP server status on Linux
# BGP Server Status Check Script
echo -e "\033[36mChecking BGP Server Status...\033[0m"
# Check if Docker is running
if ! docker version >/dev/null 2>&1; then
echo -e "\033[31m✗ Docker is not running\033[0m"
exit 1
fi
echo -e "\033[32m✓ Docker is running\033[0m"
# Check container status
echo -e "\n\033[33mContainer Status:\033[0m"
container_status=$(docker ps --filter "name=bgp-server" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}")
if [ -n "$container_status" ] && ! echo "$container_status" | grep -q "NAMES"; then
echo -e "\033[32m$container_status\033[0m"
else
echo -e "\033[31m✗ BGP container is not running\033[0m"
echo -e "\033[33mTo start the server, run: ./start-bgp-server.sh\033[0m"
exit 1
fi
# Check network ports
echo -e "\n\033[33mNetwork Ports:\033[0m"
if netstat -tuln 2>/dev/null | grep -q ":179 "; then
echo -e "\033[32m✓ BGP port 179 is listening\033[0m"
else
echo -e "\033[31m✗ BGP port 179 is not listening\033[0m"
fi
if netstat -tuln 2>/dev/null | grep -q ":2601 "; then
echo -e "\033[32m✓ vtysh port 2601 is listening\033[0m"
else
echo -e "\033[31m✗ vtysh port 2601 is not listening\033[0m"
fi
# Check BGP status inside container
echo -e "\n\033[33mBGP Status:\033[0m"
bgp_summary=$(docker exec bgp-server vtysh -c "show ip bgp summary" 2>/dev/null)
if [ -n "$bgp_summary" ]; then
echo -e "\033[32m✓ BGP daemon is running\033[0m"
echo -e "\033[36mBGP Summary:\033[0m"
echo -e "\033[37m$bgp_summary\033[0m"
else
echo -e "\033[31m✗ BGP daemon is not responding\033[0m"
fi
# Check recent logs
echo -e "\n\033[33mRecent Logs:\033[0m"
recent_logs=$(docker-compose logs --tail=10 bgp-server 2>/dev/null)
if [ -n "$recent_logs" ]; then
echo -e "\033[37m$recent_logs\033[0m"
else
echo -e "\033[90mNo recent logs available\033[0m"
fi
echo -e "\n\033[32mStatus check completed!\033[0m"
-10
View File
@@ -1,10 +0,0 @@
# Дополнительные префиксы
# Этот файл может содержать дополнительные сети для анонсирования
# Тестовые сети
192.168.100.0/24
192.168.200.0/24
# Специальные сети
10.10.10.0/24
10.20.20.0/24
-9
View File
@@ -1,9 +0,0 @@
# Основные префиксы
192.168.100.0/24
192.168.101.0/24
10.0.0.0/8
172.16.0.0/12
# Дополнительные префиксы
203.0.113.0/24
198.51.100.0/24
+22 -23
View File
@@ -2,31 +2,30 @@ version: '3.8'
services:
bgp-server:
build: .
image: quay.io/frrouting/frr:latest
container_name: bgp-server
restart: unless-stopped
ports:
- "179:179" # BGP порт
hostname: bgp-server
privileged: true
network_mode: host
volumes:
- ./data:/app/data:ro
- ./logs:/app/logs
- ./frr.conf:/etc/frr/frr.conf:ro
- ./prefixes.txt:/etc/frr/prefixes.txt:ro
- frr-logs:/var/log/frr
- frr-run:/var/run/frr
environment:
- BGP_LOCAL_AS=65000
- BGP_ROUTER_ID=192.168.100.99
- BGP_NEIGHBOR_IP=192.168.0.254
- BGP_NEIGHBOR_AS=65001
- BGP_HOLD_TIME=90
- BGP_KEEPALIVE=30
- BGP_LOG_LEVEL=info
networks:
- bgp-network
- FRR_USER=frr
- FRR_VTYSH_PASSWORD=zebra
ports:
- "179:179" # BGP port
- "2601:2601" # vtysh port
restart: unless-stopped
command: ["/usr/lib/frr/frrinit.sh", "start"]
cap_add:
- NET_ADMIN # Для работы с сетевыми интерфейсами
privileged: true # Для работы с FRR демонами
- NET_ADMIN
- SYS_ADMIN
security_opt:
- seccomp:unconfined
networks:
bgp-network:
driver: bridge
ipam:
config:
- subnet: 192.168.100.0/24
volumes:
frr-logs:
frr-run:
+62 -39
View File
@@ -1,46 +1,69 @@
# FRR Configuration File
# Этот файл будет перезаписан динамически сгенерированной конфигурацией
# из переменных окружения при запуске контейнера.
#
# Для просмотра текущей конфигурации используйте:
# docker exec bgp-server cat /etc/frr/frr.conf
# FRRouting configuration file
# BGP Server Configuration
# Глобальные настройки
frr version 8.5.2
frr defaults traditional
hostname bgp-server
log syslog info
service integrated-vtysh-config
# Enable password for vtysh
password zebra
enable password zebra
# Настройки BGP
# Router ID
router-id 192.168.1.1
# BGP configuration
router bgp 65000
bgp router-id 192.168.100.99
bgp log-neighbor-changes
neighbor 192.168.0.254 remote-as 65001
neighbor 192.168.0.254 description RouterOS Client
neighbor 192.168.0.254 timers 30 90
neighbor 192.168.0.254 capability graceful-restart
neighbor 192.168.0.254 soft-reconfiguration inbound
!
address-family ipv4 unicast
neighbor 192.168.0.254 activate
neighbor 192.168.0.254 route-map OUTBOUND out
neighbor 192.168.0.254 route-map INBOUND in
exit-address-family
!
bgp router-id 192.168.1.1
# Route maps для фильтрации
route-map OUTBOUND permit 10
description Allow all outbound routes
!
route-map INBOUND deny 10
description Deny all inbound routes (receive-only mode)
!
# Network configuration
network 192.168.1.0/24
network 10.0.0.0/8
network 172.16.0.0/12
network 203.0.113.0/24
network 198.51.100.0/24
network 192.0.2.0/24
network 8.8.8.0/24
network 1.1.1.0/24
network 9.9.9.0/24
# Настройки интерфейса
# IPv6 networks
network 2001:db8::/32
network 2001:db8:1::/48
network 2001:db8:2::/48
# Community configuration
neighbor 0.0.0.0/0 remote-as external
neighbor 0.0.0.0/0 send-community
neighbor 0.0.0.0/0 send-community extended
# IPv6 neighbors
neighbor ::/0 remote-as external
neighbor ::/0 send-community
neighbor ::/0 send-community extended
# Route redistribution
redistribute connected
redistribute static
# Static routes with communities
ip route 192.168.1.0/24 null0 community 65000:100:65000:200
ip route 10.0.0.0/8 null0 community 65000:101:65000:201
ip route 172.16.0.0/12 null0 community 65000:102:65000:202
ip route 203.0.113.0/24 null0 community 65000:110:65000:210
ip route 198.51.100.0/24 null0 community 65000:111:65000:211
ip route 192.0.2.0/24 null0 community 65000:112:65000:212
ip route 8.8.8.0/24 null0 community 65000:120:65000:220
ip route 1.1.1.0/24 null0 community 65000:121:65000:221
ip route 9.9.9.0/24 null0 community 65000:122:65000:222
# IPv6 static routes
ipv6 route 2001:db8::/32 null0 community 65000:300:65000:400
ipv6 route 2001:db8:1::/48 null0 community 65000:301:65000:401
ipv6 route 2001:db8:2::/48 null0 community 65000:302:65000:402
# Interface configuration
interface eth0
ip address 192.168.100.99/24
!
ip address 192.168.1.1/24
ipv6 address 2001:db8::1/64
no shutdown
# Статические маршруты (будут добавлены динамически)
# ip route 192.168.1.0/24 Null0
# Logging
log file /var/log/frr/frr.log
log timestamp precision 6
+106
View File
@@ -0,0 +1,106 @@
#!/bin/bash
# Bash script to install dependencies on Linux
# Dependencies Installation Script
echo -e "\033[36mInstalling BGP Server Dependencies...\033[0m"
# Detect OS
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
VER=$VERSION_ID
else
echo -e "\033[31mCannot detect OS version\033[0m"
exit 1
fi
echo -e "\033[33mDetected OS: $OS $VER\033[0m"
# Function to install Docker
install_docker() {
echo -e "\033[33mInstalling Docker...\033[0m"
# Remove old versions
sudo apt-get remove docker docker-engine docker.io containerd runc 2>/dev/null || true
# Update package index
sudo apt-get update
# Install prerequisites
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Set up stable repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# Add user to docker group
sudo usermod -aG docker $USER
# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
echo -e "\033[32m✓ Docker installed successfully\033[0m"
echo -e "\033[33mNote: You may need to log out and back in for group changes to take effect\033[0m"
}
# Function to install Docker Compose
install_docker_compose() {
echo -e "\033[33mInstalling Docker Compose...\033[0m"
# Download Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Make it executable
sudo chmod +x /usr/local/bin/docker-compose
# Create symbolic link
sudo ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
echo -e "\033[32m✓ Docker Compose installed successfully\033[0m"
}
# Check if Docker is installed
if ! command -v docker &> /dev/null; then
echo -e "\033[31mDocker is not installed\033[0m"
install_docker
else
echo -e "\033[32m✓ Docker is already installed\033[0m"
fi
# Check if Docker Compose is installed
if ! command -v docker-compose &> /dev/null; then
echo -e "\033[31mDocker Compose is not installed\033[0m"
install_docker_compose
else
echo -e "\033[32m✓ Docker Compose is already installed\033[0m"
fi
# Make scripts executable
echo -e "\033[33mMaking scripts executable...\033[0m"
chmod +x *.sh
# Test Docker installation
echo -e "\033[33mTesting Docker installation...\033[0m"
if sudo docker run hello-world >/dev/null 2>&1; then
echo -e "\033[32m✓ Docker is working correctly\033[0m"
else
echo -e "\033[31m✗ Docker test failed\033[0m"
echo -e "\033[33mYou may need to log out and back in, or restart the system\033[0m"
fi
echo -e "\n\033[32mDependencies installation completed!\033[0m"
echo -e "\033[33mTo start the BGP server, run: ./start-bgp-server.sh\033[0m"
+23
View File
@@ -0,0 +1,23 @@
# BGP Prefixes with Communities
# Format: prefix community1:community2:community3
# Communities format: ASN:value (e.g., 65000:100)
# Public IP ranges
192.168.1.0/24 65000:100:65000:200
10.0.0.0/8 65000:101:65000:201
172.16.0.0/12 65000:102:65000:202
# Specific subnets
203.0.113.0/24 65000:110:65000:210
198.51.100.0/24 65000:111:65000:211
192.0.2.0/24 65000:112:65000:212
# IPv6 prefixes
2001:db8::/32 65000:300:65000:400
2001:db8:1::/48 65000:301:65000:401
2001:db8:2::/48 65000:302:65000:402
# Additional prefixes for testing
8.8.8.0/24 65000:120:65000:220
1.1.1.0/24 65000:121:65000:221
9.9.9.0/24 65000:122:65000:222
+63
View File
@@ -0,0 +1,63 @@
#!/bin/bash
# Quick run script for BGP container
# Simple one-command BGP server launcher
echo -e "\033[32m🚀 Quick BGP Server Launcher\033[0m"
# Check if required files exist
if [ ! -f "frr.conf" ]; then
echo -e "\033[31mError: frr.conf not found in current directory\033[0m"
exit 1
fi
if [ ! -f "prefixes.txt" ]; then
echo -e "\033[31mError: prefixes.txt not found in current directory\033[0m"
exit 1
fi
# Stop existing container if running
docker stop bgp-server 2>/dev/null || true
docker rm bgp-server 2>/dev/null || true
# Pull latest image
echo -e "\033[33m📥 Pulling FRRouting image...\033[0m"
docker pull quay.io/frrouting/frr:latest
# Run container
echo -e "\033[33m🚀 Starting BGP server...\033[0m"
docker run -d \
--name bgp-server \
--hostname bgp-server \
--privileged \
--network host \
-v "$(pwd)/frr.conf:/etc/frr/frr.conf:ro" \
-v "$(pwd)/prefixes.txt:/etc/frr/prefixes.txt:ro" \
-e FRR_USER=frr \
-e FRR_VTYSH_PASSWORD=zebra \
--cap-add=NET_ADMIN \
--cap-add=SYS_ADMIN \
--security-opt seccomp=unconfined \
--restart unless-stopped \
quay.io/frrouting/frr:latest \
/usr/lib/frr/frrinit.sh start
# Wait for startup
sleep 5
# Show status
echo -e "\033[36m📊 Container Status:\033[0m"
docker ps --filter "name=bgp-server" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# Show BGP status
echo -e "\n\033[36m🌐 BGP Status:\033[0m"
if docker exec bgp-server vtysh -c "show ip bgp summary" 2>/dev/null; then
echo -e "\n\033[32m✅ BGP Server is running successfully!\033[0m"
else
echo -e "\n\033[33m⚠️ BGP daemon is starting up...\033[0m"
fi
echo -e "\n\033[33m🔧 Useful commands:\033[0m"
echo -e " Connect to vtysh: docker exec -it bgp-server vtysh"
echo -e " View logs: docker logs bgp-server"
echo -e " Stop server: docker stop bgp-server"
echo -e " Check status: docker ps | grep bgp-server"
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
# Quick stop script for BGP container
# Simple one-command BGP server stopper
echo -e "\033[33m🛑 Quick BGP Server Stopper\033[0m"
# Check if container is running
if docker ps -q -f name=bgp-server | grep -q .; then
echo -e "\033[33m⏹️ Stopping BGP server...\033[0m"
docker stop bgp-server
docker rm bgp-server
echo -e "\033[32m✅ BGP Server stopped successfully!\033[0m"
else
echo -e "\033[31m❌ BGP Server is not running\033[0m"
fi
# Show remaining containers
echo -e "\n\033[36m📊 Remaining containers:\033[0m"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo -e "\n\033[33m🚀 To start again: ./quick-run.sh\033[0m"
-1
View File
@@ -1 +0,0 @@
watchdog>=2.1.0
-255
View File
@@ -1,255 +0,0 @@
# Настройка RouterOS для работы с BGP сервером
## Требования
- RouterOS 7.14 или выше
- Доступ к командной строке RouterOS (WinBox, SSH, или Console)
- Сетевое подключение к BGP серверу
## Схема подключения
```
RouterOS (192.168.1.1) ←→ BGP Server (192.168.1.100)
AS: 65001 AS: 65000
```
## Пошаговая настройка
### Шаг 1: Проверка сетевого подключения
Убедитесь, что RouterOS может достичь BGP сервера:
```routeros
/ping 192.168.1.100 count=4
```
Ожидаемый результат:
```
HOST SIZE TTL TIME STATUS
192.168.1.100 56 64 0.5ms echo reply
192.168.1.100 56 64 0.4ms echo reply
192.168.1.100 56 64 0.5ms echo reply
192.168.1.100 56 64 0.4ms echo reply
sent=4 received=4 packet-loss=0% min-rtt=0.4ms avg-rtt=0.5ms max-rtt=0.5ms
```
### Шаг 2: Создание BGP экземпляра
```routeros
/routing bgp instance
add name=bgp-server as=65001 router-id=192.168.1.1
```
### Шаг 3: Настройка BGP сети
```routeros
/routing bgp network
add network=192.168.1.0/24
```
### Шаг 4: Настройка BGP пира
```routeros
/routing bgp peer
add name=bgp-server remote-address=192.168.1.100 remote-as=65000 instance=bgp-server
```
### Шаг 5: Включение BGP экземпляра
```routeros
/routing bgp instance set bgp-server disabled=no
```
### Шаг 6: Проверка статуса BGP сессии
```routeros
/routing bgp peer print
```
Ожидаемый результат:
```
Flags: X - disabled, I - invalid, D - dynamic, E - established
0 name="bgp-server" instance=bgp-server remote-address=192.168.1.100 remote-as=65000
tcp-md5-key="" nexthop-choice=default multihop=no route-reflect=no hold-time=3m
keepalive-time=1m address-families=ip,ipv6 default-originate=never remove-private-as=no
as-override=no passive=no use-bfd=no cisco-vpls-nlri-len-fmt=no add-path=0/0
remove-private-as-if-export=no in-filter="" out-filter=""
state=established uptime=1m30s prefix-count=8 updates-sent=8 updates-received=0
withdrawn-sent=0 withdrawn-received=0
```
## Дополнительные настройки
### Настройка MD5 аутентификации (рекомендуется)
```routeros
/routing bgp peer set bgp-server tcp-md5-key="your-secure-password"
```
### Настройка фильтров (опционально)
Создание фильтра для входящих маршрутов:
```routeros
/routing filter
add name=bgp-in chain=input protocol=bgp
add name=bgp-in chain=input protocol=bgp action=accept
```
Применение фильтра к BGP пиру:
```routeros
/routing bgp peer set bgp-server in-filter=bgp-in
```
### Настройка таймаутов
```routeros
/routing bgp peer set bgp-server hold-time=90s keepalive-time=30s
```
## Мониторинг и диагностика
### Проверка статуса BGP сессии
```routeros
/routing bgp peer print detail
```
### Просмотр полученных маршрутов
```routeros
/routing bgp routes print
```
### Просмотр логов BGP
```routeros
/log print where topics~"bgp"
```
### Проверка статистики BGP
```routeros
/routing bgp peer print stats
```
## Устранение неполадок
### Проблема: BGP сессия не устанавливается
1. Проверьте сетевое подключение:
```routeros
/ping 192.168.1.100
```
2. Проверьте настройки BGP пира:
```routeros
/routing bgp peer print detail
```
3. Проверьте логи:
```routeros
/log print where topics~"bgp"
```
### Проблема: Маршруты не получаются
1. Проверьте статус сессии:
```routeros
/routing bgp peer print
```
2. Проверьте фильтры:
```routeros
/routing filter print
```
3. Проверьте полученные маршруты:
```routeros
/routing bgp routes print
```
### Проблема: Неправильные AS номера
Убедитесь, что AS номера настроены правильно:
```routeros
/routing bgp instance print
/routing bgp peer print
```
## Полезные команды
### Экспорт конфигурации BGP
```routeros
/export compact where routing~"bgp"
```
### Сброс BGP сессии
```routeros
/routing bgp peer reset bgp-server
```
### Просмотр детальной информации о пире
```routeros
/routing bgp peer print detail where name="bgp-server"
```
### Мониторинг в реальном времени
```routeros
/routing bgp peer monitor bgp-server
```
## Безопасность
### Рекомендации по безопасности
1. **Используйте MD5 аутентификацию**
2. **Настройте фильтры для входящих маршрутов**
3. **Ограничьте доступ к BGP порту (179)**
4. **Регулярно проверяйте логи**
### Настройка firewall для BGP
```routeros
/ip firewall filter
add chain=input protocol=tcp dst-port=179 src-address=192.168.1.100 action=accept comment="BGP from server"
add chain=input protocol=tcp dst-port=179 action=drop comment="Block other BGP"
```
## Автоматизация
### Скрипт для автоматической настройки
Создайте файл `bgp-setup.rsc`:
```routeros
# BGP Setup Script
/routing bgp instance
add name=bgp-server as=65001 router-id=192.168.1.1
/routing bgp network
add network=192.168.1.0/24
/routing bgp peer
add name=bgp-server remote-address=192.168.1.100 remote-as=65000 instance=bgp-server
/routing bgp instance set bgp-server disabled=no
:log info "BGP setup completed"
```
Загрузите и выполните скрипт:
```routeros
/import bgp-setup.rsc
```
## Заключение
После выполнения всех шагов RouterOS должен успешно установить BGP сессию с сервером и начать получать маршруты. Регулярно проверяйте статус сессии и логи для обеспечения стабильной работы.
+148
View File
@@ -0,0 +1,148 @@
#!/bin/bash
# Ready-to-use Docker container script for BGP server
# BGP Container Runner Script
CONTAINER_NAME="bgp-server"
IMAGE_NAME="quay.io/frrouting/frr:latest"
BGP_PORT="179"
VTYSH_PORT="2601"
CONFIG_DIR="$(pwd)"
echo -e "\033[36m=== BGP Server Container Runner ===\033[0m"
# Function to check if Docker is running
check_docker() {
if ! docker version >/dev/null 2>&1; then
echo -e "\033[31mError: Docker is not running. Please start Docker first.\033[0m"
exit 1
fi
echo -e "\033[32m✓ Docker is running\033[0m"
}
# Function to stop existing container
stop_container() {
if docker ps -q -f name=$CONTAINER_NAME | grep -q .; then
echo -e "\033[33mStopping existing container...\033[0m"
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
fi
}
# Function to pull image
pull_image() {
echo -e "\033[33mPulling FRRouting image...\033[0m"
docker pull $IMAGE_NAME
}
# Function to create and run container
run_container() {
echo -e "\033[33mStarting BGP container...\033[0m"
docker run -d \
--name $CONTAINER_NAME \
--hostname $CONTAINER_NAME \
--privileged \
--network host \
-v "$CONFIG_DIR/frr.conf:/etc/frr/frr.conf:ro" \
-v "$CONFIG_DIR/prefixes.txt:/etc/frr/prefixes.txt:ro" \
-e FRR_USER=frr \
-e FRR_VTYSH_PASSWORD=zebra \
--cap-add=NET_ADMIN \
--cap-add=SYS_ADMIN \
--security-opt seccomp=unconfined \
--restart unless-stopped \
$IMAGE_NAME \
/usr/lib/frr/frrinit.sh start
}
# Function to check container status
check_status() {
echo -e "\033[36mContainer Status:\033[0m"
docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo -e "\n\033[36mNetwork Ports:\033[0m"
if netstat -tuln 2>/dev/null | grep -q ":179 "; then
echo -e "\033[32m✓ BGP port 179 is listening\033[0m"
else
echo -e "\033[31m✗ BGP port 179 is not listening\033[0m"
fi
if netstat -tuln 2>/dev/null | grep -q ":2601 "; then
echo -e "\033[32m✓ vtysh port 2601 is listening\033[0m"
else
echo -e "\033[31m✗ vtysh port 2601 is not listening\033[0m"
fi
}
# Function to show logs
show_logs() {
echo -e "\n\033[36mContainer Logs:\033[0m"
docker logs $CONTAINER_NAME
}
# Function to show usage
show_usage() {
echo -e "\033[33mUsage:\033[0m"
echo -e " $0 [start|stop|restart|status|logs|help]"
echo -e ""
echo -e "\033[33mCommands:\033[0m"
echo -e " start - Start BGP container"
echo -e " stop - Stop BGP container"
echo -e " restart - Restart BGP container"
echo -e " status - Show container status"
echo -e " logs - Show container logs"
echo -e " help - Show this help"
echo -e ""
echo -e "\033[33mExamples:\033[0m"
echo -e " $0 start"
echo -e " $0 status"
echo -e " $0 logs"
}
# Main script logic
case "${1:-start}" in
start)
check_docker
stop_container
pull_image
run_container
sleep 3
check_status
show_logs
echo -e "\n\033[32mBGP Server is running!\033[0m"
echo -e "\033[33mTo connect to vtysh: docker exec -it $CONTAINER_NAME vtysh\033[0m"
echo -e "\033[33mTo view logs: $0 logs\033[0m"
echo -e "\033[33mTo stop: $0 stop\033[0m"
;;
stop)
echo -e "\033[33mStopping BGP container...\033[0m"
docker stop $CONTAINER_NAME 2>/dev/null || true
docker rm $CONTAINER_NAME 2>/dev/null || true
echo -e "\033[32mBGP container stopped\033[0m"
;;
restart)
echo -e "\033[33mRestarting BGP container...\033[0m"
$0 stop
sleep 2
$0 start
;;
status)
check_docker
check_status
;;
logs)
if docker ps -q -f name=$CONTAINER_NAME | grep -q .; then
show_logs
else
echo -e "\033[31mContainer is not running\033[0m"
fi
;;
help|--help|-h)
show_usage
;;
*)
echo -e "\033[31mUnknown command: $1\033[0m"
show_usage
exit 1
;;
esac
-95
View File
@@ -1,95 +0,0 @@
#!/usr/bin/env python3
"""
Скрипт для генерации конфигурации FRR из переменных окружения
"""
import os
import sys
from pathlib import Path
def get_env_var(name, default):
"""Получение переменной окружения с значением по умолчанию"""
return os.environ.get(name, default)
def generate_frr_config():
"""Генерация конфигурации FRR"""
# Получение настроек из переменных окружения
local_as = get_env_var('BGP_LOCAL_AS', '65000')
router_id = get_env_var('BGP_ROUTER_ID', '192.168.100.99')
neighbor_ip = get_env_var('BGP_NEIGHBOR_IP', '192.168.0.254')
neighbor_as = get_env_var('BGP_NEIGHBOR_AS', '65001')
hold_time = get_env_var('BGP_HOLD_TIME', '90')
keepalive = get_env_var('BGP_KEEPALIVE', '30')
log_level = get_env_var('BGP_LOG_LEVEL', 'info')
# Конфигурация FRR
config = f"""# FRR Configuration File
# Generated automatically from environment variables
# Глобальные настройки
frr version 8.5.2
frr defaults traditional
hostname bgp-server
log syslog {log_level}
service integrated-vtysh-config
# Настройки BGP
router bgp {local_as}
bgp router-id {router_id}
bgp log-neighbor-changes
neighbor {neighbor_ip} remote-as {neighbor_as}
neighbor {neighbor_ip} description RouterOS Client
neighbor {neighbor_ip} timers {keepalive} {hold_time}
neighbor {neighbor_ip} capability graceful-restart
neighbor {neighbor_ip} soft-reconfiguration inbound
!
address-family ipv4 unicast
neighbor {neighbor_ip} activate
neighbor {neighbor_ip} route-map OUTBOUND out
neighbor {neighbor_ip} route-map INBOUND in
exit-address-family
!
# Route maps для фильтрации
route-map OUTBOUND permit 10
description Allow all outbound routes
!
route-map INBOUND deny 10
description Deny all inbound routes (receive-only mode)
!
# Настройки интерфейса
interface eth0
ip address {router_id}/24
!
# Статические маршруты (будут добавлены динамически)
# ip route 192.168.1.0/24 Null0
"""
return config
def main():
"""Основная функция"""
try:
# Генерация конфигурации
config = generate_frr_config()
# Запись в файл
config_path = Path('/etc/frr/frr.conf')
config_path.parent.mkdir(parents=True, exist_ok=True)
with open(config_path, 'w') as f:
f.write(config)
print(f"FRR configuration generated: {config_path}")
print("Configuration content:")
print(config)
except Exception as e:
print(f"Error generating FRR configuration: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
-245
View File
@@ -1,245 +0,0 @@
#!/usr/bin/env python3
"""
Скрипт для загрузки префиксов из текстовых файлов в FRR
"""
import sys
import os
import time
import subprocess
import ipaddress
from pathlib import Path
from typing import List, Set
# Настройки
DATA_DIR = "/app/data"
LOG_FILE = "/app/logs/prefixes.log"
PREFIX_FILES = ["prefixes.txt", "additional_prefixes.txt"]
def log_message(message: str):
"""Запись сообщения в лог"""
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {message}"
# Вывод в stdout
print(log_entry, flush=True)
# Запись в файл (с обработкой ошибок)
try:
with open(LOG_FILE, "a") as f:
f.write(log_entry + "\n")
except (PermissionError, OSError) as e:
# Если не можем записать в файл, просто выводим в stderr
print(f"Warning: Could not write to log file: {e}", file=sys.stderr, flush=True)
def log_error(message: str):
"""Запись ошибки в лог"""
log_message(f"ERROR: {message}")
def validate_prefix(prefix: str) -> bool:
"""Валидация IP префикса"""
try:
ipaddress.ip_network(prefix, strict=False)
return True
except ValueError:
return False
def load_prefixes_from_file(file_path: Path) -> Set[str]:
"""Загрузка префиксов из файла"""
prefixes = set()
if not file_path.exists():
log_message(f"File not found: {file_path}")
return prefixes
try:
with open(file_path, 'r') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
# Пропуск пустых строк и комментариев
if not line or line.startswith('#'):
continue
# Валидация префикса
if validate_prefix(line):
prefixes.add(line)
else:
log_message(f"Invalid prefix in {file_path}:{line_num}: {line}")
except Exception as e:
log_message(f"Error reading {file_path}: {e}")
return prefixes
def load_all_prefixes() -> Set[str]:
"""Загрузка всех префиксов из всех файлов"""
all_prefixes = set()
for filename in PREFIX_FILES:
file_path = Path(DATA_DIR) / filename
prefixes = load_prefixes_from_file(file_path)
all_prefixes.update(prefixes)
log_message(f"Loaded {len(prefixes)} prefixes from {filename}")
return all_prefixes
def run_vtysh_command(command: str) -> bool:
"""Выполнение команды через vtysh"""
try:
result = subprocess.run(
['vtysh', '-c', command],
capture_output=True,
text=True,
timeout=30
)
if result.returncode != 0:
log_error(f"vtysh command failed: {command}")
log_error(f"stderr: {result.stderr}")
return False
return True
except subprocess.TimeoutExpired:
log_error(f"vtysh command timeout: {command}")
return False
except Exception as e:
log_error(f"Error running vtysh command '{command}': {e}")
return False
def announce_prefixes(prefixes: Set[str]):
"""Анонсирование префиксов через FRR"""
log_message(f"Announcing {len(prefixes)} prefixes...")
for prefix in sorted(prefixes):
# Добавление статического маршрута в FRR
command = f"ip route {prefix} Null0"
if run_vtysh_command(command):
log_message(f"Announced prefix: {prefix}")
else:
log_error(f"Failed to announce prefix: {prefix}")
def withdraw_prefixes(prefixes: Set[str]):
"""Отзыв префиксов через FRR"""
log_message(f"Withdrawing {len(prefixes)} prefixes...")
for prefix in sorted(prefixes):
# Удаление статического маршрута из FRR
command = f"no ip route {prefix} Null0"
if run_vtysh_command(command):
log_message(f"Withdrew prefix: {prefix}")
else:
log_error(f"Failed to withdraw prefix: {prefix}")
def check_frr_status() -> bool:
"""Проверка статуса FRR"""
try:
result = subprocess.run(
['vtysh', '-c', 'show version'],
capture_output=True,
text=True,
timeout=10
)
return result.returncode == 0
except Exception:
return False
def wait_for_frr():
"""Ожидание запуска FRR"""
log_message("Waiting for FRR to start...")
max_attempts = 30
attempt = 0
while attempt < max_attempts:
if check_frr_status():
log_message("FRR is ready")
return True
attempt += 1
time.sleep(2)
if attempt % 5 == 0:
log_message(f"Still waiting for FRR... (attempt {attempt}/{max_attempts})")
log_error("FRR did not start within expected time")
return False
def main():
"""Основная функция"""
# Создание директории для логов в начале
try:
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
except (PermissionError, OSError):
pass # Игнорируем ошибки создания директории
# Проверка тестового режима
if len(sys.argv) > 1 and sys.argv[1] == '--test':
print("Testing prefix loader...")
prefixes = load_all_prefixes()
print(f"Found {len(prefixes)} prefixes: {list(prefixes)}")
return
# Проверка режима отзыва
if len(sys.argv) > 1 and sys.argv[1] == '--withdraw':
log_message("Withdraw mode: loading and withdrawing all prefixes...")
prefixes = load_all_prefixes()
if wait_for_frr():
withdraw_prefixes(prefixes)
return
log_message("Starting prefix loader...")
# Ожидание запуска FRR
if not wait_for_frr():
log_error("Cannot proceed without FRR")
return
# Загрузка префиксов
prefixes = load_all_prefixes()
log_message(f"Total prefixes loaded: {len(prefixes)}")
if not prefixes:
log_message("No valid prefixes found. Exiting.")
return
# Анонсирование префиксов
announce_prefixes(prefixes)
log_message("All prefixes announced successfully")
# Мониторинг изменений в файлах
log_message("Starting file monitoring...")
try:
while True:
time.sleep(30) # Проверка каждые 30 секунд
# Перезагрузка префиксов
new_prefixes = load_all_prefixes()
# Определение изменений
added = new_prefixes - prefixes
removed = prefixes - new_prefixes
if added:
log_message(f"Adding {len(added)} new prefixes: {list(added)}")
announce_prefixes(added)
if removed:
log_message(f"Removing {len(removed)} prefixes: {list(removed)}")
withdraw_prefixes(removed)
if added or removed:
prefixes = new_prefixes
log_message(f"Updated prefix count: {len(prefixes)}")
except KeyboardInterrupt:
log_message("Received interrupt signal")
except Exception as e:
log_message(f"Error in main loop: {e}")
finally:
# Отзыв всех префиксов при завершении
log_message("Withdrawing all prefixes...")
withdraw_prefixes(prefixes)
log_message("Prefix loader stopped")
if __name__ == "__main__":
main()
-194
View File
@@ -1,194 +0,0 @@
#!/usr/bin/env python3
"""
Скрипт мониторинга FRR BGP сервера
"""
import sys
import os
import time
import subprocess
import json
from pathlib import Path
from typing import Dict, Any
# Настройки
LOG_FILE = "/app/logs/monitor.log"
STATUS_FILE = "/app/logs/status.json"
def log_message(message: str):
"""Запись сообщения в лог"""
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {message}"
print(log_entry, flush=True)
try:
with open(LOG_FILE, "a") as f:
f.write(log_entry + "\n")
except (PermissionError, OSError):
pass
def run_vtysh_command(command: str) -> str:
"""Выполнение команды через vtysh"""
try:
result = subprocess.run(
['vtysh', '-c', command],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
return result.stdout.strip()
else:
log_message(f"vtysh command failed: {command}")
return ""
except Exception as e:
log_message(f"Error running vtysh command '{command}': {e}")
return ""
def get_bgp_summary() -> Dict[str, Any]:
"""Получение сводки BGP"""
summary = run_vtysh_command("show ip bgp summary")
if not summary:
return {"error": "Could not get BGP summary"}
# Парсинг вывода BGP summary
lines = summary.split('\n')
neighbors = []
for line in lines:
if 'BGP neighbor' in line and 'remote AS' in line:
parts = line.split()
if len(parts) >= 8:
neighbor = {
"ip": parts[2].rstrip(','),
"remote_as": parts[7],
"state": parts[-1] if len(parts) > 7 else "Unknown"
}
neighbors.append(neighbor)
return {
"neighbors": neighbors,
"raw_output": summary
}
def get_bgp_routes() -> Dict[str, Any]:
"""Получение BGP маршрутов"""
routes = run_vtysh_command("show ip bgp")
if not routes:
return {"error": "Could not get BGP routes"}
# Подсчет маршрутов
route_count = 0
for line in routes.split('\n'):
if line.strip() and not line.startswith('BGP table') and not line.startswith('*>'):
if any(char.isdigit() for char in line):
route_count += 1
return {
"route_count": route_count,
"raw_output": routes
}
def get_frr_status() -> Dict[str, Any]:
"""Получение статуса FRR"""
version = run_vtysh_command("show version")
if not version:
return {"error": "Could not get FRR version"}
return {
"version": version.split('\n')[0] if version else "Unknown",
"raw_output": version
}
def get_system_status() -> Dict[str, Any]:
"""Получение системного статуса"""
try:
# Проверка процессов FRR
zebra_running = subprocess.run(['pgrep', 'zebra'], capture_output=True).returncode == 0
bgpd_running = subprocess.run(['pgrep', 'bgpd'], capture_output=True).returncode == 0
# Проверка использования памяти
memory_info = {}
try:
with open('/proc/meminfo', 'r') as f:
for line in f:
if 'MemTotal:' in line:
memory_info['total'] = line.split()[1]
elif 'MemAvailable:' in line:
memory_info['available'] = line.split()[1]
except:
pass
return {
"zebra_running": zebra_running,
"bgpd_running": bgpd_running,
"memory": memory_info
}
except Exception as e:
return {"error": f"Could not get system status: {e}"}
def save_status(status: Dict[str, Any]):
"""Сохранение статуса в файл"""
try:
with open(STATUS_FILE, 'w') as f:
json.dump(status, f, indent=2)
except Exception as e:
log_message(f"Error saving status: {e}")
def main():
"""Основная функция"""
log_message("Starting FRR monitor...")
# Создание директории для логов
try:
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
os.makedirs(os.path.dirname(STATUS_FILE), exist_ok=True)
except (PermissionError, OSError):
pass
while True:
try:
# Сбор статуса
status = {
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
"frr": get_frr_status(),
"bgp_summary": get_bgp_summary(),
"bgp_routes": get_bgp_routes(),
"system": get_system_status()
}
# Сохранение статуса
save_status(status)
# Логирование важной информации
bgp_summary = status["bgp_summary"]
if "neighbors" in bgp_summary:
for neighbor in bgp_summary["neighbors"]:
log_message(f"BGP neighbor {neighbor['ip']} (AS {neighbor['remote_as']}): {neighbor['state']}")
bgp_routes = status["bgp_routes"]
if "route_count" in bgp_routes:
log_message(f"BGP routes: {bgp_routes['route_count']}")
system = status["system"]
if "zebra_running" in system and "bgpd_running" in system:
if not system["zebra_running"] or not system["bgpd_running"]:
log_message("WARNING: FRR daemons not running properly")
# Ожидание перед следующей проверкой
time.sleep(60) # Проверка каждую минуту
except KeyboardInterrupt:
log_message("Monitor stopped by user")
break
except Exception as e:
log_message(f"Error in monitor loop: {e}")
time.sleep(30) # Короткая пауза при ошибке
if __name__ == "__main__":
main()
-206
View File
@@ -1,206 +0,0 @@
#!/usr/bin/env python3
"""
Скрипт для перезагрузки префиксов в FRR
"""
import sys
import os
import time
import subprocess
import ipaddress
from pathlib import Path
from typing import Set
# Настройки
DATA_DIR = "/app/data"
LOG_FILE = "/app/logs/reload.log"
PREFIX_FILES = ["prefixes.txt", "additional_prefixes.txt"]
def log_message(message: str):
"""Запись сообщения в лог"""
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {message}"
print(log_entry, flush=True)
try:
with open(LOG_FILE, "a") as f:
f.write(log_entry + "\n")
except (PermissionError, OSError):
pass
def validate_prefix(prefix: str) -> bool:
"""Валидация IP префикса"""
try:
ipaddress.ip_network(prefix, strict=False)
return True
except ValueError:
return False
def load_prefixes_from_file(file_path: Path) -> Set[str]:
"""Загрузка префиксов из файла"""
prefixes = set()
if not file_path.exists():
log_message(f"File not found: {file_path}")
return prefixes
try:
with open(file_path, 'r') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
# Пропуск пустых строк и комментариев
if not line or line.startswith('#'):
continue
# Валидация префикса
if validate_prefix(line):
prefixes.add(line)
else:
log_message(f"Invalid prefix in {file_path}:{line_num}: {line}")
except Exception as e:
log_message(f"Error reading {file_path}: {e}")
return prefixes
def load_all_prefixes() -> Set[str]:
"""Загрузка всех префиксов из всех файлов"""
all_prefixes = set()
for filename in PREFIX_FILES:
file_path = Path(DATA_DIR) / filename
prefixes = load_prefixes_from_file(file_path)
all_prefixes.update(prefixes)
log_message(f"Loaded {len(prefixes)} prefixes from {filename}")
return all_prefixes
def get_current_routes() -> Set[str]:
"""Получение текущих статических маршрутов из FRR"""
try:
result = subprocess.run(
['vtysh', '-c', 'show ip route static'],
capture_output=True,
text=True,
timeout=30
)
if result.returncode != 0:
log_message("Could not get current routes from FRR")
return set()
routes = set()
for line in result.stdout.split('\n'):
line = line.strip()
if line and 'via Null0' in line:
# Парсинг строки маршрута
parts = line.split()
if len(parts) >= 2:
route = parts[1]
if validate_prefix(route):
routes.add(route)
return routes
except Exception as e:
log_message(f"Error getting current routes: {e}")
return set()
def run_vtysh_command(command: str) -> bool:
"""Выполнение команды через vtysh"""
try:
result = subprocess.run(
['vtysh', '-c', command],
capture_output=True,
text=True,
timeout=30
)
if result.returncode != 0:
log_message(f"vtysh command failed: {command}")
return False
return True
except Exception as e:
log_message(f"Error running vtysh command '{command}': {e}")
return False
def announce_prefixes(prefixes: Set[str]):
"""Анонсирование префиксов через FRR"""
log_message(f"Announcing {len(prefixes)} prefixes...")
for prefix in sorted(prefixes):
command = f"ip route {prefix} Null0"
if run_vtysh_command(command):
log_message(f"Announced prefix: {prefix}")
else:
log_message(f"Failed to announce prefix: {prefix}")
def withdraw_prefixes(prefixes: Set[str]):
"""Отзыв префиксов через FRR"""
log_message(f"Withdrawing {len(prefixes)} prefixes...")
for prefix in sorted(prefixes):
command = f"no ip route {prefix} Null0"
if run_vtysh_command(command):
log_message(f"Withdrew prefix: {prefix}")
else:
log_message(f"Failed to withdraw prefix: {prefix}")
def check_frr_status() -> bool:
"""Проверка статуса FRR"""
try:
result = subprocess.run(
['vtysh', '-c', 'show version'],
capture_output=True,
text=True,
timeout=10
)
return result.returncode == 0
except Exception:
return False
def main():
"""Основная функция"""
log_message("Starting prefix reload...")
# Проверка статуса FRR
if not check_frr_status():
log_message("ERROR: FRR is not running")
return 1
# Загрузка новых префиксов
new_prefixes = load_all_prefixes()
log_message(f"Loaded {len(new_prefixes)} prefixes from files")
# Получение текущих маршрутов
current_routes = get_current_routes()
log_message(f"Found {len(current_routes)} current routes in FRR")
# Определение изменений
to_add = new_prefixes - current_routes
to_remove = current_routes - new_prefixes
log_message(f"Changes: {len(to_add)} to add, {len(to_remove)} to remove")
# Применение изменений
if to_remove:
withdraw_prefixes(to_remove)
if to_add:
announce_prefixes(to_add)
# Финальная проверка
final_routes = get_current_routes()
log_message(f"Final route count: {len(final_routes)}")
if len(final_routes) == len(new_prefixes):
log_message("Reload completed successfully!")
return 0
else:
log_message("WARNING: Route count mismatch after reload")
return 1
if __name__ == "__main__":
sys.exit(main())
-123
View File
@@ -1,123 +0,0 @@
# Скрипт запуска BGP Server (FRR)
param(
[string]$ContainerName = "bgp-server",
[string]$DataPath = "./data",
[string]$LogsPath = "./logs",
[switch]$Build,
[switch]$Force
)
Write-Host "=== BGP Server (FRR) Startup Script ===" -ForegroundColor Green
# Проверка существования контейнера
$containerExists = docker ps -a --filter "name=$ContainerName" --format "table {{.Names}}" | Select-String $ContainerName
if ($containerExists) {
Write-Host "Found existing container: $ContainerName" -ForegroundColor Yellow
if (-not $Force) {
$response = Read-Host "Do you want to stop and remove the existing container? (y/N)"
if ($response -ne "y" -and $response -ne "Y") {
Write-Host "Operation cancelled." -ForegroundColor Red
exit 0
}
}
# Остановка и удаление старого контейнера
Write-Host "Stopping container..." -ForegroundColor Yellow
docker stop $ContainerName
Write-Host "Removing container..." -ForegroundColor Yellow
docker rm $ContainerName
}
# Создание директорий если не существуют
if (-not (Test-Path $DataPath)) {
Write-Host "Creating data directory: $DataPath" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $DataPath -Force | Out-Null
}
if (-not (Test-Path $LogsPath)) {
Write-Host "Creating logs directory: $LogsPath" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $LogsPath -Force | Out-Null
}
# Создание файла с префиксами если не существует
$prefixesFile = Join-Path $DataPath "prefixes.txt"
if (-not (Test-Path $prefixesFile)) {
Write-Host "Creating default prefixes file..." -ForegroundColor Yellow
@"
# Default prefixes file
# Add your prefixes here, one per line
192.168.100.0/24
10.0.0.0/8
172.16.0.0/12
"@ | Out-File -FilePath $prefixesFile -Encoding UTF8
}
# Сборка образа если требуется
if ($Build) {
Write-Host "Building Docker image..." -ForegroundColor Yellow
docker build -t bgp-server-frr .
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to build image. Exiting." -ForegroundColor Red
exit 1
}
}
# Запуск контейнера
Write-Host "Starting BGP Server container..." -ForegroundColor Yellow
$currentPath = Get-Location
$dataVolume = "${currentPath}\${DataPath}:/app/data:ro"
$logsVolume = "${currentPath}\${LogsPath}:/app/logs"
docker run -d `
--name $ContainerName `
--restart unless-stopped `
-p 179:179 `
-v $dataVolume `
-v $logsVolume `
--cap-add NET_ADMIN `
--privileged `
bgp-server-frr
if ($LASTEXITCODE -eq 0) {
Write-Host "Container started successfully!" -ForegroundColor Green
# Ожидание запуска
Write-Host "Waiting for container to start..." -ForegroundColor Yellow
Start-Sleep -Seconds 10
# Проверка статуса
$status = docker ps --filter "name=$ContainerName" --format "table {{.Status}}"
Write-Host "Container status: $status" -ForegroundColor Cyan
# Проверка FRR статуса
Write-Host "Checking FRR status..." -ForegroundColor Cyan
docker exec $ContainerName vtysh -c "show version" 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "FRR is running successfully!" -ForegroundColor Green
# Показ BGP статуса
Write-Host "BGP Summary:" -ForegroundColor Cyan
docker exec $ContainerName vtysh -c "show ip bgp summary" 2>$null
# Показ логов
Write-Host "Recent logs:" -ForegroundColor Cyan
docker logs --tail=10 $ContainerName
Write-Host "`nBGP Server (FRR) is ready!" -ForegroundColor Green
Write-Host "To view logs: docker logs -f $ContainerName" -ForegroundColor Cyan
Write-Host "To check BGP status: docker exec $ContainerName vtysh -c 'show ip bgp summary'" -ForegroundColor Cyan
Write-Host "To access FRR CLI: docker exec -it $ContainerName vtysh" -ForegroundColor Cyan
} else {
Write-Host "FRR failed to start properly. Check logs:" -ForegroundColor Red
docker logs $ContainerName
}
} else {
Write-Host "Failed to start container. Check the error above." -ForegroundColor Red
exit 1
}
-189
View File
@@ -1,189 +0,0 @@
#!/bin/bash
# Скрипт запуска BGP сервера на FRR
set -e
echo "Starting BGP Server (FRR)..."
# Создание директорий если не существуют
mkdir -p /app/logs
mkdir -p /app/run
mkdir -p /app/data
mkdir -p /var/run/frr
mkdir -p /etc/frr
# Установка правильных прав доступа
chmod 755 /app/logs
chmod 755 /app/run
chmod 755 /app/data
chmod 755 /var/run/frr
chmod 755 /etc/frr
# Проверка наличия файлов с префиксами
if [ ! -f "/app/data/prefixes.txt" ]; then
echo "Warning: /app/data/prefixes.txt not found. Creating empty file."
echo "# Default prefixes file" > /app/data/prefixes.txt
echo "192.168.1.0/24" >> /app/data/prefixes.txt
fi
# Создание лог-файлов с правильными правами
echo "Creating log files with proper permissions..."
touch /app/logs/prefixes.log
touch /app/logs/frr.log
chmod 666 /app/logs/prefixes.log
chmod 666 /app/logs/frr.log
echo "Prefixes file content:"
cat /app/data/prefixes.txt
echo "---"
# Проверка прав доступа к файлам
echo "Checking file permissions:"
ls -la /app/data/
ls -la /app/scripts/
echo "---"
# Генерация конфигурации из переменных окружения
echo "Generating FRR configuration from environment variables..."
echo "Environment variables:"
env | grep BGP_ || echo "No BGP_ variables found"
echo "---"
python3 /app/scripts/generate_config.py
# Проверка конфигурации
echo "Validating FRR configuration..."
echo "Configuration file content:"
cat /etc/frr/frr.conf
echo "---"
# Проверка синтаксиса конфигурации FRR
if vtysh -c "show running-config" > /dev/null 2>&1; then
echo "FRR configuration validation passed"
else
echo "FRR configuration validation failed"
echo "Full config content:"
cat /etc/frr/frr.conf
exit 1
fi
# Тестовый запуск скрипта загрузки префиксов
echo "Testing prefix loader script..."
python3 /app/scripts/load_prefixes.py --test 2>&1 || echo "Prefix loader test failed (this is normal)"
echo "---"
# Проверка сетевого подключения
echo "Checking network connectivity..."
NEIGHBOR_IP=${BGP_NEIGHBOR_IP:-192.168.1.1}
if ping -c 1 $NEIGHBOR_IP > /dev/null 2>&1; then
echo "Network connectivity to $NEIGHBOR_IP: OK"
else
echo "Warning: Cannot reach $NEIGHBOR_IP. BGP session may not establish."
fi
# Запуск FRR демонов
echo "Starting FRR daemons..."
# Запуск zebra (обязательный демон для FRR)
echo "Starting zebra daemon..."
zebra -d -f /etc/frr/frr.conf -A 127.0.0.1 -z /var/run/frr/zebra.api
sleep 2
# Запуск bgpd
echo "Starting bgpd daemon..."
bgpd -d -f /etc/frr/frr.conf -A 127.0.0.1 -z /var/run/frr/zebra.api
sleep 2
# Проверка что демоны запустились
echo "Checking if FRR daemons are running..."
ps aux | grep -E "(zebra|bgpd)" | grep -v grep || echo "No FRR daemons found in ps"
# Сохранение PID файлов
echo "Saving PID files..."
pgrep zebra > /app/logs/zebra.pid 2>/dev/null || echo "zebra PID not found"
pgrep bgpd > /app/logs/bgpd.pid 2>/dev/null || echo "bgpd PID not found"
# Ожидание запуска
sleep 5
# Проверка статуса через vtysh
echo "Checking FRR status via vtysh..."
if vtysh -c "show version" > /dev/null 2>&1; then
echo "FRR started successfully"
echo "FRR version:"
vtysh -c "show version" 2>/dev/null || echo "Could not get version"
echo "BGP neighbors:"
vtysh -c "show ip bgp neighbors" 2>/dev/null || echo "Could not get BGP neighbors"
echo "BGP summary:"
vtysh -c "show ip bgp summary" 2>/dev/null || echo "Could not get BGP summary"
else
echo "Failed to start FRR. Checking logs:"
cat /app/logs/frr.log 2>/dev/null || echo "No FRR logs found"
exit 1
fi
# Запуск скрипта загрузки префиксов в фоновом режиме
echo "Starting prefix loader in background..."
python3 /app/scripts/load_prefixes.py > /app/logs/prefixes.log 2>&1 &
PREFIX_LOADER_PID=$!
echo $PREFIX_LOADER_PID > /app/logs/prefix_loader.pid
# Запуск монитора в фоновом режиме
echo "Starting monitor in background..."
python3 /app/scripts/monitor.py > /app/logs/monitor.log 2>&1 &
MONITOR_PID=$!
echo $MONITOR_PID > /app/logs/monitor.pid
echo "All services started successfully!"
echo "Recent logs:"
tail -10 /app/logs/prefixes.log 2>/dev/null || echo "No prefix logs yet"
echo "---"
# Функция для graceful shutdown
cleanup() {
echo "Received shutdown signal. Cleaning up..."
# Остановка скриптов
if [ -f "/app/logs/prefix_loader.pid" ]; then
kill $(cat /app/logs/prefix_loader.pid) 2>/dev/null || true
fi
if [ -f "/app/logs/monitor.pid" ]; then
kill $(cat /app/logs/monitor.pid) 2>/dev/null || true
fi
# Отзыв всех префиксов
echo "Withdrawing all prefixes..."
python3 /app/scripts/load_prefixes.py --withdraw > /dev/null 2>&1 || true
# Остановка FRR демонов
echo "Stopping FRR daemons..."
killall bgpd 2>/dev/null || true
killall zebra 2>/dev/null || true
echo "Cleanup completed."
exit 0
}
# Установка обработчиков сигналов
trap cleanup SIGTERM SIGINT
# Ожидание завершения
echo "BGP Server is running. Press Ctrl+C to stop."
while true; do
sleep 10
# Проверка что демоны все еще работают
if ! pgrep zebra > /dev/null; then
echo "ERROR: zebra daemon stopped unexpectedly"
exit 1
fi
if ! pgrep bgpd > /dev/null; then
echo "ERROR: bgpd daemon stopped unexpectedly"
exit 1
fi
done
-66
View File
@@ -1,66 +0,0 @@
# Скрипт остановки BGP Server (FRR)
param(
[string]$ContainerName = "bgp-server",
[switch]$Force
)
Write-Host "=== BGP Server (FRR) Stop Script ===" -ForegroundColor Green
# Проверка существования контейнера
$containerExists = docker ps -a --filter "name=$ContainerName" --format "table {{.Names}}" | Select-String $ContainerName
if (-not $containerExists) {
Write-Host "Container $ContainerName not found." -ForegroundColor Yellow
exit 0
}
# Проверка статуса контейнера
$containerRunning = docker ps --filter "name=$ContainerName" --format "table {{.Names}}" | Select-String $ContainerName
if ($containerRunning) {
Write-Host "Container $ContainerName is running. Stopping..." -ForegroundColor Yellow
if (-not $Force) {
$response = Read-Host "Do you want to stop the container? (y/N)"
if ($response -ne "y" -and $response -ne "Y") {
Write-Host "Operation cancelled." -ForegroundColor Red
exit 0
}
}
# Graceful shutdown - отзыв префиксов
Write-Host "Withdrawing prefixes..." -ForegroundColor Yellow
docker exec $ContainerName python3 /app/scripts/load_prefixes.py --withdraw 2>$null
# Остановка контейнера
Write-Host "Stopping container..." -ForegroundColor Yellow
docker stop $ContainerName
if ($LASTEXITCODE -eq 0) {
Write-Host "Container stopped successfully!" -ForegroundColor Green
} else {
Write-Host "Failed to stop container." -ForegroundColor Red
exit 1
}
} else {
Write-Host "Container $ContainerName is not running." -ForegroundColor Yellow
}
# Удаление контейнера если требуется
if ($Force) {
Write-Host "Removing container..." -ForegroundColor Yellow
docker rm $ContainerName 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "Container removed successfully!" -ForegroundColor Green
} else {
Write-Host "Container was already removed or removal failed." -ForegroundColor Yellow
}
} else {
Write-Host "Container stopped but not removed." -ForegroundColor Cyan
Write-Host "To remove container, run: docker rm $ContainerName" -ForegroundColor Cyan
Write-Host "Or use -Force parameter to stop and remove in one command." -ForegroundColor Cyan
}
Write-Host "BGP Server (FRR) stopped successfully!" -ForegroundColor Green
-92
View File
@@ -1,92 +0,0 @@
# Скрипт для безопасного обновления BGP Server контейнера
param(
[string]$ContainerName = "bgp-server",
[string]$ImageName = "git.shts.su/infra/bgp-server:latest",
[string]$DataPath = "./data",
[string]$LogsPath = "./logs",
[switch]$Force
)
Write-Host "=== BGP Server Container Update Script ===" -ForegroundColor Green
# Проверка существования контейнера
$containerExists = docker ps -a --filter "name=$ContainerName" --format "table {{.Names}}" | Select-String $ContainerName
if ($containerExists) {
Write-Host "Found existing container: $ContainerName" -ForegroundColor Yellow
if (-not $Force) {
$response = Read-Host "Do you want to update the container? (y/N)"
if ($response -ne "y" -and $response -ne "Y") {
Write-Host "Update cancelled." -ForegroundColor Red
exit 0
}
}
# Остановка и удаление старого контейнера
Write-Host "Stopping container..." -ForegroundColor Yellow
docker stop $ContainerName
Write-Host "Removing container..." -ForegroundColor Yellow
docker rm $ContainerName
} else {
Write-Host "No existing container found. Creating new one..." -ForegroundColor Green
}
# Создание директорий если не существуют
if (-not (Test-Path $DataPath)) {
Write-Host "Creating data directory: $DataPath" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $DataPath -Force | Out-Null
}
if (-not (Test-Path $LogsPath)) {
Write-Host "Creating logs directory: $LogsPath" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $LogsPath -Force | Out-Null
}
# Загрузка нового образа
Write-Host "Pulling latest image..." -ForegroundColor Yellow
docker pull $ImageName
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to pull image. Exiting." -ForegroundColor Red
exit 1
}
# Запуск нового контейнера
Write-Host "Starting new container..." -ForegroundColor Yellow
$currentPath = Get-Location
$dataVolume = "${currentPath}\${DataPath}:/app/data:ro"
$logsVolume = "${currentPath}\${LogsPath}:/app/logs"
docker run -d `
--name $ContainerName `
--restart unless-stopped `
-p 179:179 `
-v $dataVolume `
-v $logsVolume `
$ImageName
if ($LASTEXITCODE -eq 0) {
Write-Host "Container started successfully!" -ForegroundColor Green
# Ожидание запуска
Write-Host "Waiting for container to start..." -ForegroundColor Yellow
Start-Sleep -Seconds 5
# Проверка статуса
$status = docker ps --filter "name=$ContainerName" --format "table {{.Status}}"
Write-Host "Container status: $status" -ForegroundColor Cyan
# Показ логов
Write-Host "Recent logs:" -ForegroundColor Cyan
docker logs --tail=10 $ContainerName
Write-Host "`nContainer update completed successfully!" -ForegroundColor Green
Write-Host "To view logs: docker logs -f $ContainerName" -ForegroundColor Cyan
Write-Host "To check status: docker ps" -ForegroundColor Cyan
} else {
Write-Host "Failed to start container. Check the error above." -ForegroundColor Red
exit 1
}
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
# Bash script to start BGP server on Linux
# BGP Server Startup Script
echo -e "\033[32mStarting BGP Server with FRRouting...\033[0m"
# Check if Docker is running
if ! docker version >/dev/null 2>&1; then
echo -e "\033[31mError: Docker is not running. Please start Docker first.\033[0m"
exit 1
fi
echo -e "\033[32m✓ Docker is running\033[0m"
# Check if docker-compose is available
if ! docker-compose --version >/dev/null 2>&1; then
echo -e "\033[31mError: Docker Compose is not available. Please install Docker Compose.\033[0m"
exit 1
fi
echo -e "\033[32m✓ Docker Compose is available\033[0m"
# Stop any existing containers
echo -e "\033[33mStopping any existing BGP containers...\033[0m"
docker-compose down
# Start the BGP server
echo -e "\033[33mStarting BGP server...\033[0m"
docker-compose up -d
# Wait for container to start
sleep 5
# Check container status
echo -e "\033[36mContainer status:\033[0m"
docker ps --filter "name=bgp-server" --format "table {{.Names}}\t{{.Status}}"
# Show logs
echo -e "\n\033[36mBGP Server logs:\033[0m"
docker-compose logs bgp-server
echo -e "\n\033[32mBGP Server is running!\033[0m"
echo -e "\033[37mBGP port: 179\033[0m"
echo -e "\033[37mvtysh port: 2601\033[0m"
echo -e "\n\033[33mTo connect to vtysh: docker exec -it bgp-server vtysh\033[0m"
echo -e "\033[33mTo view logs: docker-compose logs -f bgp-server\033[0m"
echo -e "\033[33mTo stop server: docker-compose down\033[0m"
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash
# Bash script to stop BGP server on Linux
# BGP Server Stop Script
echo -e "\033[33mStopping BGP Server...\033[0m"
# Stop the BGP server
echo -e "\033[33mStopping BGP containers...\033[0m"
docker-compose down
# Remove volumes (optional - uncomment if you want to clean up completely)
# echo -e "\033[33mRemoving volumes...\033[0m"
# docker-compose down -v
# Check if containers are stopped
running_containers=$(docker ps --filter "name=bgp-server" --format "{{.Names}}")
if [ -n "$running_containers" ]; then
echo -e "\033[31mWarning: Some BGP containers are still running:\033[0m"
echo -e "\033[31m$running_containers\033[0m"
else
echo -e "\033[32mBGP Server stopped successfully!\033[0m"
fi
# Show stopped containers
echo -e "\n\033[36mContainer status:\033[0m"
docker ps -a --filter "name=bgp-server" --format "table {{.Names}}\t{{.Status}}"
echo -e "\n\033[33mTo start the server again, run: ./start-bgp-server.sh\033[0m"
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
# Bash script to update BGP prefixes on Linux
# BGP Prefixes Update Script
PREFIXES_FILE=${1:-"prefixes.txt"}
echo -e "\033[36mUpdating BGP Prefixes...\033[0m"
# Check if container is running
container_status=$(docker ps --filter "name=bgp-server" --format "{{.Names}}")
if [ -z "$container_status" ]; then
echo -e "\033[31mError: BGP container is not running. Please start it first.\033[0m"
echo -e "\033[33mRun: ./start-bgp-server.sh\033[0m"
exit 1
fi
# Check if prefixes file exists
if [ ! -f "$PREFIXES_FILE" ]; then
echo -e "\033[31mError: Prefixes file '$PREFIXES_FILE' not found.\033[0m"
exit 1
fi
# Copy new prefixes file to container
echo -e "\033[33mCopying new prefixes file to container...\033[0m"
docker cp "$PREFIXES_FILE" bgp-server:/etc/frr/prefixes.txt
# Reload BGP configuration
echo -e "\033[33mReloading BGP configuration...\033[0m"
docker exec bgp-server vtysh -c "configure terminal" -c "router bgp 65000" -c "clear ip bgp *" -c "end"
# Wait a moment for BGP to stabilize
sleep 3
# Show updated BGP table
echo -e "\n\033[32mUpdated BGP table:\033[0m"
docker exec bgp-server vtysh -c "show ip bgp"
echo -e "\n\033[32mPrefixes updated successfully!\033[0m"
echo -e "\033[33mTo view current prefixes: docker exec -it bgp-server vtysh -c 'show ip bgp'\033[0m"