sexta-feira, 20 de julho de 2007

CEF load-sharing

Existem basicamente duas formas de fazer o balanceamento de tráfego utilizando o CEF (Cisco Express Forwarding): per-packet ou per-destination. Enquanto o balanceamento per-packet é utilizado para balancear igualmente dois links, a principal vantagem de balancear utilizando a configuração per-destination é que o tráfego de aplicações sensíveis a jitter (por exemplo Voz sobre IP) não corre o risco de ter alguns de seus pacotes com maior delay do que outros, o que pode acontecer quando o delay de um caminho é maior do que o delay do outro caminho. A solução que promete resolver alguns destes problemas é utilizar o balanceamento per-port, ou seja, é possível distribuir mais igualmente o tráfego entre os caminhos redundantes sem perda de qualidade para aplicações como VoIP.

Em sua configuração padrão, o Cisco IOS com CEF habilitado trabalha com balanceamento por destino (per-destination) para dois caminhos que tenham a mesma métrica. Para habilitar o balanceamento por pacote, temos que entrar com o comando "ip load-sharing per-packet" nas interfaces de destino do caminho redundante; por exemplo, se a rede 10.10.10.0/24 pode ser alcançada pelas interfaces FastEthernet0/0 e Serial0/0, então devemos entrar com o comando nas interfaces:

Cisco(config)# int fa0/0
Cisco(config-if)# ip load-sharing per-packet
Cisco(config-if)# int ser0/0
Cisco(config-if)# ip load-sharing per-packet
Para verificar o resultado destas alterações, podemos utilizar o comando abaixo ou ainda o "show ip cef 10.10.10.1 internal". Para mais detalhes, consultar a documentação oficial da Cisco para troubleshooting de caminhos redundantes utilizando o CEF.
Cisco#show ip cef 10.10.10.1 detail
10.10.10.0/24 version 7920, per-packet sharing
0 packets, 0 bytes
via 10.2.2.2, FastEthernet0/0, 0 dependencies
traffic share 1, current path
next hop 10.2.2.2, FastEthernet0/0
valid adjacency
via 10.1.1.1, Serial0/0, 0 dependencies
traffic share 1
next hop 10.1.1.1, Serial0/0
valid adjacency
0 packets, 0 bytes switched through the prefix
tmstats: external 0 packets, 0 bytes
internal 0 packets, 0 bytes
A partir da versão 12.4(11)T do IOS, a Cisco incluiu o suporte a Per-port CEF load-sharing, ou seja, a função hash para balanceamento de carga utilizando CEF pode utilizar as informações de número de porta TCP ou UDP (camada 4) para determinar o rota.

Para habilitar o balanceamento per-port, deve-se utilizar o comando:
Cisco(config)# ip cef load-sharing algorithm include-ports source destination
E para verificar o caminho escolhido:
Cisco# show ip cef exact-route 10.0.0.10 src-port 35 192.168.0.2 dest-port 80
Para saber mais detalhes sobre esta nova feature basta consultar a documentação da versão 12.4 T aqui.

terça-feira, 17 de julho de 2007

Paper: Fast-Flux Service Networks

No último dia 13 deste mês o projeto Honeynet publicou um white-paper com um estudo sobre a utilização de "Fast-Flux Service Networks", uma tecnologia utilizada por criminosos para ocultar suas atividades na Internet. O documento apresenta um detalhamento muito bom da arquitetura single-flux e double-flux, das principais vantagens para os criminosos que se utilizam da mesma e um estudo de caso de como ele acontece no mundo real, além de detalhes de métodos de detecção.

Know Your Enemy: Fast-Flux Service Networks - 15 July, 2007

Cisco PPPoE Client

Pode-se utilizar um link ADSL e um roteador Cisco da série 800 para combinar uma solução de baixo custo para acesso à Internet. Um dos modos de configurar um ambiente deste tipo é com a utilização de um modem ADSL configurado para atuar em modo bridge ou mesmo um roteador que tenha suporte ADSL e utilizar a configuração de bridge-group entre a interface ATM e Ethernet.

