From a437b755406c34eaffdf0c3c01017f474e42c822 Mon Sep 17 00:00:00 2001 From: Denis Shatskiy Date: Fri, 11 Jul 2025 16:28:33 +0700 Subject: [PATCH] Enhance ExaBGP configuration and scripts by adding environment variable support for neighbor IP, local AS, and router ID. Update Dockerfile to include permissions for the new generate_config.py script. Improve start.sh to generate configuration dynamically and display relevant information during startup. --- DOCKER_RUN.md | 27 ++++++++--- Dockerfile | 1 + exabgp.conf | 55 ++-------------------- scripts/generate_config.py | 96 ++++++++++++++++++++++++++++++++++++++ scripts/load_prefixes.py | 16 +++++-- scripts/start.sh | 12 +++++ 6 files changed, 146 insertions(+), 61 deletions(-) create mode 100644 scripts/generate_config.py diff --git a/DOCKER_RUN.md b/DOCKER_RUN.md index 52a679a..6652603 100644 --- a/DOCKER_RUN.md +++ b/DOCKER_RUN.md @@ -30,7 +30,7 @@ Get-Content data/prefixes.txt ### 2. Запуск контейнера из registry ```powershell -# Запуск BGP сервера из registry +# Запуск BGP сервера из registry с переменными окружения docker run -d ` --name bgp-server ` --restart unless-stopped ` @@ -41,21 +41,23 @@ docker run -d ` -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 -# Примечание: Если используете старую версию образа, может потребоваться пересборка -# или запуск с дополнительными volume для named pipes: +# Пример с кастомными настройками docker run -d ` - --name bgp-server ` + --name bgp-server-custom ` --restart unless-stopped ` -p 179:179 ` -v ${PWD}/data:/app/data:ro ` -v ${PWD}/logs:/app/logs ` - -v /run/exabgp:/run/exabgp ` -e BGP_LOCAL_AS=65000 ` - -e BGP_ROUTER_ID=192.168.1.100 ` - -e BGP_NEIGHBOR_IP=192.168.1.1 ` + -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_MD5_PASSWORD="your-secure-password" ` git.shts.su/infra/bgp-server:latest ``` @@ -138,6 +140,17 @@ docker run -d ` | `BGP_NEIGHBOR_AS` | AS номер пира | 65001 | | `BGP_HOLD_TIME` | Hold time в секундах | 90 | | `BGP_KEEPALIVE` | Keepalive в секундах | 30 | +| `BGP_MD5_PASSWORD` | MD5 пароль для аутентификации | (не используется) | + +### Просмотр сгенерированной конфигурации + +```powershell +# Просмотр текущей конфигурации ExaBGP +docker exec bgp-server cat /app/exabgp.conf + +# Просмотр переменных окружения +docker exec bgp-server env | findstr BGP_ +``` ## Управление контейнером diff --git a/Dockerfile b/Dockerfile index 2cdde51..48b8c35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,6 +21,7 @@ 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 # Рабочая директория WORKDIR /app diff --git a/exabgp.conf b/exabgp.conf index b875324..5c90769 100644 --- a/exabgp.conf +++ b/exabgp.conf @@ -1,50 +1,5 @@ -# Основная конфигурация ExaBGP -process load-prefixes { - run /app/scripts/load_prefixes.py; - encoder json; -} - -# Глобальные настройки -group default { - # Настройки CLI - cli { - in /run/exabgp/exabgp.in; - out /run/exabgp/exabgp.out; - } - - # Настройки BGP - neighbor 192.168.1.1 { - router-id 192.168.1.100; - local-address 192.168.1.100; - local-as 65000; - peer-as 65001; - - # Только исходящие анонсы (не принимаем префиксы) - capability { - graceful-restart; - } - - # Настройки сессии (hold-time автоматически рассчитывает keepalive) - hold-time 90; - - # Логирование - api { - processes [load-prefixes]; - neighbor-changes; - receive { - parsed; - update; - } - send { - parsed; - update; - } - } - } -} - -# Глобальные настройки логирования -log { - destination /app/logs/exabgp.log; - level INFO; -} \ No newline at end of file +# Этот файл будет перезаписан динамически сгенерированной конфигурацией +# из переменных окружения при запуске контейнера. +# +# Для просмотра текущей конфигурации используйте: +# docker exec bgp-server cat /app/exabgp.conf \ No newline at end of file diff --git a/scripts/generate_config.py b/scripts/generate_config.py new file mode 100644 index 0000000..74e196e --- /dev/null +++ b/scripts/generate_config.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +""" +Скрипт для генерации конфигурации ExaBGP из переменных окружения +""" + +import os +import sys + +def get_env_var(name: str, default: str) -> str: + """Получение переменной окружения с значением по умолчанию""" + return os.environ.get(name, default) + +def generate_exabgp_config(): + """Генерация конфигурации ExaBGP""" + + # Получение переменных окружения + local_as = get_env_var('BGP_LOCAL_AS', '65000') + router_id = get_env_var('BGP_ROUTER_ID', '192.168.1.100') + neighbor_ip = get_env_var('BGP_NEIGHBOR_IP', '192.168.1.1') + 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') + md5_password = get_env_var('BGP_MD5_PASSWORD', '') + + # Генерация конфигурации + config = f"""# Автоматически сгенерированная конфигурация ExaBGP +process load-prefixes {{ + run /app/scripts/load_prefixes.py; + encoder json; +}} + +# Настройки CLI +cli {{ + in /run/exabgp/exabgp.in; + out /run/exabgp/exabgp.out; +}} + +# Настройки BGP +neighbor {neighbor_ip} {{ + router-id {router_id}; + local-address {router_id}; + local-as {local_as}; + peer-as {neighbor_as}; + + # Только исходящие анонсы (не принимаем префиксы) + capability {{ + graceful-restart; + }} + + # Настройки сессии + hold-time {hold_time}; +""" + + # Добавление MD5 пароля если указан + if md5_password: + config += f" md5-password \"{md5_password}\";\n" + + config += f""" + # Логирование + api {{ + processes [load-prefixes]; + neighbor-changes; + receive {{ + parsed; + update; + }} + send {{ + parsed; + update; + }} + }} +}} + +# Глобальные настройки логирования +log {{ + destination /app/logs/exabgp.log; + level INFO; +}} +""" + + return config + +def main(): + """Основная функция""" + if len(sys.argv) > 1 and sys.argv[1] == '--print': + # Вывод конфигурации в stdout + print(generate_exabgp_config()) + else: + # Запись конфигурации в файл + config = generate_exabgp_config() + with open('/app/exabgp.conf', 'w') as f: + f.write(config) + print("Configuration generated successfully") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/scripts/load_prefixes.py b/scripts/load_prefixes.py index 7585fa6..e60c817 100644 --- a/scripts/load_prefixes.py +++ b/scripts/load_prefixes.py @@ -78,18 +78,23 @@ def load_all_prefixes() -> Set[str]: def announce_prefixes(prefixes: Set[str]): """Анонсирование префиксов через ExaBGP API""" + # Получение настроек из переменных окружения + neighbor_ip = os.environ.get('BGP_NEIGHBOR_IP', '192.168.1.1') + local_as = int(os.environ.get('BGP_LOCAL_AS', '65000')) + router_id = os.environ.get('BGP_ROUTER_ID', '192.168.1.100') + for prefix in sorted(prefixes): # Формат команды для ExaBGP command = { "command": "announce route", "neighbor": { - "ip": "192.168.1.1", + "ip": neighbor_ip, "description": "RouterOS peer" }, "attribute": { "origin": "igp", - "as-path": [65000], - "next-hop": "192.168.1.100" + "as-path": [local_as], + "next-hop": router_id }, "nlri": prefix } @@ -100,11 +105,14 @@ def announce_prefixes(prefixes: Set[str]): def withdraw_prefixes(prefixes: Set[str]): """Отзыв префиксов через ExaBGP API""" + # Получение настроек из переменных окружения + neighbor_ip = os.environ.get('BGP_NEIGHBOR_IP', '192.168.1.1') + for prefix in sorted(prefixes): command = { "command": "withdraw route", "neighbor": { - "ip": "192.168.1.1", + "ip": neighbor_ip, "description": "RouterOS peer" }, "nlri": prefix diff --git a/scripts/start.sh b/scripts/start.sh index c94bb86..52bd87e 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -10,6 +10,7 @@ echo "Starting BGP Server..." mkdir -p /app/logs mkdir -p /app/run mkdir -p /run/exabgp +mkdir -p /app/data # Создание named pipes для CLI в стандартном месте if [ ! -p "/run/exabgp/exabgp.in" ] || [ ! -p "/run/exabgp/exabgp.out" ]; then @@ -32,8 +33,19 @@ if [ ! -f "/app/data/prefixes.txt" ]; then echo "192.168.1.0/24" >> /app/data/prefixes.txt fi +echo "Prefixes file content:" +cat /app/data/prefixes.txt +echo "---" + +# Генерация конфигурации из переменных окружения +echo "Generating ExaBGP configuration from environment variables..." +python3 /app/scripts/generate_config.py + # Проверка конфигурации echo "Validating ExaBGP configuration..." +echo "Configuration file content:" +cat /app/exabgp.conf +echo "---" exabgp --validate /app/exabgp.conf # Запуск ExaBGP в фоновом режиме