# BGP (Border Gateway Protocol)

### 📋 **Índice**

1. Fundamentos do BGP
2. Arquitetura e Componentes
3. Tipos e Variações
4. Mecanismos de Funcionamento
5. Atributos BGP e Seleção de Rotas
6. Segurança e Vulnerabilidades
7. Pentesting e BGP
8. Configurações e Hardening
9. Ferramentas e Diagnóstico

***

### 🔍 **Fundamentos do BGP**

#### **O que é BGP?**

O **Border Gateway Protocol (BGP)** é o protocolo de roteamento que sustenta a infraestrutura da Internet. Classificado como um protocolo de **Vetor de Caminho** (*Path Vector*), o BGP é responsável por trocar informações de roteamento entre diferentes Sistemas Autônomos (AS), formando a coluna vertebral da conectividade global.

#### **Contexto Histórico**

```yaml
Evolução do BGP:
  1989: BGP-1 (RFC 1105) - Primeira versão
  1990: BGP-2 (RFC 1163) - Melhorias no protocolo
  1991: BGP-3 (RFC 1267) - Refinamentos
  1994: BGP-4 (RFC 1654) - Versão atual com CIDR
  1995: BGP-4 (RFC 1771) - Padrão estabilizado
  2006: BGP-4 (RFC 4271) - Especificação atual
  2020: BGPsec (RFC 8205) - Extensão de segurança

Motivação:
  ❌ EGP (Exterior Gateway Protocol) não escalava
  ❌ Necessidade de suporte a CIDR
  ❌ Políticas de roteamento entre organizações
  ✅ BGP permite roteamento baseado em políticas
```

#### **Conceitos Fundamentais**

| Conceito                   | Descrição                                           | Importância           |
| -------------------------- | --------------------------------------------------- | --------------------- |
| **AS (Autonomous System)** | Conjunto de redes sob controle administrativo único | Unidade básica do BGP |
| **ASN (AS Number)**        | Identificador único de 16 ou 32 bits                | Identidade global     |
| **Prefix IP**              | Bloco de endereços IP anunciados                    | Unidade de roteamento |
| **Peering**                | Relacionamento entre ASs                            | Troca de tráfego      |
| **Path Vector**            | Lista de ASs no caminho                             | Detecção de loops     |

#### **Sistemas Autônomos (AS)**

```yaml
Tipos de AS:
  
  Transit AS:
    - Fornece trânsito para outros ASs
    - Ex: Operadoras de telecom (Level3, NTT)
    - Cobra por tráfego
  
  Stub AS:
    - Conecta-se a apenas um AS
    - Não fornece trânsito
    - Ex: Empresas, universidades
  
  Multihomed AS:
    - Conecta-se a múltiplos ASs
    - Não fornece trânsito
    - Ex: Grandes empresas
  
  Internet Exchange Point (IXP):
    - Ponto de troca de tráfego
    - Múltiplos ASs conectados
    - Ex: PTT.br, AMS-IX
```

***

### 🏗️ **Arquitetura e Componentes**

#### **Topologia BGP**

```mermaid
graph TD
    subgraph "AS 64500 (ISP Core)"
        R1[R1 - BGP Router]
        R2[R2 - BGP Router]
    end
    
    subgraph "AS 64501 (Customer)"
        C1[Customer Router]
    end
    
    subgraph "AS 64502 (Peer)"
        P1[Peer Router]
    end
    
    subgraph "AS 64503 (Transit)"
        T1[Transit Router]
    end
    
    R1 ---|eBGP| C1
    R1 ---|eBGP| P1
    R2 ---|eBGP| T1
    R1 ---|iBGP| R2
```

#### **Tipos de Sessões BGP**

```yaml
eBGP (External BGP):
  - Entre diferentes ASs
  - Normalmente direto (adjacentes)
  - TTL = 1 (padrão)
  - Multihop permitido com configuração
  
iBGP (Internal BGP):
  - Dentro do mesmo AS
  - Pode não ser adjacente
  - Necessita full mesh ou route reflectors
  - Não modifica AS_PATH
```

#### **Estrutura de Pacotes BGP**

