O Minimo que Voce precisa saber sobre o BGP

De Wiki BPF
Revisão de 21h59min de 5 de junho de 2020 por Leonardo.furtado (discussão | contribs)
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para navegação Ir para pesquisar

O mínimo que você precisa saber sobre o BGP

Nota sobre direitos autorais, termo de uso e isenção de responsabilidade

Consulte os direitos autorais e licença de uso antes de usar este material em seu blog, ou incorporá-lo a qualquer trabalho de natureza acadêmica ou de destinação profissional.

Autor: Leonardo Furtado

Introdução

Em minhas andanças Brasil afora e também nos grupos de discussão e nas redes sociais, com muita frequência, me deparo com a seguinte situação: indivíduos que precisam conceber políticas de roteamento com o BGP para o cumprimento de algum objetivo em seu Sistema Autônomo envolvendo a engenharia da rede ou a engenharia de tráfego. Por exemplo:

"Preciso preferir rotas oriundas do AS 'X' a partir do IX em São Paulo. Como faço? "

"Preciso influenciar o tráfego de entrada (download) de determinado serviço de conteúdo a partir do meu trânsito contratado com a 'xpto'? Alguém me ajuda?"

"Como faço para influenciar o tráfego de saída (upload) por determinada sessão de peering 'xyz'?"

"Qual é a melhor maneira de promover uma simetria mais proporcional sobre a ocupação dos enlaces com os meus upstreams?"

E situações deste tipo.

Ai eu analiso as tantas contribuições e ajudas que a comunidade fornece para esses requisitantes. Algumas ajudas são bem válidas, sem dúvidas, e outras um tanto desconexas. O que eu percebo é que muito frequentemente quem solicita a ajuda precisa em primeiro momento compreender como o BGP de fato funciona. O básico. O fundamental. E, em alguns casos, as almas boas que propõem-se a ajudar também deixam implícito que não conhecem tanto do BGP assim, mas que, de certa forma, habituaram-se a trabalhar com as ferramentas de manipulação do tráfego do BGP por pura e simples osmose. "Um consultor veio aqui e fez isso, e desde então eu venho mantendo assim". Aquela famosa expressão "papagaio de pirata".

Por que estou escrevendo este artigo? Sinceramente? Porque eu entendo que lidar com políticas de roteamento para influenciar o envio e recebimento de rotas, manipulação do tráfego upload/download, engenharia de tráfego por BGP e afins, tudo isto, deve ser uma das últimas coisas que você de fato precisa se preocupar e dominar no BGP. Você primeiro precisa conhecer o funcionamento do BGP antes mesmo de querer implementar coisas mais sofisticadas. E é justamente isto que vejo faltando em muitos profissionais excessivamente preocupados com assuntos de políticas de roteamento do BGP.

Muito do que fazemos ou do que precisa ser feito exige conhecimentos em diversas áreas fundamentais do BGP! Estou sendo bem honesto aqui: muitos realmente não dominam o básico do BGP e, por este motivo, possuem dificuldades em conceber determinados cenários envolvendo suas políticas de roteamento e outras coisas.

Esta "palinha" que acompanha a ilustração/topologia mostrada a seguir tem um conceito que venho abordando há alguns anos para orientar profissionais que atuam em ISP sobre o funcionamento básico do BGP. Espero que seja igualmente útil para os frequentadores da Wiki do Brasil Peering Forum (BPF)!

A estratégia de abordagem para este artigo será padrão "bullets". Isto é, sentenças curtas e bem objetivos para tentar mostrar o meu ponto de vista e o que eu estou tentando contribuir para estes profissionais e interessados.Considere como um livro compactado na forma de "bullets"!

Confesso que muitos ainda assim terão dificuldades em compreender o BGP. Eu prometi que eu comentaria o básico e de forma objetiva. Eu não prometi o "fácil": prometi apenas o fundamental!

Caso você realmente precise de uma "escovada" mais básica nos temas de redes, posso sugerir aqui um artigo muito útil: Fundamentos de Roteamento para Provedores.

Mas, realmente, recomendo que você faça vários (e bons!) cursos na área. Está na hora de você fazer este investimento na sua carreira, não?

Vamos lá?

O básico do BGP mostrado em uma única página!

Revisão de alguns conceitos bem básicos do BGP-4

Para todos os efeitos - e até mesmo para facilitar o seu entendimento sobre os fundamentos do BGP - considere a topologia a seguir. E vá acompanhando "texto + topologia" para melhorar o seu entendimento.

Uma topologia básica envolvendo o BGP

Por que preciso um protocolo de roteamento IGP tipo o OSPF na minha rede? Não poderia ter apenas o BGP rodando no meu AS?

A resposta direta, crua e nua, é "não!". O BGP depende de roteamento unicast para o seu funcionamento. Os "bullets" a seguir sintetizam os motivos disto:

  • O protocolo de roteamento BGP-4 não funciona “sozinho”, ou seja, numa rede (Autonomous System) não pode operar sem o auxílio do roteamento unicast do tipo IGP. O BGP depende diretamente das rotas IGP (não importa o tipo, podendo ser conectada, estática, OSPF, etc., mas desde que seja IGP) na tabela de roteamento do equipamento para realizar duas funções básicas:
    • Transportar as sessões BGP entre os roteadores de uma determinada sessão.
    • Validar o atributo NEXT_HOP do BGP num procedimento que chamamos de roteamento recursivo.

Não compreendo as diferenças entre IBGP e EBGP. Pensei que fossem apenas nomes a serem decorados. Quais são as diferenças funcionais?

O que todos sabem é que há sessões "internas" e "externas", ou seja, IBGP e EBGP. A primeira envolve sessões estabelecidas entre roteadores do mesmo AS, e a segunda, obviamente, entre roteadores em ASs distintos. As diferenças vão bem além dos simples termos "EBGP" e "IBGP" como muitos sugerem. A questão é funcional mesmo:

  1. Há diferenças nos requerimentos para a formação de sessões BGP internas e externas. Por exemplo, sessões EBGP precisam ser estabelecidas através da mesma subrede IP ("diretamente conectados no L2+IP"), exceto quando fazendo isto por EBGP Multihop. Enquanto isto, para as sessões IBGP, normalmente assumimos que os roteadores a serem vizinhos estejam de fato distantes entre si.
  2. Há diferenças no que tange ao repasse de anúncios nos dois casos (ex: Split Horizon no IBGP, e até mesmo o descontinuado "Synchronization" do IBGP).
  3. Há diferenças na preferência por rotas. Dependendo da disposição de atributos e estágios "mais fortes", roteadores tendem a preferir rotas recebidas de sessões externas do que rotas para os mesmos prefixos recebidos por sessões internas.