Para este exemplo, utilizamos o cenário abaixo com um modem (modo bridge) e um roteador Cisco 831.

Para fazer a configuração do roteador é necessário configurar uma interface dialer para tratar a conexão ADSL, habilitar vpdn e configurar a interface ethernet 0 para trabalhar como PPPoE.

! configuração do vpdn
vpdn enable

! configuração da interface conectada ao modem ADSL
interface Ethernet0
no ip address
no ip proxy-arp
ip virtual-reassembly
pppoe enable
pppoe-client dial-pool-number 1
no cdp enable

interface Dialer1
ip address negotiated
ip virtual-reassembly
encapsulation ppp
dialer pool 1
dialer-group 1
no cdp enable
! para autenticação via PPP chap
ppp chap hostname user@provedor
ppp chap password 7
! ou para autenticação PPP pap
ppp pap sent-username user@provedor password 7

! rota default
ip route 0.0.0.0 0.0.0.0 Dialer1

dialer-list 1 protocol ip permit
Vale lembrar que muitas vezes é necessário ajustar o valor do MSS do cabeçalho TCP para que este tipo de conexão funcione adequadamente, como já havia comentado no post "Cisco, DSL, PPPoE e o MTU". Para troubleshooting deste ambiente, fica a sugestão de executar o comando de verificação "show pppoe session all" para verificar se os endereços MAC foram aprendidos pelo Cisco e, caso positivo, verificar com o "debup ppp authentication" o processo de autenticação ADSL.

cisco#sh pppoe session all
Total PPPoE sessions 1

session id: 45316
local MAC address: 0016.c7ee.f8cc, remote MAC address: 0004.3daa.aafb
virtual access interface: Vi1, outgoing interface: Et0
286832 packets sent, 365434 received
17806173 bytes sent, 357739263 received

Cisco Replace e Rollback

A partir da versão 12.3(7)T ou 12.2(25)S não é necessário fazer todo o processo de boot para reverter para a configuração que está gravada na startup-config, basta utilizar a feature "Configuration Replace and Configuration Rollback". A idéia é muito simples: se houver algum problema enquanto estivermos aplicando as novas configurações, é possível reverter a configuração para, por exemplo, aquela que está salva na nvram. É possível também salvar várias versões de uma configuração e carregá-las quando for necessário. Primeiramente, vamos ver um exemplo:

cisco# configure terminal
cisco(config)#interface loopback 0
cisco(config-if)#ip address 10.10.10.10 255.255.255.255
Se não foi satisfatória essa alteração, então podemos carregar novamente a configuração que está gravada na startup-config diretamente para a running-config.
cisco#configure replace nvram:startup-config list
This will apply all necessary additions and deletions
to replace the current running configuration with the
contents of the specified configuration file, which is
assumed to be a complete configuration, not a partial
configuration. Enter Y if you are sure you want to proceed. ? [no]: yes
!Pass 1

!List of Commands:
no interface Loopback0
end


Total number of passes: 1
Rollback Done
cisco#
Até agora, nenhuma novidade. No entanto, podemos combinar o configure replace com o archive, ou seja, podemos armazenar várias versões diferentes de configuração e utilizá-las com o configure replace.
cisco(config)#archive
cisco(config-archive)#maximum 5
cisco(config-archive)#path flash:myconfig
Ou seja, agora podemos ter 5 arquivos de backup que serão gravados na memória flash com o prefixo "myconfig".
cisco#archive config

cisco#sh archive
There are currently 2 archive configurations saved.
The next archive file will be named flash:myconfig-2
Archive # Name
0
1 flash:myconfig-1 <- Most Recent
2
3
4
5
(...)

Agora podemos utilizar o comando "archive config" para gravar e "configure replace" para carregar versões de configuração.
cisco#configure replace flash:myconfig-1 list time 120
This will apply all necessary additions and deletions
to replace the current running configuration with the
contents of the specified configuration file, which is
assumed to be a complete configuration, not a partial
configuration. Enter Y if you are sure you want to proceed. ? [no]: yes
!Pass 1

!List of Commands:
no interface Loopback0
end


Total number of passes: 1
Rollback Done