```python
#!/usr/bin/env python3
# bgp_protocol_structure.py

import struct
import socket

class BGPPacket:
    """Estrutura de pacotes BGP"""
    
    # Tipos de Mensagens BGP
    MSG_OPEN = 1
    MSG_UPDATE = 2
    MSG_NOTIFICATION = 3
    MSG_KEEPALIVE = 4
    
    def __init__(self):
        self.marker = b'\xff' * 16  # Marcador de início
        self.length = 0              # Comprimento total
        self.type = 0               # Tipo de mensagem
        self.data = b''             # Payload
    
    def build(self):
        """Construir pacote BGP"""
        self.length = 19 + len(self.data)  # 19 bytes de header
        header = self.marker + struct.pack('!HB', self.length, self.type)
        return header + self.data
    
    def parse(self, data):
        """Parsear pacote BGP"""
        if len(data) < 19:
            return None
        
        self.marker = data[:16]
        self.length = struct.unpack('!H', data[16:18])[0]
        self.type = data[18]
        self.data = data[19:self.length]
        
        return self

class BGPUpdate(BGPPacket):
    """Mensagem UPDATE BGP"""
    
    def __init__(self):
        super().__init__()
        self.type = self.MSG_UPDATE
        self.withdrawn_routes = []
        self.path_attributes = []
        self.nlri = []
    
    def build(self):
        """Construir mensagem UPDATE"""
        # Withdrawn Routes Length
        withdrawn_len = len(self.withdrawn_routes) * 2
        data = struct.pack('!H', withdrawn_len)
        
        # Withdrawn Routes
        for route in self.withdrawn_routes:
            data += struct.pack('!B', len(route)) + route
        
        # Path Attributes Length
        attr_len = self.calc_attributes_length()
        data += struct.pack('!H', attr_len)
        
        # Path Attributes
        for attr in self.path_attributes:
            data += self.build_attribute(attr)
        
        # NLRI
        for nlri in self.nlri:
            data += struct.pack('!B', len(nlri)) + nlri
        
        self.data = data
        return super().build()
    
    def calc_attributes_length(self):
        """Calcular comprimento dos atributos"""
        total = 0
        for attr in self.path_attributes:
            total += 2 + 1 + 1 + len(attr.get('value', b''))
        return total

# Exemplo de caminho AS
class ASPath:
    """Representação do caminho AS"""
    
    def __init__(self, as_list):
        self.as_list = as_list  # Lista de ASNs
    
    def prepend(self, asn):
        """Adicionar AS ao início (prepend)"""
        self.as_list.insert(0, asn)
    
    def length(self):
        """Número de AS no caminho"""
        return len(self.as_list)
    
    def contains(self, asn):
        """Verificar se AS está no caminho"""
        return asn in self.as_list
    
    def to_string(self):
        """Representação em string"""
        return " ".join(str(asn) for asn in self.as_list)
    
    def __str__(self):
        return self.to_string()
```

***

### 🔄 **Mecanismos de Funcionamento**

#### **Máquina de Estados BGP**

```mermaid
stateDiagram-v2
    [*] --> IDLE
    
    IDLE --> CONNECT: TCP Connection Init
    
    CONNECT --> OPEN_SENT: TCP Established
    CONNECT --> ACTIVE: Connection Failed
    
    ACTIVE --> CONNECT: Retry Timer
    ACTIVE --> OPEN_SENT: Connection Established
    
    OPEN_SENT --> OPEN_CONFIRM: OPEN Received
    OPEN_SENT --> IDLE: Error
    
    OPEN_CONFIRM --> ESTABLISHED: KEEPALIVE Received
    
    ESTABLISHED --> ESTABLISHED: UPDATE/KEEPALIVE
    ESTABLISHED --> IDLE: Error/Timeout
    
    note right of ESTABLISHED: Estado de operação<br/>Atualizações de rotas
```

#### **Fluxo de Anúncio BGP**

```mermaid
sequenceDiagram
    participant A as AS 65000 (Origem)
    participant B as AS 65001 (ISP)
    participant C as AS 65002 (Peer)
    participant D as AS 65003 (Destino)

    Note over A: Anuncia prefixo 203.0.113.0/24
    
    A->>B: UPDATE: NLRI 203.0.113.0/24<br/>AS_PATH: 65000
    Note over B: Recebe anúncio<br/>Valida caminho<br/>Aplica políticas
    
    B->>C: UPDATE: NLRI 203.0.113.0/24<br/>AS_PATH: 65000 65001
    Note over C: Avalia políticas<br/>Possivelmente anuncia
    
    C->>D: UPDATE: NLRI 203.0.113.0/24<br/>AS_PATH: 65000 65001 65002
    Note over D: Rota instalada<br/>Tráfego pode fluir
```

#### **Implementação de Roteador BGP**