Agora, voltemos aos "bullets" aqui:

  • Para sessões EBGP, assumimos que os neighbors estejam diretamente conectados (mandatório = default), inclusive o TTL do cabeçalho IP é igual a “1” nos pacotes de uma sessão EBGP. Porém, quando os roteadores de AS distintos precisam formar uma sessão, e caso estejam separados por outros roteadores, você poderá configurar o ebgp-multihop para viabilizar esta sessão.
  • Para sessões IBGP, ao contrário das sessões EBGP, assumimos que os neighbors normalmente estejam distantes entre si dentro do AS (isto é, não estejam diretamente conectados).

Para provar que BGP não funciona sem o auxílio de rotas IGP:

  • Não há mecanismos de descoberta de vizinhos BGP (um “neighbor discovery" da vida), ao contrário do que ocorre com os protocolos de roteamento IGP. No caso do BGP, é mandatório configurar as vizinhanças (neighbors) manualmente.
  • O BGP não funciona por multicast com os endereços do escopo Local Network Control Block (224.0.0.0 - 224.0.0.255 (224.0.0/24)), como seria o caso de um protocolo de roteamento interior (OSPF, RIPv2, EIGRP) e sim por unicast (TCP porta 179). Uma sessão BGP não é muito diferente de, por exemplo, uma conexão com um serviço Web por transmissão unicast. É sério!
    • Por ser uma transmissão Unicast, há obviamente os endereços de origem e destino no cabeçalho IP. Assim como teria num HTTP para o site do Facebook, por exemplo.
  • Numa sessão IBGP, como os neighbors frequentemente estão distantes entre si, é necessário haver uma rota IGP para se chegar até o referido neighbor e estabelecer a conexão TCP com este.
    • O endereço IP de origem a ser utilizado no cabeçalho IP será aquele associado à interface de saída da rota IGP encontrada para a conexão com o vizinho BGP pretendido. Portanto, quando o roteador “10.1.1.1” da topologia acima desejar estabelecer uma sessão BGP com o roteador “10.4.4.4”, o que ele faz?
      • O roteador “10.1.1.1” consultará a sua tabela de roteamento e buscará por uma rota unicast (pode ser diretamente conectada, OSPF, RIP, estática...) mais específica referente ao endereço IP de destino pretendido, que, neste caso, é o "10.4.4.4".
      • Determinará o next hop e a interface de saída associada a esta rota IGP que ele encontrar.
      • O PDU da camada “Rede” (cabeçalho IP) conterá como endereço IP de origem o IP da interface de saída associada à rota IGP que aponta na tabela de roteamento para a rota mais específica encontrada satisfazendo o critério ao “10.4.4.4”. E, quanto ao endereço IP de destino deste cabeçalho IP, será obviamente o "10.4.4.4".
      • Só que isto poderá causar problemas, e explico o por que logo abaixo.
    • Como os neighbors precisam estar pré-configurados, e podendo haver múltiplos caminhos internos no seu AS entre eles, poderá ser necessário "amarrar" isto numa interface loopback, usando-se o mecanismo "update-source loopback x" (ou procedimento similar no equipamento do seu fabricante).
      • Isto significa que recomenda-se estabelecer as sessões IBGP utilizando-se os endereços IP das interfaces Loopback que, diga-se de passagem, deverão estar participando do IGP da rede.
      • Portanto, usamos as interfaces loopback dos roteadores (tanto para a origem quanto para o destino) para estabelecer as sessões IBGP. Isto porque, na topologia acima, “10.1.1.1” espera pacotes da sessão BGP vindas de “10.4.4.4”, e vice-versa, e não de quaisquer outros endereços IP. Uma vez que múltiplos caminhos internos poderão existir e frequentemente existem entre A e B, poderá haver divergências quanto ao endereço IP de origem a ser especificado nos cabeçalhos IP.
    • O não cumprimento disto fatalmente resultará na falha do estabelecimento da sessão BGP entre os dois vizinhos IBGP, pois o endereço IP de origem da transmissão poderá ser o de uma interface local ao router cujo endereço não é reconhecido como vizinho/neighbor IBGP no equipamento remoto o qual desejamos formar a sessão IBGP.
  • Em tempo, isto portanto isto reforça novamente o argumento que não há como BGP operar/funcionar sem o auxílio do roteamento unicast devidamente alimentado por rotas IGP.
  • Outra informação importante é que, de todas as rotas publicadas em uma tabela de roteamento, as únicas que não possuem interface de saída associada são justamente a rotas BGP, ao contrário do que ocorre com rotas IGP.
    • Isto porque o BGP não é habilitado e não funciona diretamente sobre as interfaces dos roteadores, pois é um processo completamente "global" no equipamento. Ao oposto do que ocorre nos protocolos IGP, que são configurados globalmente, mas que, ainda assim, são ativados diretamente sobre as interfaces desejadas.
      • O que ocorre aqui neste caso, dentre outras coisas, é o chamado "recursive routing lookup" (roteamento recursivo). Há alguns processos/threads relacionadas ao BGP no software dos roteadores, e um deles é responsável por realizar periodicamente, dentre outras funções importantes, um "walking" sobre a tabela BGP para a validação dos next-hops BGP, se os mesmos encontram-se alcançáveis através da tabela de roteamento com rotas IGP.
        • Portanto precisamos do IGP para: a) transportar as sessões BGP. b) para validação e recursivo do atributo NEXT_HOP associado a cada uma das rotas mantidas na tabela BGP do roteador.

A propósito, caso você tenha curiosidade, os protocolos de roteamento implementam um conceito chamado de Finite State Machine. Que são justamente os estágios de formação de vizinhança. No caso do BGP, os estados são:

  • Idle
  • Active
  • Connect
  • Open Sent
  • Open Confirm
  • Established

Compreender exatamente o que ocorre em cada um desses estágios é fundamental para que você consiga resolver problemas com formação de vizinhanças no BGP, sejam estas internas ou externas!

Finite State Machine (FSM) do BGP