cisco# configure confirm
Neste último exemplo, utilizamos a opção time no comando configure replace para que se não houver a confirmação (configure confirm) então o IOS irá reverter automaticamente para a última configuração antes do replace após transcorridos 2 minutos (120 segundos).

segunda-feira, 16 de julho de 2007

Cisco PIX e TFTP

Apesar de ter uma interface muito parecida com o IOS, a configuração dos firewalls da Cisco (os famosos Cisco PIX) é em alguns casos muito diferente do IOS utilizado nos roteadores. Por exemplo, quando é necessário copiar uma configuração de um firewall para um servidor tftp e restaurar este backup em um outro firewall os comandos "copy runn tftp" e "copy tftp runn" não estão disponíveis no PIX.

Para fazer o backup da configuração atual de um firewall Cisco PIX (neste exemplo na versão 6.3(5)) para um servidor de tftp, devemos utilizar o comando:

pix1# write net 10.10.10.10:arquivo.cfg
Onde 10.10.10.10 é o endereço IP do servidor tftp e arquivo.cfg é o nome do arquivo que será criado com o backup da configuração.

O processo inverso é um pouco menos trivial e, para isso, devemos utilizar o comando configure dentro da opção de configuração:
pix2# configure terminal
pix2(config)# configure net 10.10.10.10:arquivo.cfg
Após entrar com o comando acima a configuração que foi salva no servidor de tftp será carregada no segundo pix.

quarta-feira, 11 de julho de 2007

Kerberos: No default realm defined for Kerberos!

Para evitar a mensagem do título do post ao tentar conectar em algum equipamento utilizando o usuário utilizado pelo Rancid, coloque a seguinte linha no arquivo .telnetrc do usuário:

#su - rancid
$echo "default unset autologin" > ~/.telnetrc

quarta-feira, 4 de julho de 2007

tcpdump

Quando falamos em sniffers de rede - programas que colocam uma interface de rede em modo promíscuo, capturam o tráfego e mostram para o usuário em um formato amigável -, certamente devemos lembrar do tcpdump. Este software permite a utilização de filtros para capturar somente aqueles pacotes que estamos buscando dentre os milhares de pacotes que trafegam por uma ou outra interface de rede. Neste post tentarei apresentar um pouco como é trabalhar com um sniffer. Antes de mais nada é necessário saber os argumentos mais comuns e o formato do comando:

Para capturar o tráfego da interface eth0 (-i) e não resolver o reverso dos endereços IP (-n); opção que ajuda bastante na velocidade da captura. Capturar até 1500 bytes dos pacotes (-s) ao invés dos 68 bytes capturados na opção padrão. Capturar somente 1000 pacotes (-c) e gravar em um arquivo (-w) chamado file.cap, utilizamos o exemplo abaixo.

root@server# tcpdump -i eth0 -n -s 1500 -c 1000 -w file.cap
A opção -r deve ser utilizada posteriormente para ler o arquivo file.cap. Ou seja, a sintaxe padrão do tcpdump é:
root@server# tcpdump [ opções ] [ expressão ]

E é na parte de expressões que estou interessado hoje. Estas expressões são definidas por palavras reservadas e operadores lógicos para selecionar um determinado tráfego de rede. As principais palavras reservadas são:

- Tipo: host, net, port, ...
- Protocolo: ether, ip, tcp, udp, arp, rarp, ...
- Direção: src, dst, src and dst, src or dst, ...
- Operadores lógicos: and, or, not.

Podemos então montar um filtro para selecionar os pacotes com origem na rede 10.10.10.0/24 e com destino o servidor 192.168.0.1 na porta 80.
root@server# tcpdump -ni eth0 'src net 10.10.10.0/24 and dst host 192.168.0.1 and dst port 80'