```python
#!/usr/bin/env python3
# bgp_router_simulator.py

import socket
import threading
import time
import queue

class BGPRouter:
    """Simulador básico de roteador BGP"""
    
    def __init__(self, asn, router_id):
        self.asn = asn
        self.router_id = router_id
        self.peers = {}  # ASN -> Peer
        self.routing_table = {}  # Prefix -> (next_hop, as_path)
        self.local_prefixes = set()  # Prefixos originados
    
    class Peer:
        def __init__(self, asn, ip, local_asn):
            self.asn = asn
            self.ip = ip
            self.local_asn = local_asn
            self.state = "IDLE"
            self.socket = None
            self.routes = {}  # Prefixos recebidos
    
    def add_peer(self, asn, ip):
        """Adicionar vizinho BGP"""
        self.peers[asn] = self.Peer(asn, ip, self.asn)
        print(f"✅ Peer adicionado: AS{asn} em {ip}")
    
    def add_local_prefix(self, prefix, next_hop=None):
        """Adicionar prefixo local para anúncio"""
        if not next_hop:
            next_hop = self.router_id
        
        self.local_prefixes.add(prefix)
        self.routing_table[prefix] = {
            'next_hop': next_hop,
            'as_path': [self.asn],
            'origin': 'IGP',
            'local_pref': 100
        }
        print(f"📢 Prefixo local anunciado: {prefix}")
    
    def process_update(self, peer, update):
        """Processar mensagem UPDATE recebida"""
        nlri = update.get('nlri', [])
        path_attrs = update.get('path_attributes', {})
        
        # Extrair AS_PATH
        as_path = path_attrs.get('as_path', [])
        as_path.append(peer.asn)
        
        # Processar cada prefixo
        for prefix in nlri:
            self.routing_table[prefix] = {
                'next_hop': path_attrs.get('next_hop'),
                'as_path': as_path.copy(),
                'origin': path_attrs.get('origin'),
                'local_pref': path_attrs.get('local_pref', 100)
            }
            print(f"  📥 Rota instalada: {prefix} via AS{peer.asn}")
    
    def generate_updates(self):
        """Gerar mensagens UPDATE para peers"""
        updates = []
        
        for prefix in self.local_prefixes:
            # Criar UPDATE para prefixo local
            update = {
                'nlri': [prefix],
                'path_attributes': {
                    'as_path': [self.asn],
                    'origin': 'IGP',
                    'next_hop': self.router_id,
                    'local_pref': 100
                }
            }
            updates.append(update)
        
        # Adicionar rotas aprendidas (se anunciáveis)
        for prefix, route in self.routing_table.items():
            if prefix not in self.local_prefixes:
                # Verificar se não há loop
                if self.asn not in route['as_path']:
                    new_as_path = route['as_path'].copy()
                    new_as_path.insert(0, self.asn)
                    
                    update = {
                        'nlri': [prefix],
                        'path_attributes': {
                            'as_path': new_as_path,
                            'origin': route['origin'],
                            'next_hop': self.router_id,
                            'local_pref': route.get('local_pref', 100)
                        }
                    }
                    updates.append(update)
        
        return updates
    
    def send_updates_to_peer(self, peer):
        """Enviar atualizações para peer específico"""
        updates = self.generate_updates()
        
        for update in updates:
            print(f"📤 Enviando UPDATE para AS{peer.asn}: {update}")
            # Simular envio
            self.process_update(peer, update)
    
    def advertise_to_all(self):
        """Anunciar rotas para todos os peers"""
        for asn, peer in self.peers.items():
            self.send_updates_to_peer(peer)
    
    def show_routing_table(self):
        """Exibir tabela de roteamento"""
        print("\n" + "=" * 60)
        print(f"Tabela de Roteamento - AS{self.asn} (Router: {self.router_id})")
        print("=" * 60)
        print(f"{'Prefix':<20} {'Next Hop':<15} {'AS Path':<20}")
        print("-" * 60)
        
        for prefix, route in sorted(self.routing_table.items()):
            as_path = " ".join(str(asn) for asn in route['as_path'])
            print(f"{prefix:<20} {route['next_hop']:<15} {as_path:<20}")
        
        print("=" * 60)

# Simulação
if __name__ == "__main__":
    # Criar roteadores
    r1 = BGPRouter(asn=65000, router_id="10.0.0.1")
    r2 = BGPRouter(asn=65001, router_id="10.0.0.2")
    r3 = BGPRouter(asn=65002, router_id="10.0.0.3")
    
    # Estabelecer peers
    r1.add_peer(65001, "10.0.0.2")
    r2.add_peer(65000, "10.0.0.1")
    r2.add_peer(65002, "10.0.0.3")
    r3.add_peer(65001, "10.0.0.2")
    
    # Adicionar prefixos locais
    r1.add_local_prefix("203.0.113.0/24")
    r3.add_local_prefix("198.51.100.0/24")
    
    # Anunciar rotas
    print("\n🔁 Anunciando rotas...")
    r1.advertise_to_all()
    r2.advertise_to_all()
    r3.advertise_to_all()
    
    # Verificar tabelas
    r2.show_routing_table()
```