Alguns conceitos fundamentais sobre os atributos do BGP e o processo de seleção de caminhos

  • As “métricas” do BGP são bastante diferentes das métricas de outros protocolo de roteamento. O protocolo RIP por exemplo implementa o “hop count” (contagem de saltos). O OSPF por sua vez implementa o “cost” (custo, que é a banda de referência globalmente definida pelo OSPF - em muitos casos é 100 Mbps por padrão - dividida pela banda da interface), etc. Já o BGP é muito mais amplo que isto, por tratar-se de um protocolo vetor de caminhos (path vector). Não há na verdade “métricas”, e sim os chamados atributos de caminhos (path attributes).
  • Os atributos do BGP são categorizados nos seguintes: Well-known Mandatory, Well-Known Discretionary, Optional Transitive e Optional Non-transitive. Em particular, os atributos "mandatórios” são: AS_PATH, ORIGIN e o NEXT_HOP. Estes atributos são chamados de mandatórios porque precisam constar em todas as mensagens Update do BGP (por onde ocorrem o envio e o recebimento de prefixos (“anúncios”)).

Resumindo aqui:

  • Atributos "Well-Known": todo roteador que se preze e que suporte o BGP precisa por obrigação compreender aquele atributo recebido, caso seja um Well-Known.
    • Mandatory: obrigatório ser incluído em todas as mensagens Update.
    • Discretionary: a presença do atributo nas mensagens Update é facultativa. Mas, se um atributo desse for incluído, o roteador que o receber precisará compreendê-lo.
  • Atributos "Optional": o roteador não é "obrigado" a compreender o atributo. Vai que não suporta (ainda) no seu código?
    • Transitive: caso o roteador suporte, fará uso do atributo e o repassará adiante para outros peers. Caso não suporte o referido atributo, passará adiante da mesma forma.
    • Non-Transitive: o atributo não é repassado para outros peers, sendo reconhecido ou não.

A ilustração a seguir mostra os principais, ou, melhor, os mais conhecidos atributos do BGP, sendo que a maioria deles sequer é utilizada para o processo (natural) de seleção das melhores rotas na tabela BGP.

Os principais (ou mais conhecidos) atributos do BGP

Mas a lista de atributos do BGP é bastante extensa! A tabela a seguir dá uma noção do quanto o profissional precisa estar preparado para conhecer as aplicabilidades de cada um destes tantos atributos.

OBS: a lista é mantida e atualizada pelo IANA na URL Border Gateway Protocol (BGP) Parameters.

Valor Código Referência
0 Reserved
1 ORIGIN [RFC4271]
2 AS_PATH [RFC4271]
3 NEXT_HOP [RFC4271]
4 MULTI_EXIT_DISC [RFC4271]
5 LOCAL_PREF [RFC4271]
6 ATOMIC_AGGREGATE [RFC4271]
7 AGGREGATOR [RFC4271]
8 COMMUNITY [RFC1997]
9 ORIGINATOR_ID [RFC4456]
10 CLUSTER_LIST [RFC4456]
11 DPA (deprecated) [Chen, E., Bates, T., "Destination Preference Attribute for BGP", Work in progress, March 1996.][RFC6938]
12 ADVERTISER (historic) (deprecated) [RFC1863][RFC4223][RFC6938]
13 RCID_PATH / CLUSTER_ID (Historic) (deprecated) [RFC1863][RFC4223][RFC6938]
14 MP_REACH_NLRI [RFC4760]
15 MP_UNREACH_NLRI [RFC4760]
16 EXTENDED COMMUNITIES [Eric_Rosen][draft-ramachandra-bgp-ext-communities-00][RFC4360]
17 AS4_PATH [RFC6793]
18 AS4_AGGREGATOR [RFC6793]
19 SAFI Specific Attribute (SSA) (deprecated) [Gargi_Nalawade][draft-kapoor-nalawade-idr-bgp-ssa-00][draft-nalawade-idr-mdt-safi-00][draft-wijnands-mt-discovery-00]
20 Connector Attribute (deprecated) [RFC6037]
21 AS_PATHLIMIT (deprecated) [draft-ietf-idr-as-pathlimit]
22 PMSI_TUNNEL [RFC6514]
23 Tunnel Encapsulation Attribute [RFC5512]
24 Traffic Engineering [RFC5543]
25 IPv6 Address Specific Extended Community [RFC5701]
26 AIGP [RFC7311]
27 PE Distinguisher Labels [RFC6514]
28 BGP Entropy Label Capability Attribute (deprecated) [RFC6790][RFC7447]
29 BGP-LS Attribute [RFC7752]
30 Deprecated [RFC8093]
31 Deprecated [RFC8093]
32 LARGE_COMMUNITY [RFC8092]
33 BGPsec_Path [RFC8205]
34 BGP Community Container Attribute (TEMPORARY - registered 2017-07-28, extension registered 2018-08-10, expires 2019-07-28) [draft-ietf-idr-wide-bgp-communities]
35 Internal Only To Customer (TEMPORARY - registered 2018-03-29, extension registered 2019-03-18, expires 2020-03-29) [draft-ietf-idr-bgp-open-policy]
36 BGP Domain Path (D-PATH) (TEMPORARY - registered 2019-07-08, expires 2020-07-08) [draft-ietf-bess-evpn-ipvpn-interworking]
37-39 Unassigned
40 BGP Prefix-SID [RFC-ietf-idr-bgp-prefix-sid-27]
41-127 Unassigned
128 ATTR_SET [RFC6368]
129 Deprecated [RFC8093]
130-240 Unassigned
241 Deprecated [RFC8093]
242 Deprecated [RFC8093]
243 Deprecated [RFC8093]
244-254 Unassigned
255 Reserved for development [RFC2042]

Voltando aqui para a linha de raciocínio com os "bullets"! Vejamos:

  • O BGP emprega, em ordem linear, 11 (onze) critérios para a seleção de caminhos, e isto pode ser um pouco diferente dependendo da plataforma/fabricante. Por exemplo, o conhecido "Weight" não é na verdade um atributo, pois não navega nas mensagens Update e, sim, é um mecanismo local no roteador. E é proprietário (Cisco), portanto não é fatorado no processo de seleção de rotas BGP em roteadores não Cisco.
  • Eu costumo citar especialmente aqui que o critério "zero" é: "um router BGP só considera durante o processo de seleção de best paths de rotas BGP somente aquelas cujo o atributo NEXT_HOP for conhecido ou 'alcançável' por rotas IGP na tabela de roteamento".
    • Portanto, novamente, reforçamos aqui o conceito de "recursive routing" efetuado pelo BGP.

