Antigamente, por volta de 1993, o roteamento (criar e deletar rotas) no Linux era um trabalho puramente manual e realizado com o comando "route".
O trabalho sério, realizados por gateways com protocolos automatizados era deixado para roteadores profissionais (3com, Cisco, Juniper, etc...) e o Linux se limitava a servidores e aplicações de host.
Um tímido processo chamado "routed" implementava um único protocolo de roteamento dinâmico para Linux, o RIP.
Um programador chamado Kunihiro Ishiguro desenvolveu então um software chamado Zebra (GNU Zebra), um framework para aprendizado e compartilhamento de informações de roteamento por meio de protocolos dinâmicos, cujas rotas são aplicadas na tabela de rotas do Kernel Linux.
O framework Zebra era tão elegante e estável que passou a ser referência de roteamento dinâmico em sistemas Unix, e sua fama fez parecer que ele era o único software desse tipo.
No desenho acima temos, como base de tudo, o hardware. Executando sobre o hardware e mantendo controle dos dispositivos PCI, memória, processador e demais periféricos o Kernel Linux. No Kernel temos todas as funções de rede para criação e processamento de pacotes IP, incluindo as interfaces lógicas de rede (eth0, eth1, loopback), e principalmente a tabela de rotas.
Dentro do Kernel Linux onde há um espaço de memória alocado para armazenar a tabela de rotas, esse espaço é o que denominamos FIB (Forward Information Base).
A cada pacote IP recebido ou criado num sistema Linux, o IP de destino do pacote é localizado na tabela de rotas, e através dele sabe-se qual o proximo salto do pacote.
Quando o administrador de sistema insere uma rota usando o comando "route" ou "ip route", tal rota é diretamente inserida na FIB por meio de uma API (RTNL).
Quando o administrador, ou algum script de gerencia de rede (ifup, NetworkManager, netplan, rc.inet1, etc...), adiciona um endereço IP em uma interface, o que de fato acontece é o envio de uma mensagem por meio de socket RTNL, o Kernel recebe a mensagem e efetiva o pedido, criando a rota da rede local (rota para rede diretamente conectada) e associando o endereço IP à interface.
Essa maneira simples de trabalhar, baseado em mensagens, permite que qualquer programa (rodando como root ou com NET_CAPABILITIES) a capacidade de inserir e remover rotas na FIB.
Ao criar um software que implemente um protocolo de roteamento, como é o caso do "routed", basta que tal software envie mensagens RTNL para obter uma cópia da tabela de rota quanto inserir nela uma nova rota aprendida por meio de um roteador vizinho. Não há mistério nisso, e o código é pequeno e simples.
No entanto, quando se deseja criar vários softwares, onde cada um aprende e ensina rotas usando um protocolo diferente, um problema sério surge: a concorrência no acesso a tabela de rotas do kernel. Este problema cria um fenômeno chamado "rota presa", que trata-se uma rota que foi inserida erroneamente, ou foi inserida por um software e apagada por outro, sem que esses software tenham uma comunicação entre si para evitar tais problemas ou sinalizar preferencia sobre uma rota.
A forma mais elegante de resolver este problema é criar uma nova camada de software, essa camada cria uma tabela de rotas chamada RIB (Route Information Base).
Um software, que aqui se chama ZEBRA, fica responsável por manter um banco de dados de informações aprendidas por diferentes protocolos, e associa a cada um deles uma prioridade.
Exemplo: uma informação (rota) aprendida pelo protocolo OSPF (metric 110) não vence uma rota aprendida através de eBGP (metric 20). Na RIB precisam constar ambas as informações, o Zebra aplicará ao kernel somente a rota vencedora (eBGP nesse caso). Se ocorrer um withdrawn no eBGP que remova a informação da RIB, o Zebra notificará o Kernel, removendo a rota aprendida via eBGP e inserindo a rota alternativa, aprendida via OSPF. Se ocorrer, por coincidência de ambas as rotas terem o mesmo IP de gateway, nenhuma notificação é enviada ao kernel, pois afinal, nada de fato mudou a nível de FIB, somente a nível de RIB, "seria trocar 6 por meia-dúzia".
É importante informar que, embora na RIB as rotas tenham diferentes métricas (eBGP=20, iBGP=220, OSPF=110), a melhor rota é inserida no kernel com uma métrica fixa (proto zebra metric 20).
Ao ser executado num modelo cliente-servidor, o zebra permite que qualquer protocolo de roteamento possa ser implementado sem que alterações drásticas precisem ser feitas em sua estrutura.
Bastaria escrever o software cliente e conecta-lo ao socket do zebra, e enviar as informações aprendidas à RIB.
Cada ZClient (software cliente zebra) fica responsável pela sua própria configuração, cabendo a ele ler o arquivo inicial, interpretá-lo e obedecê-lo.
Aqui mora um perigo: a ausência do arquivo de configuração, ou a incapacidade de lê-lo (permissões), ou corrupção na sintaxe pode fazer com que o ZClient não seja iniciado.
Exemplo: se você editar manualmente o arquivo ospfd.conf e escrever uma palavra desconhecida, o processo ospfd (ZClient de OSPFv2) não irá iniciar.
A melhor abordagem é criar todos os arquivos de configuração vazios e configurá-los via terminal zebra, o VTYSH.
Vou ensinar como operar o VTYSH mais tarde.
Kunihiro Ishiguro criou o projeto Zebra, que foi muito tempo depois copiado (fork) e mantido por outra equipe de desenvolvedores, denominado projeto Quagga.
O Quagga mantinha inicialmente uma boa evolução do código, criando novos recursos, principalmente recursos adicionais no BGP e suporte a IPv6 (ainda sim ficou muito bugado, tenha dó).
Nesse momento da história, softwares como Debian, Ubuntu, VyAtta, VyOS, EdgeOS, entre outros, implementaram o Quagga com grande sucesso comercial.
Devida a alta demanda por estabilidade, novos recursos, maior flexibilidade e, principalmente, pressão por parte de grandes empresas que contribuíram para projetos de software open-source (Cumulus Networks, VMWare, Dell, etc...) e que precisavam de desenvolvedores mais comprometidos a frente do projeto Zebra/Quagga, a Linux Foundation apoiou um novo fork do projeto, vindo a chamá-lo de FRR - Free Range Routing (tradução direta: Faixa Livre para Roteamento).
Usaremos como base o Debian 10.5
Não recomendo que você realize o tutorial em ambiente de produção, portanto, pratique em maquinas virtuais de laboratórios (EVE-NG, GNS3, VirtualBox, VMWare, etc...).
O FRR não pode ser executado em um Linux que já rode o Quagga.
Se você instalou o Quagga, remova-o antes de iniciar os estudo do FRR.
Comandos (1 por linha) para instalação dos pacotes:
apt-get -y update apt-get -y upgrade apt-get -y install frr
Observe a pasta /etc/frr/
ls -lah /etc/frr/
# total 20K
# drwxr-x--- 2 frr frr 4.0K Aug 11 03:01 .
# drwxr-xr-x 108 root root 4.0K Aug 11 03:01 ..
# -rw-r----- 1 frr frr 1.9K Jan 7 2020 daemons
# -rw-r----- 1 frr frr 120 Jan 7 2020 frr.conf
# -rw-r----- 1 frr frr 32 Jan 7 2020 vtysh.conf
Os arquivos frr.conf e vtysh.conf não precisam nem devem ser editados, inicialmente.
Se você por algum motivo estragá-los, basta deixá-los em branco que tudo ficará bem.
Por segurança vamos fazer uma copia dos arquivos originais:
mkdir -p /etc/frr/backup/ cp /etc/frr/daemons /etc/frr/backup/ cp /etc/frr/frr.conf /etc/frr/backup/ cp /etc/frr/vtysh.conf /etc/frr/backup/
# Ativar BGP: sed -i 's#bgpd=no#bgpd=yes#' /etc/frr/daemons # Ativar OSPFD (OSPFv2 - IPv4): sed -i 's#ospfd=no#ospfd=yes#' /etc/frr/daemons # Ativar OSPF6D (OSPFv3 - IPv6): sed -i 's#ospf6d=no#ospf6d=yes#' /etc/frr/daemons # Ativar RIPD (RIPv2 - IPv4): sed -i 's#ripd=no#ripd=yes#' /etc/frr/daemons # Ativar RIPNGD (RIPv3 - IPv6): sed -i 's#ripngd=no#ripngd=yes#' /etc/frr/daemons # Ativar ISISD (IS-IS - Protocolo igp Cisco): sed -i 's#isisd=no#isisd=yes#' /etc/frr/daemons # Ativar PIMD (PIM - Roteamento Multicast): sed -i 's#pimd=no#pimd=yes#' /etc/frr/daemons # Ativar LDPD (LDP - Labels MPLS para rotas igp): sed -i 's#ldpd=no#ldpd=yes#' /etc/frr/daemons # Ativar NHRPD (NHRP - roteamento entre tuneis): sed -i 's#nhrpd=no#nhrpd=yes#' /etc/frr/daemons # Ativar EIGRPD (EIGRP - protocolo igp Cisco): sed -i 's#eigrpd=no#eigrpd=yes#' /etc/frr/daemons # Ativar BABELD (BABEL - protocolo igp dual-stack): sed -i 's#babeld=no#babeld=yes#' /etc/frr/daemons # Ativar SHARPD (SHARP - protocolo exemplo zclient): sed -i 's#sharpd=no#sharpd=yes#' /etc/frr/daemons # Ativar PBRD (PBR - gestao de regras para Police Based Routing): sed -i 's#pbrd=no#pbrd=yes#' /etc/frr/daemons # Ativar BFDD (BFD - protocolo de adjacencia instantanea): sed -i 's#bfdd=no#bfdd=yes#' /etc/frr/daemons
Para desativar todos, execute:
sed -i 's#bgpd=yes#bgpd=no#' /etc/frr/daemons sed -i 's#ospfd=yes#ospfd=no#' /etc/frr/daemons sed -i 's#ospf6d=yes#ospf6d=no#' /etc/frr/daemons sed -i 's#ripd=yes#ripd=no#' /etc/frr/daemons sed -i 's#ripngd=yes#ripngd=no#' /etc/frr/daemons sed -i 's#isisd=yes#isisd=no#' /etc/frr/daemons sed -i 's#pimd=yes#pimd=no#' /etc/frr/daemons sed -i 's#ldpd=yes#ldpd=no#' /etc/frr/daemons sed -i 's#nhrpd=yes#nhrpd=no#' /etc/frr/daemons sed -i 's#eigrpd=yes#eigrpd=no#' /etc/frr/daemons sed -i 's#babeld=yes#babeld=no#' /etc/frr/daemons sed -i 's#sharpd=yes#sharpd=no#' /etc/frr/daemons sed -i 's#pbrd=yes#pbrd=no#' /etc/frr/daemons sed -i 's#bfdd=yes#bfdd=no#' /etc/frr/daemons
Neste artigo usaremos apenas os protocolos OSPFv2, OSPFv3, BABEL e BGP, portanto ative-os:
sed -i 's#bgpd=no#bgpd=yes#' /etc/frr/daemons sed -i 's#ospfd=no#ospfd=yes#' /etc/frr/daemons sed -i 's#ospf6d=no#ospf6d=yes#' /etc/frr/daemons sed -i 's#babeld=no#babeld=yes#' /etc/frr/daemons
É imperativo garantir a existência dos arquivos de configuração de cada processo e as permissões da pasta /etc/frr:
touch /etc/frr/frr.conf touch /etc/frr/vtysh.conf touch /etc/frr/staticd.conf touch /etc/frr/bgpd.conf touch /etc/frr/ospfd.conf touch /etc/frr/ospf6d.conf touch /etc/frr/ripd.conf touch /etc/frr/ripngd.conf touch /etc/frr/isisd.conf touch /etc/frr/pimd.conf touch /etc/frr/ldpd.conf touch /etc/frr/nhrpd.conf touch /etc/frr/eigrpd.conf touch /etc/frr/babeld.conf touch /etc/frr/sharpd.conf touch /etc/frr/pbrd.conf touch /etc/frr/bfdd.conf chown frr:frr /etc/frr/*.conf chmod 600 /etc/frr/*.conf
Antigamente, quando o servidor zebra sofria com algum problema computacional e travava, isso fatalmente tornava toda pilha de roteamento dinâmico inútil, visto que sem os commits da RIB a rede fica sem convergência. A única forma de restaurar o serviço era matar e reiniciar os processos MANUALMENTE.
Na pilha Zebra a ordem de execução dos processos é vital para seu funcionamento. O servidor zebra deve ser iniciado primeiro, abrir o socket e aguardar por mensagens dos aplicativos.
Os aplicativos de roteamento ao serem executados devem encontrar o socket pronto para leitura e escrita.
Um processo cliente travado é igualmente traumático para a rede do backbone, mas não é fatal para a pilha zebra, visto que basta que o aplicativo que falhou seja reiniciado.
Você não vai querer fazer isso manualmente, como era feito antigamente. O pacote FRR conta com uma herança do Quagga para resolver esse problema, um serviço de watchdog chamado WATCHFRR.
Ele é responsável por iniciar o servidor zebra, testar o socket, e então iniciar os aplicativos zclients (os que você configurou como yes no arquivo /etc/frr/daemons).
Dessa forma, se o servidor zebra travar todos os processos serão assassinados pelo WATCHFRR e iniciados na ordem correta. Se algum aplicativo individual travar ele é exterminado e iniciado, sem prejuízo dos demais processos saudáveis.
Agora que você já sabe que FRR é o conjunto da obra, vamos reinicia-lo manualmente para subir as aplicações que ativamos
# - Ativar servico systemctl enable frr.service # - Parar servico: service frr stop # - Iniciar servico: service frr start
Observe se os processos estão em execução:
ps ax | grep frr
39213 ? S<s 0:00 /usr/lib/frr/watchfrr -d zebra bgpd ospfd ospf6d babeld staticd
39238 ? S<sl 0:00 /usr/lib/frr/zebra -d -A 127.0.0.1 -s 90000000
39243 ? S<sl 0:00 /usr/lib/frr/bgpd -d -A 127.0.0.1
39252 ? S<s 0:00 /usr/lib/frr/ospfd -d -A 127.0.0.1
39259 ? S<s 0:00 /usr/lib/frr/ospf6d -d -A ::1
39266 ? S<s 0:00 /usr/lib/frr/babeld -d -A 127.0.0.1
39272 ? S<s 0:00 /usr/lib/frr/staticd -d -A 127.0.0.1
Analisando status:
service frr status
● frr.service - FRRouting
Loaded: loaded (/lib/systemd/system/frr.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-08-11 04:24:53 -03; 3min 17s ago
Docs: https://frrouting.readthedocs.io/en/latest/setup.html
Process: 39204 ExecStart=/usr/lib/frr/frrinit.sh start (code=exited, status=0/SUCCESS)
Tasks: 15 (limit: 2330)
Memory: 16.3M
CGroup: /system.slice/frr.service
├─39213 /usr/lib/frr/watchfrr -d zebra bgpd ospfd ospf6d babeld staticd
├─39238 /usr/lib/frr/zebra -d -A 127.0.0.1 -s 90000000
├─39243 /usr/lib/frr/bgpd -d -A 127.0.0.1
├─39252 /usr/lib/frr/ospfd -d -A 127.0.0.1
├─39259 /usr/lib/frr/ospf6d -d -A ::1
├─39266 /usr/lib/frr/babeld -d -A 127.0.0.1
└─39272 /usr/lib/frr/staticd -d -A 127.0.0.1
Aug 11 04:24:53 labserver watchfrr[39213]: zebra state -> up : connect succeeded
Aug 11 04:24:53 labserver watchfrr[39213]: bgpd state -> up : connect succeeded
Aug 11 04:24:53 labserver watchfrr[39213]: ospfd state -> up : connect succeeded
Aug 11 04:24:53 labserver watchfrr[39213]: ospf6d state -> up : connect succeeded
Aug 11 04:24:53 labserver watchfrr[39213]: babeld state -> up : connect succeeded
Aug 11 04:24:53 labserver watchfrr[39213]: staticd state -> up : connect succeeded
Aug 11 04:24:53 labserver watchfrr[39213]: all daemons up, doing startup-complete notify
Aug 11 04:24:53 labserver frrinit.sh[39204]: Started watchfrr.
Aug 11 04:24:53 labserver systemd[1]: Started FRRouting.
Aug 11 04:25:07 labserver watchfrr[39213]: configuration write completed with exit code 0
O Zebra, alem de ser um framework de protocolos de rede, ele também se propõe a ser um shell independente.
Esse shell é implementado pelo VTYSH, que segue o modelo Cisco de comandos (show, configure terminal, quit, end, write, etc...).
O comando "vtysh" é, internamente, um loop interpretador de palavras utilizando a biblioteca GNU Readline.
Ao contrário do shell Bash, onde cada palavra é um arquivo a ser procurado na variavel $PATH, o VTYSH é mais simplório.
O Zebra registra os comandos e respectivas funções em uma tabela interna. Quando um ZClient é iniciado ele informa ao Zebra seus próprios comandos.
Quando uma nova sessão do VTYSH é iniciada, a primeira palavra digitada é procurada na lista de comandos, se encontrada, a função associada é invocada.
Uma grande vantagem desse shell é possibilidade de criar um Linux básico com apenas o FRR, orientado a funções de rede, onde ao acessar via terminal, telnet ou ssh, o shell padrão do usuário aponta para o VTYSH.
Exemplo (entrando, exibindo a versão (show version), saindo (exit):
vtysh Hello, this is FRRouting (version 6.0.2). Copyright 1996-2005 Kunihiro Ishiguro, et al. labserver# labserver# show version FRRouting 6.0.2 (labserver). Copyright 1996-2005 Kunihiro Ishiguro, et al. configured with: ... labserver# exit
Uma outra forma de acessar o shell do zebra é via TELNET.
Por padrão o FRR não abre portas telnet, se você desejar experimentar o acesso a essas portas, será necessário atribuir a senha de acesso e a senha e enable (acesso privilegiado).
vtysh Hello, this is FRRouting (version 6.0.2). Copyright 1996-2005 Kunihiro Ishiguro, et al. labserver# configure terminal labserver(config)# password tulipa labserver(config)# enable password javali labserver(config)# service password-encryption labserver(config)# line vty labserver(config-line)# login labserver(config)# end labserver# write Note: this version of vtysh never writes vtysh.conf Building Configuration... Integrated configuration saved to /etc/frr/frr.conf [OK] labserver# exit
Para abrir as portas de TELNET, edite o arquivo /etc/frr/daemons e encontre as variáveis abaixo, e complete-as com o argumento -P
# Arquivo /etc/frr/daemons
zebra_options=" -A 127.0.0.1 -s 90000000 -P 2300"
bgpd_options=" -A 127.0.0.1"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
Reinicie o FRR:
service frr stop service frr start
Acessando Zebra via TELNET:
telnet localhost 2300 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Hello, this is FRRouting (version 6.0.2). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: digite: tulipa labserver> labserver> labserver> enable Password: digite: javali labserver# labserver# labserver# exit
Embora não seja seguro utilizar telnet, uma das aplicações para esse tipo de acesso é a confecção de servidores Looking Glass, bastando remover a senha comum para que todos os usuários tenham acesso livre a parte comum (somente leitura e consulta).
Exemplo:
vtysh Hello, this is FRRouting (version 6.0.2). Copyright 1996-2005 Kunihiro Ishiguro, et al. labserver# configure terminal labserver(config)# no password Please be aware that removing the password is a security risk and you should think twice about this command. labserver(config)# line vty labserver(config-line)# no login labserver(config)# end labserver# write Note: this version of vtysh never writes vtysh.conf Building Configuration... Integrated configuration saved to /etc/frr/frr.conf [OK] labserver# exit
Acredito que você ja tenha entendido como funciona o VTYSH, como entrar e sair dele.
De agora em diante vou exibir apenas os comandos digitados nas telas pretas, assim ficará mais fácil para você copiar do artigo e colar no terminal.
Antigamente a pilha zebra mantinha a configuração de cada aplicação em seu respectivo arquivo (zebra.conf, ospfd.conf, bgpd.conf, etc...)
Agora por padrão, todas as configurações ficam centralizadas em um único arquivo: /etc/frr/frr.conf, e o que diz respeito a cada aplicação fica em seu respectivo arquivo, difere que ao ser iniciado apenas o frr.conf é relevante. Esse comportamento padrão é determinado pela configuração "service integrated-vtysh-config".
Desativando o service integrated-vtysh-config:
config t no service integrated-vtysh-config end write # Note: this version of vtysh never writes vtysh.conf # Building Configuration... # Configuration saved to /etc/frr/zebra.conf # Configuration saved to /etc/frr/ospfd.conf # Configuration saved to /etc/frr/ospf6d.conf # Configuration saved to /etc/frr/bgpd.conf # Configuration saved to /etc/frr/babeld.conf # Configuration saved to /etc/frr/staticd.conf # [OK]
Ativando o service integrated-vtysh-config, configuração padrão desejável:
config t
service integrated-vtysh-config
end
write
# Note: this version of vtysh never writes vtysh.conf
# Building Configuration...
# Integrated configuration saved to /etc/frr/frr.conf
# [OK]
Nota: até a versão corrente, independente do que se fazia, ao reiniciar o FRR ele sempre pinava com o service integrated-vtysh-config ativado.
Concluímos até aqui as operações básicas no framework Zebra. Vamos operar alguns protocolos.
O OSPFv2 é um protocolo relativamente simples. Principais regras:
# Roteador BGP
config t router ospf network 10.90.0.0/30 area 0.0.0.0 default-information originate always end write
# Roteador CORE
config t router ospf network 10.90.0.0/30 area 0.0.0.0 network 10.0.0.0/30 area 0.0.0.0 end write
# Roteador BNG
config t router ospf network 10.0.0.0/30 area 0.0.0.0 end write
Comandos explicados:
Dado os fatos, a configuração abaixo é igualmente eficiente:
# Roteador BGP
config t router ospf network 10.0.0.0/8 area 0.0.0.0 default-information originate always end write
# Roteador CORE
config t router ospf network 10.0.0.0/8 area 0.0.0.0 end write
# Roteador BNG
config t router ospf network 10.0.0.0/8 area 0.0.0.0 end write
Se você observou bem, nada foi mencionado na configuração do OSPF a respeito do servidor Zabbix na rede 172.16.0.0/24, o que significa que apenas o roteador BNG conseguirá se comunicar com ele (por estar na mesma subrede - rota conectada).
Temos 3 opções aqui:
# Roteador BNG - Opção 1
config t router ospf network 10.0.0.0/8 area 0.0.0.0 network 172.16.0.0/24 area 0.0.0.0 end write
# Roteador BNG - Opção 2
config t interface router ospf network 10.0.0.0/8 area 0.0.0.0 network 172.16.0.0/24 area 0.0.0.0 passive-interface eth0 end write
# Roteador BNG - Opção 3
config t interface router ospf network 10.0.0.0/8 area 0.0.0.0 redistribute connected end write
Principais comandos de analise:
show run ospfd show ip ospf interface show ip ospf interface json show ip ospf interface eth0 show ip ospf route show ip ospf neighbor show ip ospf neighbor all show ip ospf neighbor detail show ip ospf database
As adjacências (ato de dois ou mais roteadores estabelecerem troca de informações) no OSPF é por padrão do tipo BROADCAST.
Vale ressaltar que estamos falando de um tipo de adjacência, e não um tipo de pacote (rede OSPF tipo Broadcast não tem a ver com pacotes broadcast ip ou mac). E o OSPF não usa pacotes broadcast, apenas multicast.
As regras de uma rede local com adjacência BROADCAST são:
Outro tipo comum de adjacência é o POINT-TO-POINT (P2P ou PTP).
Trata-se de uma sub-rede utilizada em um enlace com apenas um roteador em cada ponta, quando você liga um roteador direto em outro, ou o OSPF é feito dentro de um Tunnel/VPN L3.
Nesse tipo de adjacência basta que um dos lados envie um HELLO para que a adjacência suba imediatamente. Não há eleição de DR e BDR.
Nossa rede exemplo ficaria melhor configurado dessa forma:
Há uma pegadinha no diagrama acima.
Como nós não determinamos o Router-ID, o OSPF utiliza um dos IPs locais como Router-ID, como também não determinamos o PRIORITY das interfaces, todas elas subiram com PRIORITY 1 (valor padrão). O roteador BNG pode ter o Router-ID 10.90.0.2 ou 172.16.0.1, independente disso, se ele participar da rede 172.16.0.0/24 em adjacência BROADCAST, ele perderá para o servidor Zabbix na eleição, e se tornará BDR. Isso não faz nenhum sentido pra mim.
Se futuramente subirmos mais um servidor nessa subrede com ip 172.16.0.3/24 e ele participar do OSPF, ele será o futuro DR, o Servidor Zabbix BDR e o roteador BNG um Dr-Other.
Portanto, segue a configuração dos 3 roteadores corretamente configurados:
# Roteador BGP
config t interface eth0 ip ospf network point-to-point router ospf network 10.0.0.0/8 area 0.0.0.0 default-information originate always end write
# Roteador CORE
config t interface eth0 ip ospf network point-to-point interface eth2 ip ospf network point-to-point router ospf network 10.0.0.0/8 area 0.0.0.0 end write
# Roteador BNG
config t interface eth0 ip ospf priority 255 ip ospf network broadcast interface eth2 ip ospf network point-to-point router ospf network 10.0.0.0/8 area 0.0.0.0 network 172.16.0.0/24 area 0.0.0.0 redistribute connected end write
Deixei por último a configuração da LOOPBACK e do Router-ID. Eu ouço em muitos cursos e videos de OSPF que a loopback e o Router-ID são vitais para a rede OSPF, e sem eles a rede não funciona. ERRADO.
O RouterID é auto-configurado, e se obviamente você não repetir IP na rede, cada roteador usará um dos seus próprios IPs, que são únicos e inequívocos, logo não há problema algum em deixar o RouterID automático se você não cometeu erros grosseiros na alocação de prefixos IP.
Ja o caso da loopback, é importante que seu roteador tenha um IP que não dependa de cabos para ficar sempre ativo. Se você configura seu SNMP ou qualquer outro protocolo para acessar um roteador, e a interface onde está esse IP perde linha (cabo retirado, fibra rompida), o IP é desativado e você perde contato, tendo que usar um IP de outra interface.
Configurando uma Loopback, independe de qual abordagem ao roteador rompeu, a rota para alcançar a loopback continua lá na rede.
Juntando esses dados, podemos dar um IP único para a loopback de cada roteador, e usamos esse ip como base de tudo: monitoramento, Router-ID do OSPF/LDP/BGP, etc...
Rede com Loopback e Router-ID manual:
# Roteador BGP
config t interface lo ip address 10.255.255.1/32 interface eth0 ip ospf network point-to-point router ospf ospf router-id 10.255.255.1 network 10.0.0.0/8 area 0.0.0.0 default-information originate always end write
# Roteador CORE
config t interface lo ip address 10.255.255.2/32 interface eth0 ip ospf network point-to-point interface eth2 ip ospf network point-to-point router ospf ospf router-id 10.255.255.2 network 10.0.0.0/8 area 0.0.0.0 end write
# Roteador BNG
config t interface lo ip address 10.255.255.3/32 interface eth0 ip ospf priority 255 ip ospf network broadcast interface eth2 ip ospf network point-to-point router ospf ospf router-id 10.255.255.3 network 10.0.0.0/8 area 0.0.0.0 network 172.16.0.0/24 area 0.0.0.0 redistribute connected end write
Para encerrar a matéria de OSPFv2, vamos implementar o tratamento de rotas conectadas de usuários PPPoE. Fonte das principais demandas do uso de OSPF e onde acontecem uma quantidade enorme de deselegâncias na configuração.
Considere o diagrama abaixo, onde no roteador BNG temos um PPPoE Server (Accel-ppp ou RP-PPPoE, ...).
Missão:
É necessário que o roteador BGP e o roteador CORE tenham conhecimento das rotas utilizadas no roteador BNG via clientes PPPoE.
Existem algumas formas de resolver esse problema, a saber:
Essa é a pior técnica de todas.
Sempre que você declarar uma rede no OSPF, você está criando um filtro que determina quais interfaces participam da área, e incluir o POOL de clientes PPPoE nesse filtro é uma violência à rede. Cada interface PPP será classificada como uma interface OSPF assim que receber um endereço IP dentro dos filtros de OSPF Network, tal interface aparecerá no comando "show ip ospf interface", e pior de tudo, um LSA (Link-state advertisement) será enviado para cada evento up/down de cada interface, 1000 usuários representariam 2000 LSA que irão inundar todo o backbone.
Se houver LDP na rede, cada atualização de rota IP resultará no provisionamento de um LABEL MPLS para ela.
O endereço IP do cliente PPPoE (/32) será propagado por todo backbone, 1 rota por conexão PPPoE. Num provedor com 16 mil usuários, isso seria um completo inferno astral para o backbone.
Para piorar, cada interface classificada na área será uma possivel adjacência, o OSPF enviará HELLO padrão periódio para cada interface PPP, com 1000 clientes online isso significa 1 hello a cada 10 segundos, 6 hellos por interface PPP a cada minuto, 6000 pacotes por minuto sendo injetados na rede de clientes PPPoE. Isso numa rede rádio é um desastre.
router ospf # ... network 100.80.0.0/19 area 0.0.0.0 network 172.22.0.0/22 area 0.0.0.0 network 45.255.128.0/22 area 0.0.0.0 # ... end
Para resolver os problemas da opção 1, cujo sintoma é estouro de CPU dos roteadores do backbone, algumas pessoas classificam todas as interfaces por padrão como passivas, ou seja, ainda serão classificadas como interfaces na área, gerando LSA abusivo, mas não haverá possibilidade de adjacência com os clientes PPPoE pela supressão do envio de hello. Se a opção 1 era extremamente horrível, essa é apenas muito ruim.
O endereço IP do cliente PPPoE (/32) ainda será propagado por todo backbone, 1 rota por conexão PPPoE.router ospf # ... network 100.80.0.0/19 area 0.0.0.0 network 172.22.0.0/22 area 0.0.0.0 network 45.255.128.0/22 area 0.0.0.0 passive-interface default no passive-interface eth0 no passive-interface eth1 # ... end
A sumarização de rotas de uma área é um mecanismo que, ao especificar um prefixo sumarizado, a presença de apenas 1 prefixo especifico dentro do prefixo sumarizado dispara o anuncio da rota sumarizada, e não as rotas especificas.
Essa técnica sozinha é ineficiente em concentradores PPPoE pois ainda há o registro de cada interface PPP no banco de dados de interfaces OSPF dentro da área, se na mesma área houver outras redes, elas serão inundadas de LSA.
Para evitar que os clientes sejam inundados com hello, combina-se com o uso de interfaces passivas.
Posso classificar essa técnica como não muito ruim.router ospf # ... network 100.80.0.0/19 area 0.0.0.99 network 172.22.0.0/22 area 0.0.0.99 network 45.255.128.0/22 area 0.0.0.99 area 0.0.0.99 range 100.80.0.0/19 area 0.0.0.99 range 172.22.0.0/22 passive-interface default no passive-interface eth0 no passive-interface eth1 # ... end
Em vez de torrar o banco de dados do OSPF com milhares de dados e cálculos de interfaces, adjacências em PPP, sumarização, podemos simplesmente não incluir os usuários PPPoE diretamente no OSPF e obter as rotas conectadas importando-as do kernel para dentro do banco de dados de rotas OSPF.
Não haverá inundação de LSA e teremos apenas atualização de rotas, estressando menos o algoritmo Dijkstra’s.
Essa técnica é a mais comum, mas ainda tem um efeito desagradável. A rede é inundada com muitas rotas /32, uma para cada usuário conectado. O que tem efeitos colaterais desastrosos no LDP/MPLS e na CPU de todos os roteadores do backbone.
Eu classifico essa técnica como ruim, preguiçosa.router ospf # ... redistribute connected # ... end
Quando eu informo para algum aluno ou cliente que uma rota blackhole destrui os pacotes com destino nela, a primeira reação é sempre de repulsa, porque deletar os pacotes que vão para os IPs dos clientes?
Observe a configuração:ip route 100.80.0.0/19 blackhole 1 ip route 172.22.0.0/22 blackhole 1 router ospf # ... redistribute static # ... end
Embora os prefixos estejam em blackhole, quando um cliente PPPoE se conectar uma nova rota /32 surgirá, e por ser mais específica a rota /32 vence a decisão, e em vez do pacote ser deletado ele é enviado ao cliente.
Isso é o que acontece no roteador BNG, mas os demais roteadores não irão receber rotas conectadas nesse caso. Somente as rotas estáticas, e rotas blackhole são rotas estáticas.
Essa técnica provê um efeito de sumarização simples e elegante, não haverá notificações aos roteadores do backbone OSPF independente se estiverem conectados 1 ou 10 mil usuários.
Se você observou bem, não tratamos do prefixo público do CGNAT em nenhum momento, o prefixo 45.255.130.0/25.
Existem 4 formas de guiar a rota do prefixo público até o equipamento CGNAT (Roteador BNG no nosso caso).
- 1 - Criam uma rota estática no roteador acima (o Roteador CORE aponta o prefixo para o roteador BNG). Não vou nem comentar pois considero que toda rota estática que não seja blackhole uma BOMBA RELÓGIO a explodir na cara do suporte nível 3;
- 2 - Colocar todos os IPs do prefixo público de CGNAT como /32 na interface loopback, uma grosseria (um monte de IPs respondendo a ping, um monte de rotas /32 enchendo a rede, um monte de linhas na configuração);
- 3 - Colocar o primeiro IP do prefixo com a máscara correta na interface Loopback ou Null. Pena que alguns roteadores não aceitam IPs na loopback que não seja /32, nem atribuição de IPs na interface Null (dummy). Essa é uma boa opção, mas infelizmente não é universal;
- 4 - Criar uma rota blackhole do prefixo público de CGNAT. Acredite: isso não vai impedir o funcionamento do CGNAT pois quando o pacote retorna da Internet o IP de destino público é revertido para o IP privado do cliente antes da etapa de roteamento (estágio PREROUTING). A rota passa a ser uma simples rota estática.
Outra coisa que não foi abordada ainda é o uso de IPs públicos delegado aos clientes via RADIUS. Algumas redes colocam todo a faixa de IPs público numa área OSPF, o que nos retorna ao mesmo problema da opção 1.
Devido o fato de que uma rota /32 de IP público é uma rota do tipo diretamente conectada, importar rotas conectadas resolveria esse problema, se não fosse o fato de que todas os demais /32 de IPs privados no CGNAT se enquadram na mesma categoria.
Vamos resolver os problemas dos IPs públicos e blackholes de uma mesma forma: fazendo o controle de rotas que iremos importar para dentro do OSPF.
Veja a configuração completa:interface lo ip address 10.255.255.3/32 interface eth0 ip ospf priority 255 ip ospf network broadcast interface eth2 ip ospf network point-to-point # Blackholes: ip route 100.80.0.0/19 blackhole 1 ip route 172.22.0.0/22 blackhole 1 ip route 45.255.130.0/25 blackhole 1 # Lista de prefixos permitidos ip prefix-list BNG-Routes-IPv4 seq 10 permit 100.80.0.0/19 ip prefix-list BNG-Routes-IPv4 seq 20 permit 172.22.0.0/22 ip prefix-list BNG-Routes-IPv4 seq 30 permit 45.255.130.0/25 ip prefix-list BNG-Routes-IPv4 seq 40 permit 45.255.128.0/22 ge 25 le 32 # Politica para permitir apenas prefixos da lista acima route-map BNG-OSPF-Import-IPv4 permit 1 match ip address prefix-list BNG-Routes-IPv4 # router ospf ospf router-id 10.255.255.3 network 10.0.0.0/8 area 0.0.0.0 network 172.16.0.0/24 area 0.0.0.0 redistribute static route-map BNG-OSPF-Import-IPv4 redistribute connected route-map BNG-OSPF-Import-IPv4 end
Explicando:
- A - Colocamos os 3 prefixos utilizados localmente (Pool Cliente, Pool bloqueados e Prefixo público CGNAT) no blackhole (rota estática);
- B - Dentro do OSPF informamos que iremos importar rotas estáticas e rotas conectadas, mas somente se a política BNG-OSPF-Import-IPv4 permitir;
- C - Na política BNG-OSPF-Import-IPv4 informamos que iremos permitir apenas prefixos cadastrados na lista BNG-Routes-IPv4;
- D - Na lista BNG-Routes-IPv4 colocamos os 3 prefixos utilizados localmente (regra 10, 20 e 30), e qualquer IP público dentro do prefixo principal (45.255.128.0/22) na regra 40.
Dessa forma, o OSPF manterá o máximo de silêncio após anunciar os 3 prefixos no blackhole, e quebrará o silêncio apenas quando algum cliente se conectar com algum IP público (enviado pelo RADIUS).
Embora o OSPFv3 tenha sido construído para fazer no IPv6 o que o OSPFv2 faz no IPv4, ele é muito mais do que isso. Ele veio com suporte a famílias de endereços, assim, no futuro o OSPFv3 pode assumir o roteamento de qualquer família de protocolos, principalmente IPv4.
O OSPFv3 é mais simples de operar que o OSPFv2, a primeira diferença facilitadora é que ele é objetivo em relação às interfaces de redes e as áreas, a segunda é que ele NÃO PRECISA DE ENDEREÇOS CONFIGURADOS NA INTERFACE PARA FUNCIONAR.
Isso mesmo, uma rede sem nenhum IPv6 configurado funciona só de você rodar OSPFv3 no backbone, mesmo que entre as interfaces dos roteadores do backbone não hajam endereços IPv6 configurados.
Isso de deve a natureza LINK-LOCAL (fe80::) das comunicações IPv6.
Considerando o diagrama acima, a configuração fica assim:
# Roteador BGP
config t interface lo ipv6 address 2804:cafe:ffff:ffff::1/128 interface eth0 ipv6 ospf6 network point-to-point ipv6 route 2000::/3 blackhole 250 ipv6 prefix-list GLOBAL-SUMMARY-IPV6 permit 2000::/3 ipv6 prefix-list GATEWAY-IPV6 permit ::/0 route-map OSPFV3-IMPORT-STATIC permit 10 match ipv6 address prefix-list GLOBAL-SUMMARY-IPV6 route-map OSPFV3-IMPORT-STATIC permit 20 match ipv6 address prefix-list GATEWAY-IPV6 router ospf6 ospf6 router-id 10.255.255.1 interface eth0 area 0.0.0.0 interface lo area 0.0.0.0 redistribute static route-map OSPFV3-IMPORT-STATIC end write
# Roteador CORE
config t interface lo ipv6 address 2804:cafe:ffff:ffff::2/128 interface eth0 ipv6 ospf6 network point-to-point interface eth2 ipv6 ospf6 network point-to-point router ospf6 ospf6 router-id 10.255.255.2 interface eth0 area 0.0.0.0 interface eth2 area 0.0.0.0 interface lo area 0.0.0.0 end write
# Roteador BNG
config t interface lo ipv6 address 2804:cafe:ffff:ffff::3/128 interface eth0 ipv6 ospf6 network point-to-point interface eth2 ipv6 ospf6 network point-to-point ipv6 route 2804:CAFE:D100::/48 blackhole 1 ipv6 route 2804:CAFE:D200::/48 blackhole 1 ipv6 route 2001:DB8:FADA::/48 blackhole 1 router ospf6 ospf6 router-id 10.255.255.3 interface eth0 area 0.0.0.0 interface eth2 area 0.0.0.0 interface lo area 0.0.0.0 redistribute static end write
|
|