***

### 📊 **Atributos BGP e Seleção de Rotas**

#### **Atributos BGP**

| Atributo        | Código | Descrição                                 | Prioridade |
| --------------- | ------ | ----------------------------------------- | ---------- |
| **LOCAL\_PREF** | 5      | Preferência local (maior = melhor)        | 1ª         |
| **AS\_PATH**    | 2      | Lista de ASs no caminho (menor = melhor)  | 2ª         |
| **ORIGIN**      | 1      | Origem da rota (IGP > EGP > incomplete)   | 3ª         |
| **MED**         | 4      | Discriminação Multi-Exit (menor = melhor) | 4ª         |
| **NEXT\_HOP**   | 3      | Próximo salto                             | -          |
| **COMMUNITY**   | 8      | Grupo de rotas                            | -          |
| **WEIGHT**      | -      | Cisco proprietário (maior = melhor)       | 0ª         |

#### **Algoritmo de Seleção de Rotas**

```python
#!/usr/bin/env python3
# bgp_path_selection.py

class BGPPathSelection:
    """Algoritmo de seleção de rotas BGP"""
    
    def __init__(self):
        self.routes = []
    
    class Route:
        def __init__(self, prefix, next_hop, as_path, local_pref=100, med=0, origin='IGP'):
            self.prefix = prefix
            self.next_hop = next_hop
            self.as_path = as_path
            self.local_pref = local_pref
            self.med = med
            self.origin = origin
            self.weight = 0
    
    def select_best_route(self, routes):
        """Selecionar melhor rota entre múltiplas"""
        if not routes:
            return None
        
        # 0. Maior WEIGHT (Cisco)
        routes.sort(key=lambda r: r.weight, reverse=True)
        candidates = [r for r in routes if r.weight == routes[0].weight]
        
        # 1. Maior LOCAL_PREF
        candidates.sort(key=lambda r: r.local_pref, reverse=True)
        candidates = [r for r in candidates if r.local_pref == candidates[0].local_pref]
        
        # 2. Menor AS_PATH
        candidates.sort(key=lambda r: len(r.as_path))
        candidates = [r for r in candidates if len(r.as_path) == len(candidates[0].as_path)]
        
        # 3. Melhor ORIGIN (IGP > EGP > incomplete)
        origin_order = {'IGP': 0, 'EGP': 1, 'incomplete': 2}
        candidates.sort(key=lambda r: origin_order.get(r.origin, 3))
        candidates = [r for r in candidates if origin_order.get(r.origin, 3) == 
                     origin_order.get(candidates[0].origin, 3)]
        
        # 4. Menor MED
        candidates.sort(key=lambda r: r.med)
        candidates = [r for r in candidates if r.med == candidates[0].med]
        
        # 5. Preferir eBGP sobre iBGP
        # (implementação simplificada)
        
        # 6. Menor IGP cost para NEXT_HOP
        # (implementação simplificada)
        
        return candidates[0] if candidates else None
    
    def demo_selection(self):
        """Demonstrar seleção de rotas"""
        routes = [
            self.Route("203.0.113.0/24", "10.0.0.1", [65001, 65002], local_pref=100, med=100),
            self.Route("203.0.113.0/24", "10.0.0.2", [65001], local_pref=150, med=50),
            self.Route("203.0.113.0/24", "10.0.0.3", [65001, 65002, 65003], local_pref=100, med=50),
        ]
        
        best = self.select_best_route(routes)
        
        print("📊 Comparação de Rotas BGP:")
        for i, route in enumerate(routes):
            print(f"  Rota {i+1}: AS_PATH={route.as_path}, LOCAL_PREF={route.local_pref}, MED={route.med}")
        
        if best:
            print(f"\n✅ Melhor rota: AS_PATH={best.as_path}, LOCAL_PREF={best.local_pref}, MED={best.med}")
        
        return best

# Executar
selector = BGPPathSelection()
selector.demo_selection()
```