Falando do processo de seleção de rotas do BGP, que tal visualizarmos isto com maior amplitude? Fique atento ao processo suportado/executado pelo seu roteador/fabricante, pois alguns conceitos poderão ser diferentes dos mostrados a seguir. Outra informação importante: comparados à extensa lista acima, são poucos (mesmo) os atributos usados para manipular o tráfego através de uma política de roteamento no BGP.

Processo de seleção de rotas do BGP

Quais roteadores do meu AS precisam de fato rodar o BGP?

Quanto ao "rodar ou não rodar" BGP em todos os routers no AS", esclareço que:

a) Em um AS "corporativo" ou "Non Transit AS", na maioria dos casos não é necessário sessões IBGP em todos os roteadores no AS. Geralmente fazemos o EBGP nos routers de borda com as operadoras/ISP, e uma sessão IBGP entre estes routers na borda. Estes roteadores BGP tipicamente geram uma rota default (0.0.0.0/0) via protocolo IGP (OSPF ou outro) que for suportado dentro do AS, para os demais roteadores (não BGP) poderem encaminhar o tráfego de saída através desta rota default para os destinos de Internet.

b) No entanto, em um AS de Trânsito, é "obrigatório" rodar o IBGP em todos os roteadores no AS que estiverem no meio do caminho do tráfego que precisa transitar pelo AS, e devido a limitações do IBGP, sendo as seguintes:

  • Uma rota BGP não sofre quaisquer modificações de seus atributos dentro do AS entre as sessões IBGP. Isto é, uma vez a rota tiver sido injetada no AS e repassada para os neighbors IBGP, ela não sofrerá quaisquer modificações em seus atributos.
  • Portanto, uma vez que a rota BGP, quando repassada por IBGP, não sofre qualquer modificação de atributos, seria relativamente muito plausível que pudesse ocorrer um "routing loop" no AS, já que não haveria controle de diâmetro (saltos) ou incremento de "custos" (que são inexistentes na arquitetura do BGP), etc.
    • Por este motivo, há uma regra imposta para as sessões IBGP: rotas recebidas via IBGP não poderão ser repassadas para outros neighbors IBGP. É o que chamamos de "Split Horizon" do BGP. Isto é o comportamento padrão envolvendo as sessões IBGP.
    • Portanto isto significa que é mandatório possuir sessões IBGP em formação FULL MESH. Ou seja, todos os routers IBGP sendo neighbors entre si.
      • Obviamente em redes maiores isto poderá limitar um tanto a escalabilidade do AS, pois muitas sessões IBGP seriam requeridas dentro do AS, conforme regra "N*(N-1)/2".
      • No entanto, há soluções para a mitigação o relaxamento das exigências por full mesh das sessões IBGP, e estas soluções seriam o Route Reflector ou cluster de Rote Reflectors (para maior redundância e disponibilidade) ou ainda o Intra-AS Confederation, ou ainda a mistura das duas coisas. Cada projeto de BGP é um projeto distinto e com necessidades únicas.
  • Caso o IBGP seja utilizado somente entre os routers de borda conforme ilustrado no AS 200, o pacote morreria no meio do caminho (dentro do AS 200) devido ao problema do Split Horizon do BGP.
    • Por exemplo, o router "10.1.1.1" da topologia mostrada no início desse artigo possui a rota BGP para a rede "50.50.50.0/24" via Next-Hop 192.168.0.2, que está no AS 100. Ele considera esta rota válida porque o roteamento recursivo neste roteador encontrará uma rota diretamente conectada (192.168.0.0/30) para este atributo NEXT_HOP citado na rota BGP.
    • Em seguida, o roteador “10.1.1.1” repassará este anúncio (50.50.50.0/24) para os roteadores “10.2.2.2” e “10.3.3.3” através das sessões IBGP que mantém com estes dois roteadores.
    • Estes dois roteadores por sua vez não repassarão este anúncio para o roteador “10.4.4.4” porque isto fere a regra do Split Horizon do BGP (“não repassar para peers IBGP quaisquer rotas que tenham sido aprendidas através de uma sessão IBGP").
      • Isto poderia evitado de duas formas:
        • Configuração das sessões IBGP em regime "full mesh", ou seja, todos são neighbors IBGP entre si.
        • Configuração de um roteador como Router Reflector, ou ainda dois ou mais roteadores em uma disposição de "cluster" de Route Reflectors. Ou então por Confederation.
          • Na topologia fornecida nesta artigo, os roteadores "10.1.1.1" e "10.4.4.4" estão configurados como Route Reflectors e no mesmo Cluster. Isto significa que todos os roteadores do AS 200 precisariam de sessões IBGP com apenas estes dois roteadores do Cluster.
            • Lembro novamente que Route Reflectors "quebram" a exigência por full mesh das sessões IBGP em um AS, e roteadores configurados com este mecanismo podem refletir rotas recebidas por sessões IBGP para outros roteadores IBGP que sejam seus cientes de RR.

c) OK, temos aqui a solução para um AS de Trânsito: rodar o BGP em todos os roteadores que estiverem "in-line" com o tráfego. E, para fugirmos do requerimento por sessões em full-mesh, construímos as sessões com o auxílio de Route Reflectors ou Confederation. Mas, calma, há uma forma mais interessante de conduzirmos isto, vide logo a seguir.

Sobre rodar o BGP em toda a rede do AS, especialmente nos roteadores de Core (P-routers)

Na prática ou em tese todos os roteadores que estiverem no mesmo caminho do tráfego em trânsito em um AS precisam rodar o BGP, certo? Há uma solução “mais elegante” para esta questão, e ela está amplamente e bem difundida em um artigo disponível na Wiki do BPF: BGP-Free Service Provider Core.

Não detalharei essa solução aqui porque tudo isto já está bem esclarecido no artigo Redes MPLS para Provedores.

Um ponto final na questão do roteamento recursivo

No cenário em que o roteador "10.1.1.1" recebe a rota para a rede 50.50.50.0/24 via a sessão EBGP que possui com o AS 100. Este roteador reconheceria esta rota como válida (pelas validações dos atributos mandatórios) e pelo fato de ser capaz de efetuar o roteamento recursivo referente ao atributo NEXT_HOP desta rota, que seria o endereço IP 192.168.0.2. Afinal de contas, este roteador possui uma rota diretamente conectada para este next hop.

