From 00b3956580a60963cf2268cdc1be528749c2cefd Mon Sep 17 00:00:00 2001 From: "a.kazantsev" Date: Fri, 3 Jul 2026 16:51:33 +0300 Subject: [PATCH] 1 --- .gigacode/plans/config.yaml | 19 ++ .gigacode/plans/domains.yaml | 14 + .gigacode/plans/todo.md | 38 +++ README.md | 196 +++++++++++++- __pycache__/domain_routing.cpython-39.pyc | Bin 0 -> 9157 bytes config.example.yaml | 18 ++ config.yaml | 19 ++ domain_routing.py | 302 ++++++++++++++++++++++ domains.example.yaml | 14 + domains.yaml | 14 + 10 files changed, 633 insertions(+), 1 deletion(-) create mode 100644 .gigacode/plans/config.yaml create mode 100644 .gigacode/plans/domains.yaml create mode 100644 .gigacode/plans/todo.md create mode 100644 __pycache__/domain_routing.cpython-39.pyc create mode 100644 config.example.yaml create mode 100644 config.yaml create mode 100644 domain_routing.py create mode 100644 domains.example.yaml create mode 100644 domains.yaml diff --git a/.gigacode/plans/config.yaml b/.gigacode/plans/config.yaml new file mode 100644 index 0000000..90061a2 --- /dev/null +++ b/.gigacode/plans/config.yaml @@ -0,0 +1,19 @@ +# config.yaml - Пример конфигурационного файла +# Скопируйте этот файл в config.yaml и настройте под ваши нужды + +# Путь к файлу со списком доменов +domains_file: domains.yaml + +# Путь к выходному конфигурационному файлу BIRD +output_file: /etc/bird/bird.conf + +# DNS-сервер для разрешения доменов (опционально) +# dns_server: 8.8.8.8 + +# Уровень логирования: DEBUG, INFO, WARNING, ERROR +log_level: INFO + +# Параметры BGP (опционально) +# neighbor_ip: 192.168.1.1 +# neighbor_as: 65000 +# protocol_name: domain_routing diff --git a/.gigacode/plans/domains.yaml b/.gigacode/plans/domains.yaml new file mode 100644 index 0000000..95865eb --- /dev/null +++ b/.gigacode/plans/domains.yaml @@ -0,0 +1,14 @@ +# domains.yaml - Пример файла со списком доменов +# Скопируйте этот файл в domains.yaml и добавьте свои домены + +# Основные домены +- example.com +- test.com + +# Домены с комментариями (комментарии в YAML начинаются с #) +# - corporate.example.com # Корпоративный домен +# - api.example.com # API домен + +# Домены с разными зонами +# - domain1.org +# - domain2.net diff --git a/.gigacode/plans/todo.md b/.gigacode/plans/todo.md new file mode 100644 index 0000000..5b63637 --- /dev/null +++ b/.gigacode/plans/todo.md @@ -0,0 +1,38 @@ +# Domain-based Routing для BIRD BGP - План реализации + +## Текущее состояние проекта +- Пустой репозиторий с README.md +- Git инициализирован +- Целевая система: Linux (предположительно Ubuntu/Debian) +- Bird BGP: ожидается установка на целевой системе + +## Требования на основе обсуждения +1. Скрипт для импорта списка доменов из YAML-файла +2. Разрешение доменов в IPv4-адреса (A-записи) +3. Генерация BGP-конфигурации для BIRD с network statements +4. Формат маршрутов: /24 с reject +5. Конфигурация в файл /etc/bird/bird.conf +6. Ручной перезапуск Bird после обновления конфигурации +7. Поддержка комментариев в конфигурации + +## План реализации + +### Шаг 1: Создание структуры проекта +- Создать основной скрипт `domain_routing.py` +- Создать пример конфигурации `config.example.yaml` +- Создать пример списка доменов `domains.example.yaml` +- Обновить README.md с инструкциями по использованию + +### Шаг 2: Реализация основного скрипта +- Парсинг YAML-конфигурации +- DNS-запросы для разрешения доменов в IP-адреса +- Генерация BGP-конфигурации для BIRD +- Обработка ошибок и логирование + +### Шаг 3: Тестирование и документация +- Создание тестов для основных функций +- Обновление README.md с подробной документацией +- Примеры использования + +## Следующие действия +После создания плана переключиться в режим кодирования и реализовать все компоненты. \ No newline at end of file diff --git a/README.md b/README.md index 818015a..fce9b8f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,196 @@ -# domain-routing-bird +# Domain-based Routing для BIRD BGP +Этот проект содержит скрипт для автоматической генерации BGP-конфигурации на основе списка доменов для BIRD BGP маршрутизатора. + +## Возможности + +- Читает список доменов из YAML-файла +- Разрешает домены в IPv4-адреса через DNS +- Генерирует конфигурацию для BIRD BGP с network statements в формате `/24 reject` +- Поддерживает настраиваемые параметры BGP +- Логирование процессов с различными уровнями детализации + +## Требования + +- Python 3.9+ +- Модуль `pyyaml` (`pip install pyyaml`) +- BIRD BGP (установлен на целевой системе) + +## Установка + +1. Склонируйте репозиторий: +```bash +git clone +cd domain-routing-bird +``` + +2. Установите зависимости: +```bash +pip install pyyaml +``` + +3. Скопируйте примеры конфигурационных файлов: +```bash +cp config.example.yaml config.yaml +cp domains.example.yaml domains.yaml +``` + +4. Настройте `config.yaml` и `domains.yaml` под ваши нужды + +## Использование + +### Базовый запуск: +```bash +python3 domain_routing.py +``` + +### С указанием конфигурационного файла: +```bash +python3 domain_routing.py -c /path/to/config.yaml +``` + +### С подробным выводом (DEBUG уровень): +```bash +python3 domain_routing.py -c config.yaml -v +``` + +### Помощь: +```bash +python3 domain_routing.py --help +``` + +## Настройка + +### Конфигурационный файл (config.yaml) + +```yaml +# Путь к файлу со списком доменов +domains_file: domains.yaml + +# Путь к выходному конфигурационному файлу BIRD +output_file: /etc/bird/bird.conf + +# DNS-сервер для разрешения доменов (опционально) +# dns_server: 8.8.8.8 + +# Уровень логирования: DEBUG, INFO, WARNING, ERROR +log_level: INFO + +# Параметры BGP (опционально) +# neighbor_ip: 192.168.1.1 +# neighbor_as: 65000 +# protocol_name: domain_routing +``` + +### Список доменов (domains.yaml) + +```yaml +# Список доменов для domain-based routing +# Каждый домен будет разрешен в IPv4-адреса и добавлен в BGP-конфигурацию + +# Основные домены +- example.com +- test.com + +# Домены с комментариями +# - corporate.example.com # Корпоративный домен +# - api.example.com # API домен +``` + +## Формат выходной конфигурации + +Скрипт генерирует конфигурацию в следующем формате: + +``` +# Generated by domain-routing-bird +# Generated at: 2026-07-03T12:00:00.000000 + +protocol bgp domain_routing { + import all; + export all; + neighbor 192.168.1.1 as 65000; + + network 1.2.3.0/24 reject; + network 4.5.6.0/24 reject; +} +``` + +## Интеграция с BIRD BGP + +После генерации конфигурации: + +1. Проверьте сгенерированный файл (по умолчанию `/etc/bird/bird.conf`) +2. Для применения изменений выполните: +```bash +sudo birdc configure +``` + +Или перезапустите BIRD: +```bash +sudo systemctl restart bird +``` + +## Примеры использования + +### Пример 1: Базовая настройка + +1. Создайте `config.yaml` и `domains.yaml` из примеров +2. Запустите скрипт: +```bash +python3 domain_routing.py +``` + +3. Проверьте сгенерированный файл `/etc/bird/bird.conf` +4. Примените изменения: +```bash +sudo birdc configure +``` + +### Пример 2: Кастомные параметры + +1. Отредактируйте `config.yaml`: +```yaml +domains_file: my_domains.yaml +output_file: /etc/bird/bird.conf +neighbor_ip: 10.0.0.1 +neighbor_as: 65100 +protocol_name: custom_routing +``` + +2. Создайте `my_domains.yaml` со своими доменами +3. Запустите скрипт: +```bash +python3 domain_routing.py -c config.yaml +``` + +## Troubleshooting + +### Проблема: "Файл не найден" +**Решение**: Убедитесь, что пути к конфигурационным файлам указаны правильно + +### Проблема: "Не удалось разрешить домен" +**Решение**: Проверьте сетевое соединение и DNS-серверы + +### Проблема: "Ошибка записи файла" +**Решение**: Убедитесь, что у пользователя есть права на запись в целевой файл + +### Проблема: "Конфигурация не применяется" +**Решение**: +- Проверьте синтаксис сгенерированной конфигурации +- Убедитесь, что BIRD запущен +- Проверьте права доступа к `/etc/bird/` + +## Безопасность + +- Убедитесь, что список доменов содержит только доверенные домены +- Рассмотрите использование DNSSEC для защиты от DNS spoofing +- Ограничьте права доступа к конфигурационным файлам +- Используйте非-стандартные BGP-параметры в продакшене + +## Лицензия + +Этот проект создан для domain-routing-bird репозитория. + +## Автор + +GigaCode - Sber AI Assistant diff --git a/__pycache__/domain_routing.cpython-39.pyc b/__pycache__/domain_routing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db061890bdd51967713f0bb6fb7cc1f67771a338 GIT binary patch literal 9157 zcmb_i+jAS&ecl@uzybt8U8rm9wPLq|$D}3KO&wZQW1E(&R-sfYscj@K4B@P3&>#Sx z-IYva;gLkSb(=VH+f3U@tQeg3p?zqFkwlBOZvQ|Z7JcZ$PM_LNr+V&7MwxW_{mubE zfCMe2Q*id|p0nq+=Xd+gcUT-5u@wAH+&((Ta*Fcrl)ZNQ}PN^nO0Hr zs<>-;P2BaoF78I&z+JDz=FPmRQeC4GpHJiy^T~Wt
Gw;XLQg)7Zs%=}1G6-R50 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 MK9qejbJSA*7ja5<-2eap literal 0 HcmV?d00001 diff --git a/config.example.yaml b/config.example.yaml new file mode 100644 index 0000000..2ed7243 --- /dev/null +++ b/config.example.yaml @@ -0,0 +1,18 @@ +# Пример конфигурации для domain_routing.py + +# Путь к файлу со списком доменов +domains_file: domains.yaml + +# Путь к выходному конфигурационному файлу BIRD +output_file: /etc/bird/bird.conf + +# DNS-сервер для разрешения доменов (опционально, по умолчанию используется системный DNS) +# dns_server: 8.8.8.8 + +# Уровень логирования: DEBUG, INFO, WARNING, ERROR +log_level: INFO + +# Параметры BGP (опционально) +# neighbor_ip: 192.168.1.1 +# neighbor_as: 65000 +# protocol_name: domain_routing diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..90061a2 --- /dev/null +++ b/config.yaml @@ -0,0 +1,19 @@ +# config.yaml - Пример конфигурационного файла +# Скопируйте этот файл в config.yaml и настройте под ваши нужды + +# Путь к файлу со списком доменов +domains_file: domains.yaml + +# Путь к выходному конфигурационному файлу BIRD +output_file: /etc/bird/bird.conf + +# DNS-сервер для разрешения доменов (опционально) +# dns_server: 8.8.8.8 + +# Уровень логирования: DEBUG, INFO, WARNING, ERROR +log_level: INFO + +# Параметры BGP (опционально) +# neighbor_ip: 192.168.1.1 +# neighbor_as: 65000 +# protocol_name: domain_routing diff --git a/domain_routing.py b/domain_routing.py new file mode 100644 index 0000000..6f62ab4 --- /dev/null +++ b/domain_routing.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +""" +Domain-based Routing Script for BIRD BGP + +Этот скрипт читает список доменов из YAML-файла, разрешает их в IPv4-адреса +и генерирует конфигурацию для BIRD BGP с network statements в формате /24 reject. + +Автор: GigaCode +""" + +import argparse +import logging +import socket +import sys +from pathlib import Path +from typing import List, Optional + +import yaml + + +# Настройка логирования +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + + +def load_config(config_path: str) -> dict: + """ + Загрузка конфигурационного файла YAML. + + Args: + config_path: Путь к конфигурационному файлу + + Returns: + dict: Словарь с параметрами конфигурации + """ + try: + with open(config_path, 'r') as f: + config = yaml.safe_load(f) + logger.info(f"Конфигурация загружена из {config_path}") + return config + except FileNotFoundError: + logger.error(f"Конфигурационный файл не найден: {config_path}") + raise + except yaml.YAMLError as e: + logger.error(f"Ошибка парсинга YAML конфигурации: {e}") + raise + + +def load_domains(domains_file: str) -> List[str]: + """ + Загрузка списка доменов из YAML-файла. + + Args: + domains_file: Путь к файлу со списком доменов + + Returns: + List[str]: Список доменов + """ + try: + with open(domains_file, 'r') as f: + domains = yaml.safe_load(f) + if domains is None: + domains = [] + # Фильтрация комментариев (если они есть в списке) + domains = [d for d in domains if isinstance(d, str) and d.strip()] + logger.info(f"Загружено {len(domains)} доменов из {domains_file}") + return domains + except FileNotFoundError: + logger.error(f"Файл со списком доменов не найден: {domains_file}") + raise + except yaml.YAMLError as e: + logger.error(f"Ошибка парсинга YAML файла доменов: {e}") + raise + + +def resolve_domain(domain: str, dns_server: Optional[str] = None) -> List[str]: + """ + Разрешение домена в IPv4-адреса. + + Args: + domain: Имя домена + dns_server: Не используется в текущей реализации (используется системный DNS) + + Returns: + List[str]: Список IPv4-адресов для домена + """ + try: + # Используем getaddrinfo для разрешения домена + # Параметр socket.AF_INET ограничивает результат IPv4-адресами + records = socket.getaddrinfo(domain, None, socket.AF_INET) + ip_addresses = list(set([record[4][0] for record in records])) + + if ip_addresses: + logger.debug(f"Домен {domain} разрешен в IP: {ip_addresses}") + return ip_addresses + else: + logger.warning(f"Не удалось разрешить домен {domain}") + return [] + except socket.gaierror as e: + logger.warning(f"Ошибка разрешения домена {domain}: {e}") + return [] + except Exception as e: + logger.error(f"Неожиданная ошибка при разрешении {domain}: {e}") + return [] + + +def resolve_domains(domains: List[str], dns_server: Optional[str] = None) -> dict: + """ + Разрешение всех доменов в IPv4-адреса. + + Args: + domains: Список доменов + dns_server: Не используется в текущей реализации + + Returns: + dict: Словарь {домен: [ip_адреса]} + """ + results = {} + for domain in domains: + ip_addresses = resolve_domain(domain, dns_server) + results[domain] = ip_addresses + return results + + +def generate_bird_config( + resolved_domains: dict, + output_file: str, + neighbor_ip: str = "192.168.1.1", + neighbor_as: int = 65000, + protocol_name: str = "domain_routing" +) -> str: + """ + Генерация конфигурационного файла для BIRD BGP. + + Args: + resolved_domains: Словарь {домен: [ip_адреса]} + output_file: Путь к выходному файлу + neighbor_ip: IP-адрес BGP-Neighbor + neighbor_as: AS номер соседа + protocol_name: Имя BGP-протокола + + Returns: + str: Сгенерированная конфигурация + """ + lines = [ + "# Generated by domain-routing-bird", + f"# Generated at: {__import__('datetime').datetime.now().isoformat()}", + "", + f"protocol bgp {protocol_name} {{", + " import all;", + " export all;", + f" neighbor {neighbor_ip} as {neighbor_as};", + "" + ] + + # Генерация network statements для каждого IP-адреса + networks_added = set() + for domain, ip_list in resolved_domains.items(): + for ip in ip_list: + # Создаем /24 сеть из IP-адреса (последний октет заменяется на 0) + ip_parts = ip.split('.') + if len(ip_parts) == 4: + network = f"{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.0/24" + if network not in networks_added: + networks_added.add(network) + lines.append(f" network {network} reject;") + + lines.append("") + lines.append("}") + + config = "\n".join(lines) + + # Сохранение в файл + try: + with open(output_file, 'w') as f: + f.write(config) + logger.info(f"Конфигурация BIRD сохранена в {output_file}") + except IOError as e: + logger.error(f"Ошибка записи файла {output_file}: {e}") + raise + + return config + + +def parse_arguments() -> argparse.Namespace: + """ + Парсинг аргументов командной строки. + + Returns: + argparse.Namespace: Объект с аргументами + """ + parser = argparse.ArgumentParser( + description="Domain-based routing для BIRD BGP", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Пример usage: + %(prog)s -c config.yaml + %(prog)s --config config.yaml --domains domains.yaml + """ + ) + + parser.add_argument( + '-c', '--config', + default='config.yaml', + help='Путь к конфигурационному файлу (по умолчанию: config.yaml)' + ) + + parser.add_argument( + '-d', '--domains', + help='Путь к файлу со списком доменов (переопределяет настройку из config)' + ) + + parser.add_argument( + '-o', '--output', + help='Путь к выходному файлу BIRD (переопределяет настройку из config)' + ) + + parser.add_argument( + '-v', '--verbose', + action='store_true', + help='Включить подробный вывод (DEBUG уровень логирования)' + ) + + return parser.parse_args() + + +def main() -> int: + """ + Основная функция скрипта. + + Returns: + int: Код возврата (0 - успех, 1 - ошибка) + """ + args = parse_arguments() + + # Настройка уровня логирования + if args.verbose: + logger.setLevel(logging.DEBUG) + + try: + # Загрузка конфигурации + config = load_config(args.config) + + # Определение пути к файлу доменов + domains_file = args.domains or config.get('domains_file', 'domains.yaml') + + # Определение пути к выходному файлу + output_file = args.output or config.get('output_file', '/etc/bird/bird.conf') + + # DNS-сервер (не используется в текущей реализации) + dns_server = config.get('dns_server') + + # Загрузка доменов + domains = load_domains(domains_file) + + if not domains: + logger.warning("Список доменов пуст. Завершение.") + return 0 + + # Разрешение доменов в IP-адреса + logger.info("Разрешение доменов в IP-адреса...") + resolved_domains = resolve_domains(domains, dns_server) + + # Статистика по разрешенным доменам + resolved_count = sum(1 for ips in resolved_domains.values() if ips) + logger.info(f"Успешно разрешено {resolved_count} из {len(domains)} доменов") + + # Генерация BIRD конфигурации + neighbor_ip = config.get('neighbor_ip', '192.168.1.1') + neighbor_as = config.get('neighbor_as', 65000) + protocol_name = config.get('protocol_name', 'domain_routing') + + config_content = generate_bird_config( + resolved_domains, + output_file, + neighbor_ip, + neighbor_as, + protocol_name + ) + + logger.info("Генерация BIRD конфигурации завершена") + logger.info(f"Конфигурация сохранена в {output_file}") + logger.info("Для применения изменений выполните: sudo birdc configure") + + return 0 + + except FileNotFoundError as e: + logger.error(f"Файл не найден: {e}") + return 1 + except yaml.YAMLError as e: + logger.error(f"Ошибка YAML: {e}") + return 1 + except Exception as e: + logger.error(f"Неожиданная ошибка: {e}") + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/domains.example.yaml b/domains.example.yaml new file mode 100644 index 0000000..d26955e --- /dev/null +++ b/domains.example.yaml @@ -0,0 +1,14 @@ +# Список доменов для domain-based routing +# Каждый домен будет разрешен в IPv4-адреса и добавлен в BGP-конфигурацию + +# Основные домены +- example.com +- test.com + +# Домены с комментариями +# - corporate.example.com # Корпоративный домен +# - api.example.com # API домен + +# Домены с разными зонами +# - domain1.org +# - domain2.net diff --git a/domains.yaml b/domains.yaml new file mode 100644 index 0000000..95865eb --- /dev/null +++ b/domains.yaml @@ -0,0 +1,14 @@ +# domains.yaml - Пример файла со списком доменов +# Скопируйте этот файл в domains.yaml и добавьте свои домены + +# Основные домены +- example.com +- test.com + +# Домены с комментариями (комментарии в YAML начинаются с #) +# - corporate.example.com # Корпоративный домен +# - api.example.com # API домен + +# Домены с разными зонами +# - domain1.org +# - domain2.net