***

### 🔒 **Segurança e Vulnerabilidades**

#### **Principais Ameaças BGP**

```mermaid
graph TD
    A[Ameaças BGP] --> B[BGP Hijacking]
    A --> C[BGP Route Leak]
    A --> D[BGP Session Hijacking]
    A --> E[Prefix De-aggregation]
    A --> F[BGP DoS]
    
    B --> B1[Prefix Hijacking]
    B --> B2[Subprefix Hijacking]
    
    C --> C1[Transit Leak]
    C --> C2[Path Leak]
    
    D --> D1[TCP Session Reset]
    D --> D2[MD5 Weakness]
    
    E --> E1[Route Table Bloat]
    E --> E2[Traffic Blackholing]
    
    F --> F1[BGP Flap]
    F --> F2[CPU Exhaustion]
```

#### **Ataque 1: BGP Hijacking**

```python
#!/usr/bin/env python3
# bgp_hijacking_demo.py - Demonstração educacional

import random
import time

class BGPHijackingDemo:
    """
    Demonstração de BGP Hijacking
    APENAS para fins educacionais
    """
    
    def __init__(self, attacker_asn, target_prefix):
        self.attacker_asn = attacker_asn
        self.target_prefix = target_prefix
        self.legitimate_asn = None
    
    def craft_more_specific_prefix(self):
        """Criar prefixo mais específico para hijacking"""
        if "/" in self.target_prefix:
            prefix, mask = self.target_prefix.split('/')
            more_specific = f"{prefix}/{int(mask) + 1}"
            return more_specific
        return self.target_prefix
    
    def craft_hijack_update(self):
        """Construir anúncio BGP malicioso"""
        hijack = {
            'nlri': [self.craft_more_specific_prefix()],
            'as_path': [self.attacker_asn],
            'next_hop': f"192.0.2.{random.randint(1, 254)}",
            'origin': 'IGP',
            'local_pref': 150  # Prioridade alta
        }
        
        print(f"💉 Anúncio malicioso criado:")
        print(f"   Prefixo: {hijack['nlri'][0]}")
        print(f"   AS_PATH: {hijack['as_path']}")
        print(f"   Next Hop: {hijack['next_hop']}")
        
        return hijack
    
    def simulate_hijacking(self):
        """Simular sequência de hijacking"""
        print("🚨 SIMULAÇÃO DE BGP HIJACKING")
        print("=" * 50)
        
        print("\n1. Anúncio legítimo:")
        print(f"   Prefixo: {self.target_prefix}")
        print(f"   ASN Legítimo: {self.legitimate_asn or 'AS65000'}")
        
        print("\n2. Ataque: Anúncio mais específico")
        malicious = self.craft_hijack_update()
        
        print("\n3. Consequências:")
        print(f"   - Tráfego para {self.target_prefix} é redirecionado")
        print(f"   - Possível interceptação de dados")
        print(f"   - Negação de serviço (blackhole)")
        
        return malicious

# Exemplo
demo = BGPHijackingDemo(attacker_asn=65005, target_prefix="203.0.113.0/24")
demo.simulate_hijacking()
```

#### **Ataque 2: Route Leak**

```python
def simulate_route_leak():
    """Vazamento de rota BGP - anúncio acidental ou malicioso"""
    
    print("📤 SIMULAÇÃO DE ROUTE LEAK")
    print("=" * 50)
    
    as_path = {
        'legitimate': [65001, 65002, 65003],
        'leaked': [65001, 65002, 65004, 65003]
    }
    
    print(f"Rota legítima: {' -> '.join(str(a) for a in as_path['legitimate'])}")
    print(f"Rota vazada:   {' -> '.join(str(a) for a in as_path['leaked'])}")
    
    print("\nImpacto:")
    print("  - Tráfego roteado através de AS não autorizado")
    print("  - Possível degradação de performance")
    print("  - Risco de espionagem industrial")
    
    extra_hops = len(as_path['leaked']) - len(as_path['legitimate'])
    print(f"\nImpacto técnico: +{extra_hops} AS hops adicionais")

simulate_route_leak()
```

#### **Medidas de Proteção**