No entanto, ao repassar este anúncio (50.50.50.0/24) para os demais roteadores do AS 200 ("10.2.2.2", "10.3.3.3", "10.4.4.4"), seja em regime full-mesh ou em regime com Route Reflectors, teríamos outro desafio aqui. Com a exceção do próprio roteador "10.1.1.1", nenhum dos demais roteadores seria capaz de concluir o recursivo referente ao atributo NEXT_HOP, pois o endereço IP especificado (192.168.0.2) não pode ser encontrado em uma rota IGP do AS 200. E isto é fato na grande maioria das implementações do BGP. A solução para este desafio poderá ser um das três sugestões apresentadas a seguir:

  1. Configurar o IGP da rede (ex: OSPF) para incluir a conexão externa entre os AS 100 e 200, porém definindo a interface do roteador "10.1.1.1" com o AS 200 como Passive.
  2. No roteador "10.1.1.1", redistribuir a interface que conecta o AS 100 ao AS 200 para o IGP (ex: OSPF) do AS 200.
  3. Modificar o atributo NEXT_HOP antes de repassar o anúncio para as sessões IBGP. Que inclusive é o método mais utilizado por aí.
    1. Agora você compreende o significado do recurso "next-hop-self" na configuração das vizinhanças IBGP do seu roteador. Certo?

Uma observação quanto a manipulação de tráfego com o BGP

Sintetizando aqui e bastante, pois a expectativa é que tenhamos um artigo no BPF para tratarmos única e exclusivamente disto:

Manipulação do tráfego da saída (upload) do seu AS

Você tem três alternativas aqui:

  1. Em equipamentos Cisco ou outros vendors que suportarem um recurso similar, usar o recurso Weight para preferir a rota recebida daquele peer acima de todas as demais opções (maior Weight). O Weight é um recurso local ao router, e não um atributo! Logo, não acompanha as mensagens Update (ou seja, os anúncios).
  2. Implementar uma política de roteamento que aplique o atributo LOCAL_PREF correto (maior valor de LOCAL_PREF) para promover a preferência de rotas recebidas a partir de um peering ou trânsito, podendo classificá-las (estes prefixos/rotas) por vários métodos possíveis e cabíveis aqui, incluindo Communities, prefixos, AS_PATH, etc.
  3. Controlar o recebimento de anúncios mais específicos vs. menos específicos nas suas saída com a Internet. O que seria uma ação mais difícil.
Entendimento sobre o uso do atributo LOCAL_PREF

O Local Preference é um atributo do tipo Well-Known Discretionary, ou seja, o roteador poderá ou não incluir este atributo em seus anúncios, mas, caso inclua, o roteador que o receber deverá compreender o atributo, e isto é obrigatório aqui. Onde e como usar o LOCAL_PREF?

O LOCAL_PREF deve ser usado (aplicado) apenas sobre rotas recebidas de sessões EBGP para que possa ser devidamente repassado para os seus peers IBGP (ou seja, no seu AS), ou quando você estiver gerando ou agregando rotas pelo BGP dentro do seu AS. O LOCAL_PREF tem utilidade e somente funciona dentro do seu sistema autônomo (AS). É inútil configurá-lo para anúncios entre sessões EBGP! Você não pode influenciar um AS vizinho com o LOCAL_PREF!

Cada vez que eu vejo isso configurado numa policy OUT para fins de anúncios para um peer EBGP, eu realmente fico sem palavras pra me expressar - brincadeiras à parte aqui. Com as minhas próprias palavras, isto seria tipo o maior placebo que há na questão envolvendo atributos. Dessa forma, não funciona para coisa alguma, mas também não causa mal algum. Por mim, o software dos roteadores deveria recusar essa configuração no commit por violação de semântica, mas talvez isto não ocorra (a recusa de commit da configuração) porque o LOCAL_PREF excepcionalmente pode ser encaminhado entre sessões EBGP em um cenário de Confederations apenas.

Isto está nem documentado pelo RFC 4271 seção 5.1.5.

RFC 4271 seção 5.1.5 (sobre o LOCAL_PREF)
Manipulação do tráfego de entrada (download) do seu AS

Você tem três alternativas aqui:

  1. Manipular o atributo AS_PATH para realizar o prepend quando repassando o prefixo para peering ou trânsito "x". Você poderá classificar os prefixos de interesse por vários métodos possíveis e suportados, tais como os próprios prefixos diretamente, ou atributo AS_PATH, ou com Communities, etc., e fazer o prepend de acordo.
  2. Alternar o repasse de anúncios menos específicos vs. mais específicos para os peers desejados. E a classificação disto podendo ser feita pelos mesmos métodos supracitados.
  3. Caso você possua duas ou mais saídas para um mesmo AS vizinho, você poderá utilizar o atributo Multi-Exit Discriminator (MED), também conhecido por "metric", informando um valor menor desejado (no caso do MED, menor = melhor) quando repassando seus anúncios para este AS vizinho, e fazendo isto no intuito de tentar influenciar o tráfego entrante. O MED é um atributo tido como "fraco" e muito frequentemente não funciona bem para este propósito. A implementação do MED em saídas com dois ou mais AS distintos por meios de always-compare-med é uma possibilidade que pode ser estudada nos acordos de tráfego entre os sistemas autônomos envolvidos.
Entendimento sobre o uso do atributo MED

O Multi-Exit Discriminator (MED) é um atributo Optional Non-Transitive e o mesmo deve ser utilizado (apenas!) para tentarmos influenciar o tráfego de entrada do AS quando havendo duas ou mais sessões EBGP (cenário dual-homed, etc.) com um mesmo sistema autônomo vizinho. O MED funciona apenas para anúncios realizados entre sessões EBGP! E o fato do atributo ser "Non-Transitive" significa que ele (o atributo apenas) não é repassado para além do sistema autônomo (AS) vizinho que recebeu o anúncio contendo este atributo. Ou seja, o seu AS vizinho não repassará o MED para outros AS. Isto está bem documentado pelo RFC 4271, seção 5.1.4.

RFC 4271 seção 5.1.4 (sobre o MED)

Para concluir, o MED é tido como um atributo "fraco" e que frequentemente não atinge o objetivo proposto, e isto por se tratar do sexto (ou quinto, dependendo da plataforma) critério de seleção de uma "best path" do BGP. O MED também é menos funcional ainda quando precisa ser comparado em anúncios oriundos de dois ou mais sistemas autônomos distintos - o que por só já exige configurações e cooperações adicionais - pois isto não é suportado pelas vias normais.