Se estivermos em busca dos pacotes de início de uma conexão: pacotes com a flag SYN marcada no cabeçalho do TCP, então podemos utilizar a seguinte combinação:
root@server# tcpdump -ni eth0 'tcp[13] == 2'
Ou seja, o tcpdump irá selecionar somente os pacotes que tiverem o valor 2 (decimal) no décimo terceiro byte do cabeçalho TCP. Se lembrarmos das lições de redes de computadores, sabemos que o décimo terceiro byte do cabeçalho TCP é o byte reservado para as flags do protocolo e o valor 2 em decimal é a representação de 00000010 em binário. Lembre-se também da ordem das flags no cabeçalho: os dois primeiros bits são reservados e os seguintes são URG, ACK, PSH, RST, SYN e FIN. Ou seja, somente o penúltimo bit possui o valor 1 para os pacotes que carregam somente a flag SYN.

Este processo pode também ser utilizado para o protocolo ICMP, como no exemplo abaixo. Para mais detalhes sobre os tipos e códigos do protocolo ICMP consultar o documento oficial da IANA.
root@server# tcpdump -ni en1 'icmp[icmptype]==8'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
23:55:33.232659 IP 192.168.0.x > 200.192.y.x: ICMP echo request, id 52993, seq 0, length 64
As possibilidades de combinação são grandes, já que podemos também utilizar operadores lógicos bit-a-bit para selecionar o tráfego, mas este tipo de filtro vou deixar a cargo do leitor pesquisar. Podemos também utilizar estes filtros para fazer assinaturas de ataques e detectar estes ataques somente com a utilização do tcpdump. Existem dois documentos da SANS que auxiliam na utilização do tcpdump para IPv4 e IPv6. Ou ainda a man page oficial do tcpdump.

Cisco, DSL, PPPoE e o MTU

Depois de configurar um roteador Cisco para autenticar-se em um provedor utilizando PPPoE (mais tarde colocarei como fazer isso aqui também) muita gente pode não conseguir navegar "na Internet". A possível, e mais provável, causa desse problema é a limitação do tamanho máximo do MRU (maximum-receive-unit) definido no RFC2516 como 1492 bytes. Como o MTU (maximum transmission unit) dos segmentos ethernet é geralmente configurado para 1500 bytes, um pacote padrão ethernet não irá trafegar no enlace PPPoE, ou seja, entre o CPE (customer premises equipement) e o aggregator (equipamento do provedor que faz a terminação da conexão PPPoE, também conhecido como BRAS - Broadband Remote Access Server). Para mais detalhes da arquitetura do xDSL/PPPoE consultar este documento.

Dessa forma, mesmo que suas requisições consigam atravessar da sua rede interna para a Internet passando pelo seu enlace PPPoE (MTU menor que 1492 bytes) é muito provável que as respostas às suas requisições voltem em pacotes maiores que este tamanho e o equipamento aggregator da sua operadora irá descartar as respostas, montar e enviar pacotes ICMP informando a origem (neste caso o servidor) que os pacotes excederam o tamanho máximo permitido no segmento. Se o administrador do Firewall (antes do servidor) ou o administrador do próprio servidor configurou um bloqueio para todas as mensagens ICMP com destino o servidor, então a conexão não irá funcionar, pois o servidor não saberá que deve ajustar o tamanho dos pacotes para que os mesmos não sejam descartados no seu caminho de volta.

Para contornar este problema nos roteadores Cisco, existe um comando que pode ser utilizado para ajustar o campo MSS (maximum segment size) do cabeçalho TCP, permitindo que o servidor seja informado do tamanho máximo (MTU) das mensagens aceitas para determinado segmento. Para isso, devemos utilizar o comando "ip tcp adjust-mss 1492" na interface interna da rede.

Router(config)# interface fast 0
Router(config-if)# ip address 192.168.0.1 255.255.255.0
Router(config-if)# ip tcp adjust-mss 1452

Fica a lição de como contornar o problema e, principalmente, de como é importante entender cada tipo de mensagem do protocolo ICMP. Para mais detalhes sobre este problema, consulte este documento da Cisco. Mais detalhes também podem ser encontrados no RFC4638 (Accommodating a Maximum Transit Unit/Maximum Receive Unit (MTU/MRU) Greater Than 1492 in the Point-to-Point Protocol over Ethernet (PPPoE)) que mostra uma tentativa de padronizar um mecanismo para diminuir o impacto desta limitação nas novas redes banda larga.