```yaml
Proteções BGP Modernas:
  
  RPKI (Resource Public Key Infrastructure):
    - Validação de origem de prefixos
    - Certificados digitais para IPs
    - ROA (Route Origin Authorization)
    - ROV (Route Origin Validation)
  
  BGPsec (BGP Security):
    - Assinatura digital de caminhos
    - Protege contra modificação de rotas
    - RFC 8205 (2016)
  
  Prefix Filtering:
    - IRR (Internet Routing Registry)
    - Filtros de prefixos aceitos
    - Controle de AS_PATH
  
  Max Prefix Limit:
    - Limite de prefixos por peer
    - Protege contra flooding
  
  TTL Security:
    - GTSM (Generalized TTL Security Mechanism)
    - Limita escopo de sessões eBGP
```

***

### 🎯 **Pentesting e BGP**

#### **Metodologia de Teste**

**Fase 1: Descoberta de ASNs e Prefixos**

```bash
# Consultar WHOIS
whois -h whois.radb.net 203.0.113.0
whois AS65000

# Usar bgp.tools API
curl https://bgp.tools/api/v1/prefix/203.0.113.0/24

# Usar Route Views
telnet route-views.routeviews.org
show ip bgp 203.0.113.0/24
```

**Fase 2: Coleta de Dados BGP**

```python
#!/usr/bin/env python3
# bgp_recon.py

import socket
import struct
import json

class BGPRecon:
    """Ferramenta de reconhecimento BGP"""
    
    def __init__(self):
        self.data = {}
    
    def query_route_views(self, prefix):
        """Consultar Route Views Project"""
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('route-views.routeviews.org', 43))
            
            sock.send(f"show ip bgp {prefix}\n".encode())
            
            response = b''
            while True:
                data = sock.recv(4096)
                if not data:
                    break
                response += data
            
            sock.close()
            return response.decode()
        except Exception as e:
            return str(e)
    
    def analyze_as_path(self, as_path):
        """Analisar caminho AS"""
        asns = as_path.split()
        
        analysis = {
            'as_count': len(asns),
            'as_list': asns,
            'is_transit': len(asns) > 1,
            'origin_as': asns[-1] if asns else None
        }
        
        return analysis
    
    def check_prefix_vulnerability(self, prefix, asn):
        """Verificar vulnerabilidades de prefixo"""
        vulnerabilities = []
        
        subprefixes = [f"{prefix.split('/')[0]}/{int(prefix.split('/')[1]) + i}" 
                       for i in range(1, 5)]
        
        print(f"🔍 Analisando vulnerabilidades para {prefix}")
        print(f"   ASN Origem: {asn}")
        print(f"   Subprefixos potenciais: {subprefixes}")
        
        vulnerabilities.append({
            'type': 'subprefix_hijack',
            'risk': 'HIGH',
            'description': 'Possível hijacking via prefixo mais específico'
        })
        
        return vulnerabilities

# Uso
recon = BGPRecon()
result = recon.query_route_views('203.0.113.0/24')
print(result[:500])
```

**Fase 3: Teste de RPKI Validação**

```python
def check_rpki_validation(asn):
    """Verificar se um ASN implementa RPKI"""
    print(f"🔍 Verificando RPKI para AS{asn}")
    
    print("   Resultados RPKI:")
    print("   - ROA encontrados: 3")
    print("   - Prefixos válidos: 85%")
    print("   - Prefixos inválidos: 2 (alertar)")
    
    return {'rpki_enabled': True, 'valid_prefixes': 85}
```

#### **Ferramentas de Pentest BGP**

```bash
# BGP Toolkit (Radb)
whois -h whois.radb.net "!gAS65000"

# BGP Route Viewer
telnet route-views.routeviews.org

# GoBGP - Implementação BGP em Go
gobgp global rib
gobgp neighbor

# BGPStream - Análise de eventos BGP
bgpreader -t "prefix 203.0.113.0/24"

# MassBGP - Scanner de prefixos
massbgp -a 65000 -p 203.0.113.0/24

# Exabgp - Ferramenta de testes
exabgp --test

# Nmap BGP scripts
nmap -p 179 --script bgp-* 192.168.1.1
```

***

### 🛠️ **Configurações e Hardening**

#### **Configuração BGP Segura (Cisco)**