A única forma de manipulação de tráfego de entrada com a consequente seleção de caminhos (ou vice-versa) entre o seu AS e dois ou mais AS vizinhos é com o recurso de prepend de atributo AS_PATH e as estratégias de alternância entre "anúncios menos específicos" versus "anúncios mais específicos".

OBS: o MED pode ser utilizado para codificar métricas de rotas IGP eventualmente redistribuídas para o BGP e de forma a possibilitar algum controle sobre o tráfego ou para fins de manutenção da transparência (ou não) da métrica das rotas IGP originais, fim-a-fim, quando redistribuindo novamente de BGP para IGP. Isto seria o caso de setups de L3VPN MPLS. No entanto, isto está fora do escopo deste artigo.

Conclusões finais sobre manipulação de tráfego de entrada e de saída

Não existe "mágica"! É exatamente isto. Em ambos os casos (download e upload) você precisará de uma matriz de tráfego! Como projetar políticas de roteamento efetivas se você sequer compreende como as conversações fluem no seu Sistema Autônomo? Quais são os volumes de tráfego por endereços IP ou blocos de endereços IP de origem e destino, quais são os sistemas autônomos e seus respectivos registros de consumo de tráfego IN e OUT, top talkers por tipo de protocolo, etc.

Mas discutiremos este tema com bastante detalhes em futuro artigo aqui no BPF. Fique antenado!

Em tempo, confira um pouco deste tema neste artigo aqui: Como fazer com que um determinado conteúdo saia por um link específico , caso você tenha pressa em fazer alguma coisa acontecer!

Uma observação quanto à segurança do roteamento de Internet

Fora do escopo do artigo, mas preciso deixar bem claro. As políticas de roteamento BGP não servem apenas para você influenciar o upload ou o download da rede, ou para descartar o envio e recebimento de anúncios indesejados por quaisquer razões que sejam. As políticas de roteamento do BGP, em combinação com diversos (outros) procedimentos complementares, são indispensáveis para promover a segurança e disponibilidade do roteamento de toda a Internet! Ou seja, evitar vazamentos de rotas impróprias em sistemas autônomos, sequestro de prefixos, congestionamento/gargalos, indisponibilidades massivas, dentre outras graves complicações.

Fique atento quanto aos muitos controles e cuidados propostos/sugeridos pelo Mutually Agreed Norms for Routing Security (MANRS) ou Normas de Acordo Mútuo para Segurança de Roteamento! E siga as boas práticas para a proteção do seu Sistema Autônomo e, consequentemente, de toda a Internet!

"A disposição de cada um é a segurança de todos!"

Felizmente o BPF está tratando de divulgar estes temas, e já contamos com ótimos artigos sobre o assunto. E outros virão com o tempo. Confira os artigos já publicados aqui:

Coisas que você não deveria fazer no seu ambiente BGP

(Eventualmente esta seção do artigo será reeditada com o tempo, pois sempre surgirão motivos para "documentar" aqui!)

Verdades dóem!

Aqui eu relaciono algumas boas "verdades" com relação a diversas (más) práticas que vejo na questão de BGP de muitos ISPs. Seja um bom profissional e não cometa os deslizes comentados abaixo:

  1. PTT não é trânsito. Saiba dimensionar o seu trânsito para ter capacidade de escoamento de tráfego quando ocorrerem falhas nas sessões de peering.
  2. Não existe "link puro". Trânsito é trânsito, e vem tudo ali dentro (tráfego de CDNs do seu upstream, de PNIs dos AS upstreams, peerings dos upstreams, além do trânsito do trânsito, etc.).
  3. Você escolhe o seu trânsito por preço apenas? Jura que não olha/valida os mapas de emparelhamentos e as relações dos demais ASs conectados nos upstreams, assim como os ASs do ASs?
  4. O roteamento pelo BGP é assimétrico por natureza e em grande parte. Você pode até tentar conceber alguma simetria do tráfego por meios de políticas, mas não há quaisquer garantias de êxito quanto a isso.
  5. O atributo LOCAL_PREF só funciona dentro do seu AS. Por favor, não configure-o para anúncios através de sessões EBGP. É inútil, não funciona, não serve para coisa alguma, e deixa claro o quanto você não conhece do básico do BGP.
  6. Não configure o MED para anúncios entre sessões IBGP se a intenção for manipular o tráfego de entrada. Isto só funciona entre sessões EBGP e entre dois Sistemas Autônomos dual ou multi-homed. Saiba para que serve o MED e como isto funciona antes de querer usá-lo.
  7. O Weight (Cisco) não é um atributo. Não espere mesmo influenciar o ponto de saída para todo o seu AS usando o Weight numa policy para seus peers IBGP!
  8. "Toda vez que subo um trânsito X, o meu PTT sofre paralisação". Olhe o seu "umbigo" antes de subir um trânsito ou um peering. Não é uma questão apenas de configurar uma simples sessão!
  9. Compreenda e saiba identificar os tipos de situações que provocam indesejáveis e malditos Route Leaks, e como evitá-los: informe-se sobre o RFC 7908 (Problem Definition and Classification of BGP Route Leaks).
    1. Não repasse quaisquer rotas recebidas de uma sessão de trânsito para outra sessão de trânsito ou de peering. Pelo amor de Deus. N ã o f a ç a i s s o.
    2. Não repasse quaisquer rotas recebidas de uma sessão de peering para outra sessão de peering ou de trânsito. Pelo amor de Deus. N ã o f a ç a i s s o.
    3. Não gere como se fossem do seu ASN quaisquer prefixos que não sejam seus! Isto tipifica um sequestro de prefixo e não um route leak, mas os danos podem ser severos. Pelo amor de Deus. N ã o f a ç a i s s o.
    4. Não repasse para upstreams quaisquer prefixos que contenham um lista de AS_PATH irregular. Ou, melhor, rejeite o recebimento destes anúncios vindos de seu cone de clientes.
      1. Route Leaks provocados por isto são facilmente evitáveis nas políticas de import de rotas recebidas de clientes, além das garantias das suas policies de export com os upstreams. Não seja tolo!
  10. Repasse para o trânsito apenas rotas do seu AS e rotas de seus clientes. E descarte o repasse de todo o resto.
  11. Ao receber do trânsito, certifique-se de descartar martians, bogons, seus próprios blocos, e tudo aquilo tratado como "mazelas" da Internet. Não me diga que você não faz isso?
  12. Você não tem uma política de roteamento. Você tem um punhado de configurações com nomes de "policies" vinculadas nas sessões para o in e o out. Confesse!
  13. Você por acaso não cadastra os seus objetos no IRR, né? Você espera que realmente o seu upstream faça isso por você (a título de proxy). Você adora varrer poeira para debaixo do tapete dos outros, né? Seu malvadão!
  14. Você é fã do "IP Confinado" e/ou vende tráfego de CDN (ainda) descarada e impunemente: saiba que isto é uma prática ilegal. Você não pode: a) vender tráfego de CDN. b) promover comercialmente a prática disto. c) expor as logomarcas das CDNs no seu produto "IP confinado" em seu material comercial/publicitário. d) expor fotos dos servidores de CDN de seu datacenter na Internet e/ou redes sociais. Quem disse isso, o Leonardo Furtado? Não!
    1. Leia os contratos dos acordos e certifique-se do que pode ou não ser feito. A propósito, não existe um produto "IP Confinado" como vemos em muitos casos por aí que não seja uma gambiarra associada a uma clara violação de contratos.
    2. Não reclame quando você perder as suas CDNs ou quando for processado!
    3. Em suma: você pode vender produtos diferenciados tais como "Trânsito Parcial" e similares, repassando os anúncios dos seus clientes para as CDNs, mas não pode e não deve anunciar um produto tipo "vendo tráfego das CDNs X, Y e Z"'.
    4. O tráfego de CDN é um benefício para o ISP e seus assinantes e que reduz a latência nos acessos aos conteúdos e que também contribui para economizar bem no trânsito - principalmente o internacional. CDN é benefício e não produto de prateleira.