```bash
! Configuração básica segura
router bgp 65000
 bgp router-id 10.0.0.1
 bgp log-neighbor-changes
 bgp graceful-restart

! Segurança da sessão
 neighbor 192.168.1.2 remote-as 65001
 neighbor 192.168.1.2 password 0 "SECURE_PASSWORD"
 neighbor 192.168.1.2 ttl-security hops 1
 neighbor 192.168.1.2 maximum-prefix 1000 restart 30

! Filtros de prefixo
 neighbor 192.168.1.2 prefix-list CUSTOMER-IN in
 neighbor 192.168.1.2 prefix-list CUSTOMER-OUT out

! Filtros de AS_PATH
 neighbor 192.168.1.2 filter-list 10 in

! RPKI validation
 bgp rpki server tcp 10.0.0.2 port 323 refresh 600

! Prefix filtering
ip prefix-list CUSTOMER-IN seq 5 permit 203.0.113.0/24 le 28
ip prefix-list CUSTOMER-IN seq 10 deny 0.0.0.0/0 le 32

! AS_PATH filter
ip as-path access-list 10 permit ^65001$
ip as-path access-list 10 deny .*
```

#### **Configuração FRRouting (FRR)**

```bash
# /etc/frr/bgpd.conf
router bgp 65000
 bgp router-id 10.0.0.1
 bgp ebgp-requires-policy
 bgp default ipv4-unicast

 ! RPKI
 rpki
  rpki server 10.0.0.2 port 323

 ! Neighbor
 neighbor 192.168.1.2 remote-as 65001
 neighbor 192.168.1.2 password SECURE_PASSWORD
 neighbor 192.168.1.2 timers 3 9
 neighbor 192.168.1.2 maximum-prefix 1000

 ! Prefix lists
 address-family ipv4 unicast
  neighbor 192.168.1.2 prefix-list CUSTOMER-IN in
  neighbor 192.168.1.2 prefix-list CUSTOMER-OUT out
  neighbor 192.168.1.2 route-map CUSTOMER-IN in
 exit-address-family

! Route maps
route-map CUSTOMER-IN permit 10
 set local-preference 100

! Prefix lists
ip prefix-list CUSTOMER-IN permit 203.0.113.0/24 le 28
```

#### **Hardening BGP**

```yaml
Checklist de Segurança BGP:
  
  Autenticação:
    ✓ MD5/TCP-AO para sessões
    ✓ Chaves rotacionadas periodicamente
  
  Filtragem:
    ✓ Prefix filter (RPKI/IRR)
    ✓ AS_PATH filter
    ✓ Max prefix limit
  
  Proteções:
    ✓ GTSM (TTL security)
    ✓ BGP graceful restart
    ✓ Route dampening
  
  Monitoramento:
    ✓ Logging de mudanças
    ✓ Alertas de anomalias
    ✓ Monitor de prefixos críticos
```

***

### 🔍 **Ferramentas e Diagnóstico**

#### **Comandos Essenciais**

```bash
# Cisco IOS
show ip bgp summary
show ip bgp neighbors
show ip bgp 203.0.113.0/24
show ip bgp regexp ^65000
show ip bgp community

# FRRouting
vtysh -c "show bgp summary"
vtysh -c "show bgp neighbors"
vtysh -c "show bgp ipv4 unicast 203.0.113.0/24"

# Linux (BGP routes)
ip route show table bgp

# Consultas externas
whois -h whois.radb.net 203.0.113.0
whois -h whois.ripe.net AS65000
```

#### **Script de Diagnóstico BGP**

```python
#!/usr/bin/env python3
# bgp_diagnostics.py

import subprocess
import json
import sys

class BGPDiagnostics:
    """Diagnóstico de configuração BGP"""
    
    def __init__(self, router_ip=None):
        self.router_ip = router_ip
    
    def check_bgp_session(self, neighbor_asn):
        """Verificar status da sessão BGP"""
        print(f"🔍 Verificando sessão BGP com AS{neighbor_asn}")
        
        status = {
            'state': 'Established',
            'uptime': '2w3d',
            'prefixes_received': 1250,
            'prefixes_sent': 15,
            'errors': 0,
            'flaps': 0
        }
        
        print(f"   Estado: {status['state']}")
        print(f"   Uptime: {status['uptime']}")
        print(f"   Prefixos recebidos: {status['prefixes_received']}")
        print(f"   Erros: {status['errors']}")
        
        return status
    
    def validate_prefix(self, prefix, origin_as):
        """Validar prefixo via RPKI"""
        print(f"🔍 Validando {prefix} (AS{origin_as})")
        
        validation = {
            'valid': True,
            'state': 'valid',
            'source': 'RPKI',
            'matched_roa': f"{prefix} (AS{origin_as})"
        }
        
        status = "✅ Válido" if validation['valid'] else "❌ Inválido"
        print(f"   {status} - {validation['state']}")
        
        return validation
    
    def analyze_route(self, prefix):
        """Analisar rota específica"""
        print(f"🔍 Analisando rota para {prefix}")
        
        info = {
            'prefix': prefix,
            'best_path': '203.0.113.1',
            'as_path': [65000, 65001, 65002],
            'local_pref': 100,
            'med': 0,
            'community': '65000:100',
            'age': '1h30m'
        }
        
        print(f"   Next Hop: {info['best_path']}")
        print(f"   AS_PATH: {' -> '.join(str(asn) for asn in info['as_path'])}")
        print(f"   Comunidade: {info['community']}")
        
        return info
    
    def run_full_diagnostic(self):
        """Executar diagnóstico completo"""
        print("📊 DIAGNÓSTICO BGP")
        print("=" * 50)
        
        self.check_bgp_session(65001)
        print()
        self.validate_prefix("203.0.113.0/24", 65002)
        print()
        self.analyze_route("203.0.113.0/24")
        
        print("\n" + "=" * 50)
        print("Recomendações:")
        print("  ✓ Implementar RPKI")
        print("  ✓ Configurar max-prefix")
        print("  ✓ Atualizar filtros de prefixo")
        print("  ✓ Revisar políticas de anúncio")

# Uso
diag = BGPDiagnostics()
diag.run_full_diagnostic()
```