O que eu realmente preciso saber para ser considerado um expert em BGP?

Pedir a minha opinião quanto a isso é desejar receber uma resposta inusitada, mas bem humorada! Sendo honesto e humano com o leitor aqui, eu me contentaria muito se você ao menos puder sinalizar "fluência" nos seguintes temas, todos básicos:

Para ser um expert, domine o essencial e o efetivo primeiro!

  1. Conhecimentos sólidos de redes L2 e L3: o BGP, apesar de ser um protocolo de roteamento, comporta-se ou opera como se fosse uma aplicação. Muita coisa é requerida (L2/L3) para o seu funcionamento.
  2. Compreensão dos conceitos fundamentais do BGP: PDU/mensagens, FSM, conceitos de sessões, atributos, roteamento recursivo, processo de seleção dos melhores caminhos.
  3. Conhecimentos de boas práticas para a configuração do BGP: autenticação MD5, GTSM, limitação de prefixos recebidos, e afins.
  4. Conhecimentos básicos de filtros de rotas: saber o que filtrar no recebimento e o que filtrar no envio, no tocante a anúncios/prefixos.
  5. Conhecimentos básicos de como influenciar a seleção de caminhos in e out: quais atributos, métodos e procedimentos utilizar para manipular o download e o upload, e em quais circunstâncias.
  6. Conhecimentos sobre como manter uma política de roteamento básica: que seja apenas funcional, simples até, mas bem feita.
  7. Faça o seu dever de casa: nas questões associadas ao cadastros/registros no IRR e PeeringDB, além da segurança, filtros e policies.
  8. Compreensão sobre o essencial a respeito de interconexões e como estas devem funcionar: peering, trânsito, CDNs, e outros. O que são? Como funcionam? Pra que servem? O que comem? Como vivem?

O Comitê de Programa do BPF está engajado em disseminar conhecimentos acerca destes oito pontos acima. Fique atento a futuras publicações do BPF, e convocamos a sua contribuição também!

Não seja um "assassino de BGP"!

Uma coisa é compreender o BGP em sua forma mais acadêmica, e outra é saber conduzir ou "pilotar" o BGP corretamente em um Sistema Autônomo "pra valer"! Dentre os diversos absurdos que vemos por aí, posso citar alguns casos ou situações de coisas que realmente deixam a Internet estarrecida:

  1. Políticas de roteamento cujos os filtros são construídos com camada de validação minimalista: sem os devidos cuidados de validação da origem do prefixo por IRR e RPKI; o que dá margem para route leaks e hijacks.
  2. Provedores que em alguns casos repassaram rotas aprendidas a partir de uma sessão de trânsito para outras sessões de trânsito e/ou de peering: algo que provoca muitos distúrbios em muitos ASNs e seus clientes.
  3. Provedores que em alguns casos repassaram rotas aprendidas a partir de uma sessão de peering para outras sessões de peering e/ou de trânsito: outro tipo de route leak, com péssimas consequências para todos!
  4. Provedores que não validam a lista de ASNs indicada pelo atributo AS_PATH das rotas recebidas de sessões com o seu cone de clientes:
    1. Route leaks desta natureza são facilmente evitáveis com configurações simples nas políticas de importação de rotas vinculadas às sessões de clientes.
    2. Infelizmente BGPSEC (RFC 8205) e Route-Leak Protection (RLP) (draft-ietf-idr-route-leak-detection-mitigation-11) ainda não são uma realidade.
  5. Provedores que em alguns casos anunciaram prefixos indicando como origem destes o seu próprio ASN: sim, um sequestro de prefixos na cara-de-pau!
    1. Embora isto seja um "hijack" e não um route leak, as consequências são severas!
  6. Provedores que fornecem o mínimo de visibilidade para os demais ASNs e que não contribuem - nem um pouco - com transparência para a segurança da Internet:
    1. Sem quaisquer informações sobre a empresa, ferramentas e política de roteamento no PeeringDB, ou sem qualquer cadastro/registro no PeeringDB.
    2. Sem registros quaisquer de route/route6, as-set e aut-num nas bases de IRR.
      1. Ou com registros inconsistentes destes objetos, tais como a ausência de objetos route/route6 de prefixos mais específicos, as-sets, e regras RPSL de import/mp-import e export/mp-export em seus objetos aut-num, ou dados incorretos, etc.
    3. Que não disponibilizam quaisquer informações sobre as suas políticas de roteamento, seja na descrição do objeto aut-num, ou no PeeringDB, ou no website da empresa. Ou em qualquer lugar público e visível.
    4. Embora isto não seja um "crime", não está tão longe assim de ser: que diabos passa na cabeça de provedores que não disponibilizam ferramentas básicas para auxiliar de forma bem autônoma e independente outros Sistemas Autônomos no diagnóstico de problemas com o roteamento de/para aquele ASN. Por exemplo, não disponibilizam um LOOKING GLASS sequer! Isso é muito frustrante!
  7. Provedores que não removem os ASN privativos quando repassando os anúncios seus e/ou de seu cone de clientes para sessões de peering e trânsito.
  8. Provedores que injetam route leaks associados aos seus próprios prefixos ou prefixos de seus clientes.
  9. Provedores que repassam anúncios bogons, martians e unallocated para peering e trânsito.
  10. Provedores que não se preocupam nem um pouco em combater o principal vetor de ataques de DDoS contra todos os ASN na Internet: não buscam implementar mecanismos de anti-spoofing (ex: uRPF) de endereços IP de origem em suas próprias redes, incluindo o seu cone de clientes.
  11. Dentre outros absurdos.

Esses "profissionais" são que nem motoristas que dirigem alcoolizados: acham que suas ações altamente imprudentes não afetarão a vida de terceiros! Esses "bêbados da Internet" tendem a provocar distúrbios severos, impactando outros Sistemas Autônomos e milhares de usuários de Internet. Entenda: route leaks, prefix hijacks, anúncios bogons/martians/unallocated, dentre outros tipos de incidentes, causam distúrbios para grande parte da Internet, e não ficam restritos apenas no ASN do irresponsável. Reflita!

Para concluir: considerando as necessidades, objetivos, circunstâncias, realidades e situações dos dias atuais, eu, particularmente, considero inconcebível um profissional de redes lidar com o protocolo BGP em um ambiente de ISP sem que este indivíduo tenha no mínimo, além do próprio BGP, os conhecimentos de boas práticas de segurança necessários conforme descritos pelos seguintes:

  • RFC 4272 (BGP Security Vulnerabilities Analysis)
  • RFC 7132 (Threat Model for BGP Path Security)
  • RFC 7454 / BCP 194 (BGP Operations and Security)
  • BCP 38 (Network Ingress Filtering: Defeating Denial of Service Attacks which employ IP Source Address Spoofing)
  • RFC 7353 (Security Requirements for BGP Path Validation)
  • BCP 185 (Origin Validation Operation Based on the Resource Public Key Infrastructure (RPKI))
  • RFC 7908 (Problem Definition and Classification of BGP Route Leaks)
  • RFC 7948 (Internet Exchange BGP Route Server Operations)
  • RFC 7999 (BLACKHOLE Community)
  • E os arranjos de propostas e boas práticas citadas pelo Mutually Agreed Norms for Routing Security (MANRS)

Isto é o mínimo que se espera de um profissional que vá lidar como BGP nos dias atuais em ambientes Service Provider. Não duvide disto! Ou pague o preço.

Em nome do BPF, suplico: NÃO SEJA UM "BGP KILLER"!

Não seja um "BGP KILLER": faça a sua parte para uma Internet segura, rápida, e bem disponível!

Avance os seus conhecimentos para o último degrau!

Alguns projetos com o BGP podem ser extremamente complexos no ponto de vista de objetivos e concepções! Felizmente as arquiteturas de roteadores sofisticados oferecem uma gama enorme de recursos e facilidades, muitas delas de natureza proprietária, mas também muitas coisas orientadas aos padrões abertos. Não raramente engenheiros de rede se vêem forçados a intervir com alguma facilidade/recurso para fazer a coisa funcionar do jeito que deve. Fornecerei alguns exemplos de recursos relacionados aos serviços de roteamento unicast apenas!

Estude estas tecnologias, estes recursos, procure se interessar melhor pelas arquiteturas de roteadores, faça cursos, leia os manuais, etc.! Não fique limitado apenas ao que está mencionado abaixo. Procure em primeiro momento compreender o que você precisa fazer para depois estudar qual recurso promove aderência e para qual objetivo ou necessidade.

BGP Dual-homed e Dual Multihomed em cenário Primary/Backup e em cenário Load sharing BGP FlowSpec BGP Dual AS e AS Number Translation
BGP 4-byte AS (AS4_AGGREGATOR e AS4_PATH) e coexistência com 2-byte AS IBGP Full Mesh e Peer Groups / Neighbor Groups / Session Groups / Address Family Groups e similares IBGP com Route Reflectors e Confederation
EBGP Multihop EBGP Multipath e Load Sharing EBGP TTL Security Check
BGP DMZ Aggregate Bandwidth ou recurso similar suportado pelo seu fabricante BGP MD5 Authentication Redistribuição de Rotas de/para o BGP
Agregação de Rotas BGP por Static e por Atomic Aggregate BGP Conditional Route Injection Aggregate com ferramentas tais como suppress-map, AS-set e attribute-map, ou equivalentes suportados em seu equipamento
BGP Soft Reconfiguration Inbound, Route Refresh, Enhanced Route Refresh e ORF Manipulação de tráfego de saída com Local Preference (e/ou Weight, proprietário) Manipulação de tráfego de entrada com MED, deterministic-MED, always-compare-MED
Manipulação de tráfego de entrada com AS-path Prepending Alteração do BGP bestpath compare-routerid e as-path Implementação de Communities no BGP, Route Tagging e ferramentas periféricas
Filtros de rotas in e out por prefixos e atributos BGP Cost Community BGP NEXT_HOP Tracking ou recurso similar suportado no seu equipamento
BGP Route Dampening BGP Prefix Independent Convergence (PIC) para RIB e FIB BGP-RIB Feedback Mechanism
BGP Routing Domain Confederation QoS Policy Propagation via BGP (QPPB) ou similar Remotely Triggered Blackhole Filtering (RTBH)
BGP Nonstop Routing (NSR) e Nonstop Forwarding (NSF) BGP Additional Paths, iBGP Multipath Load Sharing, BGP Selective Multipath Accumulated Interior Gateway Protocol Attribute (AIGP)
IPv4 BGP Policy Accounting BFD Multihop Support para BGP BGP Accept Own
BGP Multi-Instance e Multi-AS BGP Prefix Origin Validation baseado no RPKI Etc.! a lista é quase que interminável!

Impressionado com o tamanho do artigo? Eu disse que seria aquilo que eu considero como básico/fundamental - PORQUE DE FATO É! - e não afirmei em momento algum que o texto seria minimalista ou fácil! Eu alertei!!!

Espero que tenha curtido este artigo. E nos vemos no próximo. Até!!

Autor: Leonardo Furtado