#### **Monitoramento de Anomalias BGP**

```python
# bgp_monitor.py - Monitor de eventos BGP
import time
import threading

class BGPMonitor:
    """Monitoramento de anomalias BGP"""
    
    def __init__(self):
        self.prefix_history = {}
        self.as_path_history = {}
    
    def detect_hijack(self, prefix, as_path):
        """Detectar possíveis hijacks"""
        if prefix not in self.prefix_history:
            self.prefix_history[prefix] = as_path
            return None
        
        previous = self.prefix_history[prefix]
        
        if previous[0] != as_path[0]:
            return {
                'type': 'POSSIBLE_HIJACK',
                'prefix': prefix,
                'previous_origin': previous[0],
                'new_origin': as_path[0],
                'severity': 'HIGH'
            }
        
        return None
    
    def detect_route_leak(self, prefix, as_path, max_as_count=3):
        """Detectar vazamento de rotas"""
        if len(as_path) > max_as_count * 2:
            return {
                'type': 'ROUTE_LEAK',
                'prefix': prefix,
                'as_path_length': len(as_path),
                'expected_length': max_as_count,
                'severity': 'MEDIUM'
            }
        return None
    
    def log_event(self, event):
        """Registrar evento de segurança"""
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        print(f"[{timestamp}] {event['type']}: {event['prefix']}")
        print(f"   Severidade: {event['severity']}")

# Simular monitoramento
monitor = BGPMonitor()
event = monitor.detect_hijack("203.0.113.0/24", [65005, 65001, 65002])
if event:
    monitor.log_event(event)
```

***

### 📊 **Conclusão e Boas Práticas**

#### **Resumo Técnico**

```yaml
BGP é o protocolo fundamental da Internet:
  ✅ Suporta roteamento entre 90.000+ ASNs
  ✅ Gerencia ~950.000 prefixos IPv4
  ✅ Base para políticas de tráfego
  ✅ Permite escalabilidade global

Desafios de segurança:
  ❌ Baseado em confiança implícita
  ❌ Vulnerável a hijacking
  ❌ Lentidão na detecção de anomalias
  ❌ Implementação inconsistente de segurança
```

#### **Boas Práticas**

1. **Operadores de Rede**
   * Implementar RPKI e BGPsec
   * Usar filtros de prefixo rigorosos
   * Configurar max-prefix limits
   * Monitorar mudanças em prefixos críticos
2. **Para Pentesters**
   * Verificar implementação RPKI
   * Testar vulnerabilidade a prefix hijacking
   * Analisar filtros de AS\_PATH
   * Validar sessões BGP (MD5/TCP-AO)
3. **Monitoramento**
   * Participar de comunidades de segurança BGP
   * Usar BGP Stream e outros feeds
   * Configurar alertas para prefixos próprios
   * Auditoria regular de políticas

#### **Futuro do BGP**

```yaml
Tendências:
  - BGPsec para assinatura de caminhos
  - RPKI como requisito mínimo
  - BGP em redes 5G e edge
  - Automação com YANG/NetConf
  
Desafios:
  - Migração gradual para BGPsec
  - Adoção RPKI em mercados emergentes
  - Aumento da tabela de roteamento
  - Convergência mais rápida
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/conceitos/redes/protocolos-de-roteamento/bgp-border-gateway-protocol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
