Netkit2

De MediaWiki do Campus São José
Revisão de 18h12min de 1 de agosto de 2014 por Msobral (discussão | contribs)
Ir para: navegação, pesquisa

Índice

Introdução

Netkit é um ambiente para experimentos com redes de computadores desenvolvido na Unversidade de Roma, na Itália. Com ele torna-se possível realizar experimentos sobre configuração básica de rede, roteamento, criação de infraestrutura WAN com MPLS, além de dispor de diversos serviços de rede (DNS, WWW, LDAP, e outros). Ele se compõe de máquinas virtuais Linux (implementadas com kernel Linux UML – User Mode Linux), que funcionam como roteadores ou computadores, e switches Ethernet virtuais (UML switch) para interligar as máquinas virtuais. Para todos os efeitos, cada máquina virtual funciona como se fosse um computador real, possuindo uma ou mais interfaces de rede. Com esses recursos é possível criar redes de configurações arbitrárias para estudar protocolos de comunicação e serviços de rede.

A versão do Netkit apresentada neste artigo é fruto de modificações realizadas pelo Núcleo de Telecomunicações do IF-SC (campus São José). Ela possui muitas diferenças em relação ao Netkit original, dentre elas:

  • A definição de tipos de equipamentos a serem usados no experimento, tais como roteadores, switches, e computadores de uso geral: cada máquina virtual pode assim ser especializada para facilitar sua configuração.
  • A possibilidade de definir diversos parâmetros de configuração de rede (ex: endereços de interfaces, rotas, VLANs, ...) diretamente no arquivo de configuração de um experimento.
  • A possibilidade de criar enlaces ponto-a-ponto via links seriais virtuais, que podem ter configurados suas taxas de bits, taxas de erro (BER) e atraso de propagação.
  • Uma interface gráfica para a execução de experimentos. Esse aplicativo concentra as telas de terminal das máquinas virtuais e provê diversas funções auxiliares para ajudar na realização dos experimentos. A figura abaixo mostra um exemplo dessa interface em ação:


Netkit-vlsm1.png


As próximas seções explicam como instalar o Netkit, e como criar e executar experimentos.

Sistemas Operacionais compatíveis

Sistema operacional Compatível Incompatível
Debian 6 Squeeze X
Debian 7 Wheezy X
Ubuntu 10.04 Lucid Lynx LTS X
Ubuntu 10.10 Maverick Meerkat X
Ubuntu 11.04 Natty Narwhal X
Ubuntu 11.10 Oneiric Ocelot X
Ubuntu 12.04 Precise Pangolin LTS X
Ubuntu 13.04 Raring Ringtail X
Ubuntu 14.04 Trusty Tahr LTS X

OBS: A versão utilizada nos laboratório é o Ubuntu 12.04 LTS

OBS2: No Ubuntu 14.04 LTS, recomenda-se desabilitar o menu global da interface Unity. Basta usar o aplicativo dconf-editor e nele adicionar o gnome-netkit a com -> canonical -> unity-gtk-module -> blacklist (maiores detalhes)

Instalação

A instalação pode ser feita de forma automática ou manual. Em ambos os casos, é necessário haver 1,5 GB livre em seu disco.

O Netkit foi criado para rodar em sistemas operacionais de 32 bits. Mas ele pode ser usado também em sistemas de 64 bits. Nesse caso, devem-se instalar os seguintes pacotes de software (instale-os com apt-get):

sudo apt-get install ia32-libs libc6-i386

Tanto para sistemas de 32 ou 64 bits, são necessários os seguintes pacotes de software para o correto funcionamento do Netkit:

sudo apt-get install graphviz python-vte bridge-utils uml-utilities

Após instalado, o Netkit pode ser atualizado executando-se gnome-netkit e usando o menu General->Update.

Instalação automática (recomendada)

OBS: o instalador assume que a instalação será feita em um sistema operacional Ubuntu 10.04 ou superior, 
e que o usuário use o shell Bash (/bin/bash).


Obtenha o instalador do Netkit e salve-o no disco de seu computador. Execute-o da seguinte forma em uma janela de terminal (acessível por Aplicativos->Acessórios->Terminal):

python netkit-installer

O instalador será iniciado e apresentará a seguinte tela:

Netkit-installer.png

Normalmente deve-se usar a opção Install from Network, que faz o download do arquivo de instalação e o instala. Note que esse arquivo de instalação possui pouco mais de 300 MB, e pode demorar para ser copiado pela rede. A opção Install from File pode ser usada se o arquivo de instalação já estiver em seu disco.


O instalador realiza automaticamente os procedimentos descritos na seção Instalação manual.


Ao final da instalação, o gnome-netkit poderá ser iniciado pelo menu Aplicativos/Educacional/Gnome-Netkit:


Netkit-entry.png

Instalação manual

Para instalar o Netkit, deve-se obter o arquivo compactado netkit-rco2.tar.bz2 (330 MB):

  • Cópia no servidor de Tele (atualizada em 30/11/2011)
  • … ou traga um pendrive com 500 MB livres, um CD-R ou um DVD-R
  • OBS: quem já tinha copiado o Netkit antes de 30/11/2011 precisa baixar uma atualização:
    • Obtenha o arquivo netkit-update.tgz.
    • Descompacte-o NO MESMO DIRETÓRIO ONDE FOI INSTALADO O NETKIT. Ex: se você instalou o Netkit em /home/aluno/netkit, descompacte netkit-update.tgz nesse mesmo diretório. O seguinte comando faz a instalação correta dessa atualização:
      tar xCzf $NETKIT_HOME netkit-update.tgz
      
  • OBS 2: As próximas atualizações do gnome-netkit podem ser instaladas automaticamente usando o menu General->Update


O Netkit foi intensamente modificado em relação à distribuição original do projeto para possibilitar uma sintaxe mais rica para a configuração de experimentos. A nova sintaxe é orientada a componentes de rede, tais como computadores, gateways, switches e roteadores, gerando máquinas virtuais previamente configuradas de acordo com seu papel na rede. Outra melhoria foi a possibilidade de criar enlaces ponto-a-ponto entre máquinas virtuais usando interfaces seriais. Esses enlaces emulam a comunicação via portas seriais, e neles é possível usar um protocolo de enlace ponto-a-ponto (ex: PPP).

Você precisa de um computador com Linux, para onde deve copiar os arquivos acima. Não é necessário ter privilégio de superusuário para instalar o Netkit, tampouco para executá-lo. Aliás, NÃO EXECUTE O NETKIT COMO SUPERUSUÁRIO !!!

Após copiar o arquivo netkit-rco2.tar.bz2 para seu computador, descompacte-o dentro de um subdiretório à sua escolha. Em seguida edite o arquivo ~/.profile (que contém a configuração do seu shell), e acrescente as seguintes definições de variáveis de ambiente:

export NETKIT_HOME=/home/aluno/netkit 
export MANPATH=$NETKIT_HOME/man:$MANPATH
export PATH=$NETKIT_HOME/bin:$PATH

Obs: no exemplo acima foi assumido que o Netkit foi instalado em /home/aluno/netkit (quer dizer, você descompactou os arquivos dentro de /home/aluno). Caso tenha instalado em outro diretório você deve corrigir a definição da variável de ambiente NETKIT_HOME.

Cinco softwares adicionais são necessários no Ubuntu, os quais devem ser instalados da seguinte forma:

apt-get install python-vte python-gtk2 graphviz bridge-utils uml-utilities

Antes de tentar executar um experimento, teste se a instalação teve sucesso. Para isso faça o seguinte:

. ~/.profile
cd $NETKIT_HOME
./check_configuration.sh

O resultado deve ser o seguinte:

>  Checking path correctness... passed.
>  Checking environment... passed.
>  Checking for availability of man pages... passed.
>  Checking for proper directories in the PATH... passed.
>  Checking for availability of auxiliary tools:
	awk          : ok
	basename     : ok
	date         : ok
	dirname      : ok
	find         : ok
	getopt       : ok
	grep         : ok
	head         : ok
	id           : ok
	kill         : ok
	ls           : ok
	lsof         : ok
	ps           : ok
	readlink     : ok
	wc           : ok
	port-helper  : ok
	tunctl       : ok
	uml_mconsole : ok
	uml_switch   : ok
passed.
>  Checking for availability of terminal emulator applications:
	xterm          : found
	konsole        : found
	gnome-terminal : found
passed.

[ READY ] Congratulations! Your Netkit setup is now complete!
          Enjoy Netkit!

Ao menos uma das opções de terminal deve funcionar (xterm, konsole ou gnome-terminal). Assim, se aparecer que alguma delas falhou não há problema, contanto que ao menos uma tenha dado certo. Assim, se aparecer algo parecido com isto não tem problema:

>  Checking for availability of terminal emulator applications:
	xterm          : found
	konsole        : not found
	gnome-terminal : not found
passed.

Ajustes finais

Alguns ajustes precisam ser feitos manualmente. Em particular, deve-se editar o arquivo sudoers para que o gnome-netkit tenha permissão de executar alguns comandos. Use o programa visudo para adicionar estes comandos ao sudoers (substitua ${NETKIT_HOME} pelo diretório onde o Netkit foi instalado):

  • ${NETKIT_HOME}/bin/manage_tuntap
  • ${NETKIT_HOME}/bin/vclean


Testando a instalação

Para estrear seu Netkit você pode baixar o arquivo lab1.tar.gz, que descreve um experimento, e descompactá-lo. Ao ser descompactado surge um subdiretório lab1 dentro de que há as configurações do experimento. Para rodá-lo siga estes passos:

  1. Execute . ~/.profile . Isto será necessário somente desta vez, pois das próximas vezes que iniciar o computador as configurações de ambiente do Netkit serão automaticamente carregadas.
  2. Execute gnome-netkit. Deve aparecer a tela abaixo:

    Screenshot-gnome-netkit.png

  3. Na tela do gnome-netkit clique em File->Load and Run. Em seguida escolha o arquivo de configuração de experimento lab1/Lab.conf.
  4. Após selecionar o arquivo de configuração, o experimento é automaticamente iniciado. A tela do gnome-netkit mostra o terminal (contendo um shell) de uma das máquinas virtuais. Para selecionar outra máquina virtual basta clicar no botão corresponde (logo abaixo da tela do terminal, como se pode ver abaixo).

    Screenshot-gnome-netkit-1.png

  5. Clique em File->Graph para visualizar um diagrama da topologia da rede em execução.

    Screenshot-gnome-netkit-2.png

O experimento de exemplo contém a seguinte rede:

Netkit-lab1.png

Experimente a comunicação entre os computadores dessa rede, usando o comando ping. Investigue também que interfaces de rede existem em cada um deles, usando o comando ifconfig. Veja que rotas estáticas foram definidas usando o comando netstat -rn. Finalmente, para visualizar o tráfego experimente selecionar o ítem de menu Wireshark->any e em seguida fazer ping entre os computadores.

O menu do gnome-netkit

Os ítens de menu do gnome-netkit tem as seguintes funções:

Menu File:

  • Load Only: carrega um arquivo de configuração de experimento, mas não o executa. Se um experimento já tiver sido carregado e estiver em execução, primeiro ele será terminado.
  • Load and Run: carrega um arquivo de configuração de experimento e o executa imediatamente. Se um experimento já tiver sido carregado e estiver em execução, primeiro ele será terminado.
  • Export: exporta um projeto do Netkit, o qual contém o arquivo de configuração (extensão .conf) e arquivos preservados das máquinas virtuais. Ver maiores detalhes na seção sobre Projetos do Netkit.
  • Import from folder: importa um projeto do Netkit contido em um subdiretório. Ver maiores detalhes na seção sobre Projetos do Netkit.
  • Import from file: importa um projeto do Netkit contido em um arquivo compactado. Ver maiores detalhes na seção sobre Projetos do Netkit.
  • Edit: abre o editor de texto gedit para poder editar a configuração do experimento.
  • Graph: mostra/esconde um diagrama da topologia da rede
  • Clear: para o experimento e mostra a tela inicial do gnome-netkit
  • Quit: termina o experimento e encerra o gnome-netkit.


Menu Network:

  • Start ou Restart:
    • Start: inicia um experimento cujo arquivo de configuração foi carregado mais ainda não executado (i.e. usando File->Load Only). Se o arquivo de configuração tiver sido modificado desde o instante em que foi carregado, será novamente lido antes de ser executado.
    • Restart: reinicia um experimento que já esteja em execução, recarregando seu arquivo de configuração caso tenha sido modificado.
  • Stop: termina um experimento, parando todas suas máquinas virtuais.
  • Reload: recarrega o arquivo de configuração do experimento corrente, caso tenha sido modificado. Se o experimento estiver em execução, termina-o primeiro.

Menu Wireshark:

  • Cada ítem deste menu mostra o nome de uma interface de rede da máquina virtual selecionada. O ítem any representa todas as interfaces de rede. Ao selecionar um desses ítens, um processo de captura de pacotes é acionado na máquina virtual selecionada. Em seguida é executado o Wireshark para visualizar o tráfego coletado.


Menu General:

  • Help: abre uma página de ajuda do Netkit.
  • About: mostra uma tela com informações gerais sobre o gnome-netkit.
  • Update: atualiza para a nova versão do gnome-netkit.
  • Package Install Mode: ativa o modo de instalação de software, em que uma única máquina virtual é executada e com acesso em modo leitura-escrita ao sistema de arquivos. Softwares e modificações feitas em arquivos nesse modo de execução serão permanentes.
  • Restart gnome-netkit: reinicia o gnome-netkit (neccessário após a atualização de versão).
  • Preferences: possibilita modificar algumas opções de execução de experimentos, tais como diretório de trabalho (default: diretório atual), quantidade de máquinas virtuais que podem ser iniciadas simultaneamente, e quantidade de memória alocada a cada máquina virtual.


A próxima seção descreve em detalhes como configurar um experimento do Netkit.

Criação de experimentos

Para criar um experimento do Netkit, deve-se escrever um arquivo de configuração com extensão .conf (sugestão: Lab.conf). Esse arquivo deve conter a configuração da rede do seu experimento. Nele devem-se identificar os atributos globais do experimento, as máquinas virtuais que compõem a rede, seus tipos e como se conectam suas interfaces de rede. O tipo de máquina virtual diz respeito ao seu papel na rede, que pode ser:

  • generic: uma máquina virtual comum, e que pode representar um computador sem nada de especial.
  • gateway: possui as capacidades de generic, e adiciona a função de gateway. Isto é, esse tipo de máquina virtual encaminha datagramas IP entre suas interfaces de rede.
  • pppoe: especializa gateway para adicionar a capacidade de estabelecer enlaces PPPoE (i.e. criar um AC PPPoE).
  • router: estende o tipo pppoe de forma a operar como um roteador. Usa o programa Quagga que implementa os protocolos de roteamento RIP, OSPF e BGP. Apresenta uma interface semelhante ao terminal de um roteador Cisco.
  • mpls: estende o tipo router, possibilitando criar um switch MPLS rudimentar. Com ele se podem criar LSP (circuitos-virtuais) estáticos e túneis.
  • switch: estende o tipo generic para criar um switch Ethernet com suporte a VLANs IEEE 802.1q, enlaces agregados IEEE 802.1ax, protocolo STP segundo a norma IEEE 802.1d e controle de acesso IEEE 802.1x.
  • pbx: estende o tipo generic para criar um PBX IP baseado em Asterisk.


O diagrama abaixo mostra a hierarquia dos tipos de componentes de rede ora definidos:

Netkit-tipos.png

Máquinas genéricas (computadores simples)

Máquinas genéricas são computadores que possuem uma ou mais interfaces de rede. No Netkit eles foram definidos para representar computadores de usuários ou servidores.

No exemplo abaixo duas máquinas genéricas, pc1 e pc2, têm suas interfaces ethernet eth0 conectadas à mesma rede local.

# Primeiro devem-se definir os tipos de maquinas virtuais do experimento. 
# Um computador Linux genérico é do tipo "generic":
# nome_vm[type]=generic

pc1[type]=generic
pc2[type]=generic

# Em seguida podem-se definir as interfaces de rede Ethernet: 
# nome_vm[nome_interface]=nome_rede_local:ip=IP/MASCARA

pc1[eth0]=lan0:ip=192.168.0.1/24
pc2[eth0]=lan0:ip=192.168.0.2/24

A rede resultante é:

Netkit-lab1.png

Para ver esse experimento em ação, copie o conteúdo acima para um arquivo (ex: Lab.conf). Em seguida execute o gnome-netkit e clique o botão Load para carregar esse arquivo de configuração. Assim que tiver concluído o início do experimento, você deve poder acessar as máquinas virtuais pc1 e pc2. Ambas possuem suas interfaces de rede eth0 configuradas com os endereços IP informados em Lab.conf. A figura abaixo mostra a tela do gnome-netkit com as máquinas virtuais:

Screenshot-gnome-netkit-4.png

Quando uma máquina virtual é iniciada, suas interfaces de rede precisam ser configuradas. Além disso, outros comandos podem ser necessários para prepará-la para o experimento, tais como criação de rotas estáticas ou inicialização de serviços de rede. Esses comandos adicionais podem ser adicionados ao arquivo nome_vm.startup (ex: para a máquina virtual pc1 o arquivo deve se chamar pc1.startup). No entanto, algumas opções de configuração mais comuns (como endereços IP de interfaces) podem ser feitas diretamente no arquivo de configuração Lab.conf. Assim, o próprio gnome-netkit configura automaticamente as máquinas virtuais quando inicia um experimento. Se houver necessidade de editar manualmente os arquivos nome_vm.startup, adicione seus comandos depois da linha:

/hostlab/nome_vm-auto.sh

Interligando interfaces de rede

No exemplo anterior, os dois computadores tiveram suas interfaces de rede interligadas. No Netkit o link entre interfaces é especificado por um nome_ de_link, que pode ser uma palavra qualquer a seu critério. Destacando a interligação das interfaces do exemplo anterior, nota-se que o nome do link é lan0:

pc1[eth0]=lan0:ip=192.168.0.1/24
pc2[eth0]=lan0:ip=192.168.0.2/24

Assim, todas as interfaces que estiverem associadas ao mesmo nome de link pertencerão ao mesmo enlace. Inclusive é possível conectar mais de duas interfaces ethernet, que assim se comunicarão como se houvesse um hub a interligá-las.

Observe que nome_de_link pode ser qualquer coisa. O Netkit não o interpreta nem o associa a qualquer nome de máquina virtual. Ele serve somente para informar as interfaces de rede que devem estar interligadas.

Usando DHCP

Interfaces de rede do tipo ethernet também podem ser configuradas usando DHCP. Para isso, deve-se definir o parâmetro IP da interface de rede da seguinte forma:

pc[eth0]=link:ip=dhcp

Para que o DHCP funcione, deve existir ao menos um servidor DHCP dentro do mesmo domínio de broadcast ethernet. Isso se faz definindo o atributo dhcp de uma máquina virtual, como mostrado abaixo:

servidor[type]=generic

servidor[eth0]=link:ip=10.0.0.1/24

servidor[dhcp]=eth0:range=10.0.0.10,10.0.0.20:default-lease=7200:gateway=10.0.0.254

O primeiro parâmetro na definição do atributo dhcp, como exemplificado acima, diz respeito à interface de rede onde serão atendidas requisições vindas de clientes DHCP. Mais de uma interface de rede pode ser servida, bastando definir novamente o atributo dhcp para cada interface. Os demais parâmetros seguem explicados na tabela abaixo:

Parâmetro Descrição Exemplo
range A faixa de endereços IP a ser concedida aos clientes. Deve ser definida com um par de endereços IP separados por vírgula range=10.0.0.10,10.0.0.20
gateway O endereço IP do gateway default da subrede a ser informado aos clientes. Se for omitido, o endereço IP da interface de rede que recebeu a requisição do cliente será informado como gateway default. gateway=10.0.0.254
default-lease A duração da concessão de um endereço para um cliente (em segundos). Se for omitido, será usado o valor de 600 segundos. default-lease=600
max-lease A duração máxima da concessão de um endereço para um cliente (em segundos). Se for omitido, será usado o valor de 3600 segundos. max-lease=3600

Rotas estáticas

Rotas estáticas podem ser adicionadas a qualquer máquina virtual usando o atributo route:

pc1[route]=192.168.0.0/24:gateway=192.168.10.10
pc1[route]=172.18.0.0/16:gateway=192.168.10.1
pc1[route]=default:gateway=192.168.10.2

No exemplo acima foram adicionadas três rotas estáticas ao computador pc1. A primeira tem como destino a rede 192.168.0.0/24, que deve ser alcançada via gateway 192.168.10.10. A segunda aponta a rede 172.18.0.0/16 e usa o gateway 192.168.10.1. A terceira é a rota default.

Outra forma de especificar uma rota estática define a interface de saída ao invés do gateway, e pode ser útil no caso de haver enlaces ponto-a-ponto.

pc1[route]=192.168.0.0/24:dev=ppp0

A rota default é um caso especial, e por ser bastante comum existe um atributo específico para sua definição:

pc1[default_gateway]=192.168.0.254

No exemplo acima, o computador pc1 definiu que seu roteador default deve ser 192.168.0.254. Essa forma curta de definir a rota default funciona somente para rotas que passam por gateways. No caso de rotas por interfaces, deve-se adicioná-las com o atributo route.

Enlaces ponto-a-ponto (via portas seriais)

No caso de uma rede em que máquinas virtuais se comunicam via portas seriais efetuando enlaces ponto-a-ponto, uma sintaxe ligeiramente diferente deve ser usada em Lab.conf:

pc1[type]=generic
pc2[type]=generic

pc1[ppp0]=link0:ip=10.0.0.1/30
pc2[ppp0]=link0:ip=10.0.0.2/30

A diferença está no nome da interface, que deve ser ppp0. Múltiplas interfaces ponto-a-ponto podem existir em cada máquina virtual. Ao iniciarem, as máquinas virtuais terão suas interfaces seriais interligadas. Essas interfaces dentro do Linux são identificadas por /dev/ttyS0, /dev/ttyS1, /dev/ttyS3, e assim por diante (similar a COM1, COM2, COM3, ... do Windows). Assim, dentro das máquinas virtuais podem-se criar enlaces PPP usando-se essas interfaces seriais. No exemplo acima, como foi definido o IP de cada interface ponto-a-ponto, o protocolo PPP será automaticamente ativado quando as máquinas virtuais iniciarem.

A emulação do enlace via portas seriais pode também simular propriedades de enlaces reais, tais como taxa de bits, atraso de propagação e taxa de erros de bit (BER). No exemplo anterior essas propriedades não foram especificadas, então a taxa de bits ficou limitada pelo computador, e o atraso de propapagação e BER foram nulos. Caso se deseje definir uma ou mais dessas propriedades, devem-se usar as opções rate, delay e ber na configuração do enlace ponto-a-ponto, como mostrado abaixo:

# rate: definida em bits por segundo (bps)
# delay: dado em milissegundos (ms)
# ber: valor entre 0 e 1
pc1[ppp0]=link0:ip=10.0.0.1/30:rate=64000:delay=100:ber=0.000001
pc2[ppp0]=link0:ip=10.0.0.2/30:rate=64000:delay=100:ber=0.000001

Nesse exemplo, o enlace link0 tem taxa de 64000 bps, atraso de propagação de 100 ms e BER de . Observe que uma ou mais dessas propriedades pode ser omitida, e que basta defini-las em uma das pontas do enlace.


OBS: para poder usar o wireshark em uma interface PPP, ela deve ter ativada a opção debug:

# A interface ppp0 de pc1 pode ter seu tráfego analisado com wireshark
pc1[ppp0]=link0:ip=10.0.0.1/30:debug=1

# a ppp0 de pc2 não ...
pc2[ppp0]=link0:ip=10.0.0.2/30
Usando a porta serial da máquina real

Pode-se vincular uma interface serial de uma máquina virtual a uma porta serial da máquina real. Com isso, é possível estabelecer enlaces PPP entre máquinas virtuais que estão em diferentes computadores. Esses computadores devem ter suas interfaces seriais RS-232 interligadas por um cabo serial cross. Essa vinculação é feita quando se escreve o nome de uma interface serial da máquina real no lugar do link, ao se declarar uma interface PPP:

pc1[type]=generic

# A interface ppp0 de pc1 está vinculada à interface ttyS0 da máquina real
pc1[ppp0]=ttyS0:ip=10.0.0.1/30

OBS: as interfaces seriais são chamadas de ttyS0 (equivalente a COM1 do DOS/Windows), ttyS1 (equivalente a COM2), e assim por diante.

Iniciando serviços de rede automaticamente

Serviços de rede, tais como os oferecidos pelos servidores SSH, Apache2 e outros, podem ser iniciados automaticamente usando-se o atributo services:

pc[services]=apache2:ssh

Os serviços a serem iniciados devem estar separados por :.

Observe que as configurações desses serviços poderão precisar ser ajustadas, dependendo de como se deseja que eles operem.

Arquivos de projeto do Netkit: preservando modificações feitas nas máquinas virtuais

No arquivo de configuração do Netkit (ex: Lab.conf) devem-se listar os diretorios e/ou arquivos a serem preservados em cada vm (pode haver vm sem o que preservar). Assim, ao iniciar a rede cada máquina virtual pode recuperar os arquivos preservados, e ao terminar os salva automaticamente. Por exemplo:

pc1[type]=generic
pc2[type]=generic

pc1[eth0]=link0:ip=192.168.0.1/24
pc2[eth0]=link0:ip=192.168.0.2/24

pc1[preserve]=/etc:/usr/local/etc

... vai preservar os diretorios /etc e /usr/local/etc de pc1, porém em pc2 nada será preservado. Os diretorios e arquivos a serem preservados devem estar separados por ":". Quanto mais específicos forem os diretórios listados, menor será a quantidade de arquivos a serem preservados.

Para facilitar a cópia da configuração de uma rede virtual, a qual inclui esses arquivos preservados, existem os ítens "Export" e "Import" no menu "File". Ao clicar em "Export", pode-se salvar em um subdiretório qualquer todo um projeto do Netit, o qual é chamado de "Netkit Project File". O nome desses arquivo de projeto é obtido do arquivo de configuração da rede, porém com extensão ".netkit". Ao clicar em "Import" pode-se escolher um projeto salvo previamente, tendo como efeito a restauração dos arquivos preservados das máquinas virtuais e a carga automática do arquivo de configuração. Com isso pode-se copiar o arquivo de projeto entre diferentes computadores, tornando possível reproduzir fielmente uma rede virtual criada e configurada previamente.

Gateways (computadores que interligam subredes)

Neste outro exemplo (contido neste arquivo), o computador pc2 funciona como gateway entre os computadores pc1 e pc3.

pc1[type]=generic
pc2[type]=gateway
pc3[type]=generic
pc1[default_gateway]=192.168.0.2
pc3[default_gateway]=192.168.1.2

pc1[eth0]=lan0:ip=192.168.0.1/24
pc2[eth0]=lan0:ip=192.168.0.2/24
pc2[eth1]=lan1:ip=192.168.1.2/24
pc3[eth0]=lan1:ip=192.168.1.3/24

A rede resultante é:

Netkit-lab2.png

NAT

NAT pode ser ativado em máquinas virtuais do tipo gateway. Em sua configuração deve-se informar qual a interface de saída onde será feito o NAT:

pc2[type]=gateway

pc2[nat]=eth1

Assim, todos datagramas que sairem pela interface eth1 do gateway pc2 terão seus endereços IP de origem substituídos pelo endereço IP dessa interface.

Uplink para a rede real

O Netkit possibilita que se criem links para a rede real, e com isto as máquinas virtuais podem acessar a rede externa e mesmo a Internet. No entanto, o contrário é um pouco mais difícil (se bem que não impossível) devido a forma como o acesso à rede real foi implementado. O link para a rede real funciona como um enlace ponto-a-ponto ethernet entre uma máquina virtual e a máquina real (o sistema hospedeiro), como pode ser visto neste exemplo:

Netkit-uplink.png


pc1[type]=generic
pc2[type]=gateway

pc1[default_gateway]=192.168.0.2
pc2[default_gateway]=10.0.0.2

pc1[eth0]=link1:ip=192.168.0.1/24
pc2[eth0]=link1:ip=192.168.0.2/24
pc2[eth1]=uplink:ip=10.0.0.1/30

A criação do link para rede externa deve ser feita com o link especial uplink. Ele deve ter um endereço IP que será usado somente para criar o link entre a máquina virtual e o sistema hospedeiro. O IP no sistema hospedeiro é sempre o último endereço possível dentro da subrede especificada (no exemplo, seria o IP 10.0.0.2).

pc2[eth1]=uplink:ip=10.0.0.1/30

Se outras máquinas virtuais precisarem acessar a rede externa, devem ter rotas configuradas para usarem o gateway onde foi feito o uplink. Além disso, será necessário ativar o NAT nesse gateway.

Por fim, a criaçao do uplink implica executar alguns comandos como root no sistema hospedeiro. Assim, ao ativar a rede o Netkit irá usar o sudo para executar esses comandos. Por isso é possível que a sua senha seja solicitada durante a inicialização da rede virtual.

Uplink em modo bridge

Às vezes uma interface de uma máquina virtual precisa ser exposta na rede real, como se ela pertencesse ao sistema hospedeiro. Neste caso, deve-se criar uma bridge entre a interface da máquina virtual e uma interface real do sistema hospedeiro (de forma semelhante ao que faz o Virtualbox e outros tipos de máquinas virtuais). Uma bridge é um mecanismo existente no Linux para interligar interfaces ethernet em nível de enlace, como se elas formassem um switch. O procedimento para criar uma bridge integrada a uma interface do tipo uplink do Netkit é um tanto trabalhoso, e por isso esse processo foi automatizado.

A criação de um uplink em modo bridge deve ser feita usando o parâmetro bridge ao se declarar uma interface de rede, como mostrado abaixo:

pc[eth0]=uplink:bridge=eth0:ip=192.168.1.100/24

Neste exemplo, será criada uma bridge entre a interface eth0 da máquina virtual pc e a interface eth0 do sistema hospedeiro. Como com isso a interface da máquina virtual estará exposta na rede real, seu endereço IP pode pertencer à subrede da rede real. Se esse endereço IP for de alguma outra subrede, a máquina virtual não conseguirá se comunicar com as máquinas reais, tampouco acessar a Internet. Mas isso pode ser desejável se a intenção for interligar redes virtuais que estejam sendo executadas em diferentes computadores.

Outra possibilidade é configurar a interface com DHCP:

pc[eth0]=uplink:bridge=eth0:ip=dhcp

Desta forma, a interface obterá um endereço IP (além de rota default e servidor DNS) do servidor DHCP da rede real.

Por fim, é possível definir uma interface sem endereço IP:

pc[eth0]=uplink:bridge=eth0

PBX IP (Asterisk)

O Netkit possui um tipo de máquina virtual especial para funcionar como um PBX Asterisk. As diferenças entre esse tipo de máquina e gateway é a quantidade de memória a ela reservada (64 MB) e a instalação automática do software Asterisk. Todos os arquivos do Asterisk estão dentro de /usr/local/asterisk. Abaixo há um exemplo de uma rede com um PBX:

Pbx-netkit.png
Uma pequena rede com um PBX IP

A configuração dessa rede está mostrada a seguir:

global[compact]=True
#
pbx[type]=pbx
pc1[type]=generic
pc2[type]=generic
#
pbx[eth0]=link1:ip=192.168.1.254/24
pbx[eth1]=link2:ip=192.168.2.254/24
pc1[eth0]=link1:ip=192.168.1.1/24
pc2[eth0]=link2:ip=192.168.2.1/24

pc1[default_gateway]=192.168.1.254
pc2[default_gateway]=192.168.2.254
pbx[preserve]=/usr/local/asterisk/etc

O Asterisk instalado no PBX tem somente canais SIP e IAX2, porém isso é suficiente para realizar muitos experimentos sobre VoIP. Note que na configuração do experimento mostrada acima incluiu-se uma opção para preservar os arquivos contidos em /usr/local/asterisk/etc. Isso é fortemente recomendado, para que as configurações feitas nos canais SIP e IAX2, além do plano de discagem, não sejam perdidos ao se encerrar a execução da rede. Porém para que esses arquivos sejam realmente preservados, deve-se exportar o experimento logo após parar a rede, conforme explicado na seção sobre preservação de arquivos.

OBS: o Asterisk não é iniciado automaticamente. Para iniciá-lo execute:

/usr/local/asterisk/sbin/asterisk

... ou declare-o no arquivo de configuração do Netkit como um serviço a ser iniciado:

pbx[services]=asterisk

...e para monitorá-lo (abrir seu console):

/usr/local/asterisk/sbin/rasterisk -vvv

Realizando chamadas VoIP no Netkit

Um experimento sobre VoIP implica serem feitas chamadas para se testarem as configurações do PBX e para estudar o funcionamento dos protocolos envolvidos. Porém o uso de softphones dentro do Netkit é impraticável, visto que as máquinas virtuais não foram feitas para terem acesso ao microfone e alto-falante (tampouco apresentam ambiente gráfico, o que limita os softphones que poderiam ser usados). Como o objetivo do Netkit é ajudar a criar redes virtuais e realizar experimentos com aplicações que usem essas redes, seria suficiente simular chamadas VoIP para estudar a sinalização e o transporte das streams de audio. Desta forma, no Netkit foram instalados os softwares siprtp e pjsua, que fazem parte do projeto PJSIP (um conjunto de programas de teste e avaliação de desempenho para infraestruturas VoIP baseadas em SIP).

  • siprtp: esse programa possibilita fazer chamadas com áudio sintetizado, no entanto possui algumas restrições para ser usado com o Asterisk.
  • pjsua: esse programa é mais completo, sendo capaz de realizar chamadas muito próximas do real. Ele é até capaz de gerar o audio a partir de arquivos de som. Ao contrário do siprtp, o pjsua é capaz de se registrar no Asterisk.
Usando o siprtp

O programa siprtp funciona em modo cliente-servidor: em um computador executa-se o programa em modo servidor (aguardando chamadas), e no outro executa-se em modo cliente (iniciando chamadas). As chamadas podem ser feitas diretamente ou com a intermediação de um ou mais PBX IP. O exemplo abaixo mostra os comandos necessários para se fazer uma chamada direta entre cliente e servidor:

Servidor Cliente
siprtp -i IP_do_servidor siprtp -i IP_do_cliente sip:0@IP_do_servidor

Chamadas que usam PBX como intermediários podem também ser realizadas, porém há alguns cuidados a tomar para que funcionem a contento:

  • siprtp não faz registro SIP no PBX, portanto a configuração dos canais SIP no PBX deve informar os endereços IP dos computadores onde estão tanto cliente quanto servidor. No Asterisk isso se faz com o parâmetro host de um canal SIP, definido no arquivo sip.conf:
    [1234]
    type=friend
    username=1234
    host=IP_do_computador_onde_roda_o_siprtp
    #secret=ultrasecreta ; não precisa de senha ...
    insecure=port,invite
    context=default
    allow=alaw
    allow=ulaw
    qualify=yes
    
  • siprtp não aceita RE-INVITE, portanto deve-se desativar essa funcionalidade no Asterisk. Na seção [general] do arquivo sip.conf deve-se incluir esta opção:
    directmedia=no
    
  • O cliente deve especificar o canal SIP e o endereço IP do PBX ao fazer uma chamada. Por exemplo, para fazer uma chamada para o canal 1234 deve-se executar o seguinte:
    siprtp -i IP_do_cliente sip:1234@IP_do_PBX
    
Usando o pjsua

O pjsua possui muitas funcionalidades que o tornam um agente SIP quase completo (faltaria ao menos suportar re-invite). Para usá-lo existem muitas opções de linha de comando, conforme descrito em seu manual. Aqui se demonstra como fazer uma chamada com dois pjsua registrados em um PBX Asterisk.

  1. Inicie o Asterisk no PBX, executando este comando:
    asterisk
    rasterisk -vvv
    
    Obs: "rasterisk -vvv" serve somente para que você possa monitorar o funcionamento do Asterisk
  2. Em cada máquina virtual fone pode ser criado um arquivo /root/pjsua.cfg, que contém configurações usuais para rodar o pjsua (ver exemplo mais à frente). Desta forma, evita-se ter que digitá-las sempre que se iniciar o programa. Deve-se executar o pjsua da seguinte forma para que use esse arquivo de configuração:
    pjsua --config-file=/root/pjsua.cfg
    
  3. O arquivo de configuração tenta registrar automaticamente o pjsua no Asterisk. A conta SIP pre-configurada para fins de demonstração é sip:100@ifsc.edu.br (mude-a de acordo com o seu experimento).
  4. Ao rodar o pjsua, confira no PBX se ele foi devidamente registrado. Assim, execute o seguinte no prompt do rasterisk desse PBX:
    sip show peers
    
    O resultado deve ser parecido com este (neste exemplo, foram ativados dois pjsua), em que se nota o Status OK para as contas SIP:

    Rasterisk1.png

  5. A tela do pjsua mostra um menu com os comandos que podem ser usados, como mostrado na seguinte figura:

    Pjsua1.png

  6. Para fazer uma chamada, use o comando m. Ao digitá-lo e teclar ENTER, será pedida a URL do contato a ser chamado:

    Pjsua2.png

  7. Uma vez tendo a chamada estabelecida, pode-se usar o comando dq para monitorar a qualidade da comunicação:

    Pjsua3.png

  8. Para encerrar a chamada, use o comando ha.
Ajustes na configuração do pjsua

O arquivo de configuração pjsua.cfg que foi fornecido contém configuração de demonstração. Ao fazer as suas modificações nas configurações dos PBX para realizar o trabalho, será necessário também ajustar esse arquivo. Abaixo segue o conteúdo do pjsua.cfg que está em fone1 (os números das linhas são apenas informativos, e não fazem parte do pjsua.cfg):

#
# User agent:
#
--auto-answer 200
--max-calls 4
--registrar sip:192.168.1.100
--proxy sip:192.168.1.100;lr
--realm *
# Abaixo devem ser especificados os dados da conta SIP
--id sip:100@ifsc.edu.br
--username 100
--password 100

#
# Logging options:
#
--log-level 3
--app-log-level 4

#
# Network settings:
#
--local-port 5060

#
# Media settings:
#
--null-audio
--snd-auto-close 1
--rtp-port 4000

#
# SIP extensions:
#
--use-timer 1

# Desativa deteccao de silencio
--no-vad

O que pode ser necessário modificar são os dados da conta SIP a ser usada pelo pjsua. Isso é especificado nas linhas 10, 11 e 12.

Switches

Switches são implementados usando funcionalidades existentes no Linux. Assim, uma máquina virtual devidamente configurada pode se comportar como um switch. As funcionalidades possibilitam fazer experiências com VLANs IEEE 802.1q, agregação de enlaces IEEE 802.1AX, e mesmo com STP IEEE 802.1d.

Um switch com 4 portas pode ser criado da seguinte forma:

nome[type]=switch

nome[eth0]=port0
nome[eth1]=port1
nome[eth2]=port2
nome[eth3]=port3

Sendo:

  • nome: nome da maquina virtual

O exemplo com um switch (ver a biblioteca de exemplos mais abaixo) mostra como criar uma pequena LAN com switch. Note que a máquina virtual que será o switch (chamada aqui convenientemente de switch) deve declarar suas interfaces normalmente, além de definir que elas operam em modo bridge (i.e. como um switch):

switch[type]=switch
pc1[type]=generic
pc2[type]=generic
pc3[type]=generic
pc4[type]=generic

switch[eth0]=port0
switch[eth1]=port1
switch[eth2]=port2
switch[eth3]=port3

pc1[eth0]=port0:ip=192.168.0.1/24
pc2[eth0]=port1:ip=192.168.0.2/24
pc3[eth0]=port2:ip=192.168.0.3/24
pc4[eth0]=port3:ip=192.168.0.4/24


VLANs

Um switch pode ter também suas portas em diferentes vlans. Assim, no exemplo abaixo cria-se um switch com 4 portas, porém com 2 portas na vlan 5 e duas na vlan 10 (todas em modo untagged):

nome[type]=switch

nome[eth0]=port0:vlan_untagged=5
nome[eth1]=port1:vlan_untagged=10
nome[eth2]=port2:vlan_untagged=10
nome[eth3]=port3:vlan_untagged=5

Sendo:

  • nome: nome da maquina virtual
  • vlan_untagged: especifica o número de uma VLAN em modo untagged a que pertence a interface de rede em questão.

A configuração acima vai criar uma bridge para cada conjunto de interfaces que estão na mesma VLAN. Nesse exemplo as interfaces operam todas em modo untagged, mas se for necessário que operem em modo tagged deve-se fazer da seguinte forma:

nome[type]=switch

nome[eth0]=port0:vlan_tagged=10,20
nome[eth1]=port1:vlan_untagged=10
nome[eth2]=port2:vlan_untagged=10
nome[eth3]=port3:vlan_untagged=5
nome[eth4]=port4
nome[eth5]=port5

No exemplo acima, a interface eth0 estará nas VLANs 10 e 20 em modo tagged. No caso de interfaces em que não se especificam as vlans, como eth4 e eth5, o switch assume implicitamente que estão na vlan 1 e em modo untagged.

Com base nos exemplos acima, a sintaxe para definir as VLANs em uma interface de rede de uma máquina virtual deve ser:

nome_vm[nome_iface]=nome_link:vlan_untagged=num_vid:vlan_tagged=num_vid1,num_vid2,...

... sendo que tanto vlan_untagged quanto vlan_tagged podem ser omitidos, mas não podem ser usados ao mesmo tempo.

Um outro exemplo (também encontrado na biblioteca de exemplos) mostra um switch com duas VLANs, e o computador pc4 atuando como gateway entre as VLANs. O gateway usa duas interfaces virtuais, e assim a porta do switch em que ele está conectado deve operar em modo tagged:

switch[type]=switch
pc1[type]=generic
pc2[type]=generic
pc3[type]=generic
pc4[type]=gateway
pc5[type]=generic
pc6[type]=generic
pc7[type]=generic

switch[eth0]=port0:vlan_untagged=5
switch[eth1]=port1:vlan_untagged=5
switch[eth2]=port2:vlan_untagged=5
switch[eth3]=port3:vlan_tagged=5,10
switch[eth4]=port4:vlan_untagged=10
switch[eth5]=port5:vlan_untagged=10
switch[eth6]=port6:vlan_untagged=10

pc1[eth0]=port0:ip=192.168.0.1/24
pc2[eth0]=port1:ip=192.168.0.2/24
pc3[eth0]=port2:ip=192.168.0.3/24
pc4[eth0]=port3:vlan_tagged=(5,ip=192.168.0.4/24),(10,ip=192.168.1.4/24)
pc5[eth0]=port4:ip=192.168.1.5/24
pc6[eth0]=port5:ip=192.168.1.6/24
pc7[eth0]=port6:ip=192.168.1.7/24

Esse exemplo mostra que podem-se definir diretamente os endereços IP das interfaces de rede virtuais. Isso é útil para o caso de se definirem interfaces virtuais em máquinas virtuais do tipo generic, gateway e router (não tem sentido usar isso em switch). No entanto, a sintaxe nesse caso é ligeiramente diferente, pois deve-se colocar entre parênteses o número da vlan e o IP da interface, como destacado abaixo:

pc4[eth0]=port3:vlan_tagged=(5,ip=192.168.0.4/24),(10,ip=192.168.1.4/24)

STP (Spanning Tree Protocol)

Switches reais usualmente possuem suporte a STP (Spanning Tree Protocol) para possibilitar haver enlaces redundantes em uma rede local. No Netkit podem-se criar redes em que se usa o STP, que deve ser ativado no switches. Um exemplo de rede em que o STP se torna necessário é mostrada na figura abaixo:

LAN-anel-stp.png

Para criar essa rede no Netkit pode-se usar a seguinte configuração:

sw1[type]=switch
sw2[type]=switch
sw3[type]=switch
pc1[type]=generic
pc2[type]=generic
pc3[type]=generic
 
# Ativação do STP nos switches
sw1[stp]=on:bridge_priority=1024
sw2[stp]=on:bridge_priority=128
sw3[stp]=on:bridge_priority=500

sw1[eth0]=sw1-sw2
sw1[eth1]=sw1-port1
sw1[eth2]=sw1-sw3
 
sw2[eth0]=sw1-sw2
sw2[eth1]=sw2-port1
sw2[eth2]=sw2-sw3
 
sw3[eth0]=sw1-sw3
sw3[eth1]=sw3-port1
sw3[eth2]=sw2-sw3
 
pc1[eth0]=sw1-port1:ip=192.168.0.1/24
pc2[eth0]=sw2-port1:ip=192.168.0.2/24
pc3[eth0]=sw3-port1:ip=192.168.0.3/24

A configuração do STP se faz pelo atributo especial stp a ser especificado para cada switch. A opção on ativa o STP, e bridge_priority define a prioridade do switch no escopo do STP.

Como os switches podem ser configurados com múltiplas vlans, o STP deve ser ativado apropriadamente. Isso significa que cada vlan deve ter o STP rodando de forma independente. A configuração do Netkit para especificar o STP para cada vlan segue abaixo:

sw1[type]=switch

# Ativação do STP nos switches
sw1[stp]=on:bridge_priority=1024:vlan=5
sw1[stp]=on:bridge_priority=512:vlan=10

Nesse exemplo, o switch sw1 tem o STP ativado na vlans 5 e 10. Os parâmetros do STP inclusive podem ser diferentes em cada vlan, já que ele opera em cada uma de forma independente (i.e. o STP em uma vlan não interfere com o STP em outra vlan). Vlans em que o stp não foi explicitamente ativado usarão a configuração default do stp, a qual é definida omitindo-se informação sobre vlan:

# Configuração default do STP em um switch ... vale para todas as vlans em que 
# o stp não foi configurado individualmente.
sw1[stp]=on

# A configuração default pode conter quaisquer opções do stp, menos vlan:
sw2[stp]=on:bridge_priority=2000

Um último detalhe sobre o STP diz respeito ao custo e prioridade de cada porta do switch. No STP usado em switches reais, o custo de uma porta é dado pela sua velocidade. Assim, portas mais velozes têm custo menor que portas mais lentas, como por exemplo portas 1 Gbps comparadas a 100 Mbps. No Netkit não existe essa diferenciação entre as interfaces ethernet por serem emuladas, mas pode-se especificar manualmente o custo de cada interface a ser usado pelo STP. A configuração necessária deve ser colocada em cada porta da seguinte forma:

sw1[type]=switch

# Ativação do STP nos switches
sw1[stp]=on:bridge_priority=1024

sw1[eth0]=port0:stp_cost=10
sw1[eth1]=port1:stp_cost=100

Assim, nesse exemplo a interface eth0 do switch sw1 tem custo STP 10, e a interface eth1 tem custo 100. Os custos de interfaces de acordo com a norma IEEE 802.1d pode ser visto na seguinte tabela:

Stp-custos.png


A lista completa de opções que podem ser usadas na configuração do STP no Netkit segue abaixo:

# STP no switch:
# bridge_priority: prioridade do switch no STP
# hello_time: intervalo entre envios de BPDU
# max_age: tempo máximo que o STP pode ficar sem receber uma atualização de BPDU de outro switch
# forward_delay: atraso para enviar uma BPDU notificando uma mudança de configuração do STP
# on: ativa o STP
# off: inicia com STP desativado

sw1[stp]=on:vlan=10:bridge_priority=100:hello_time=2:max_age=10:forward_delay=1

# Porta do switch: pode ter as opções stp_cost (custo da porta) e stp_prio (prioridade da porta)
sw1[eth0]=port0:stp_cost=10:stp_prio=1

Controle de acesso IEEE 802.1x

O controle de acesso IEEE 802.1x possibilita liberar ou bloquear portas de switches mediante a identificação de usuários válidos. Para usá-lo no Netkit deve-se fazer o seguinte:

  1. Nos switches ativa-se a autenticação com IEEE 802.1x, fornecendo-se uma lista de usuários e respectivas senhas. Além disso, identificam-se quais portas dos switches que exigirão que usuários se autentiquem (portas autenticadoras).
    sw[type]=switch
    
    # Podem-se definir quantos usuários e senhas forem desejados.
    sw[8021x]=1:users=usuario1/senha1,usuario2/senha2
    
    # A interface eth0 do switch é uma porta autenticadora, mas a interface eth1 não.
    sw[eth0]=port0:8021x_authenticator=1
    sw[eth1]=port1
    
  2. Nos computadores que se conectarão aos switches deve-se informar o usuário e senha para fins de autenticação.
    pc[type]=generic
    
    pc[eth0]=port0:8021x_user=usuario1/senha1:ip=10.0.0.1/24
    

Juntando os dois exemplos acima, pode-se definir uma pequena rede para fins de demonstração do controle de acesso:

sw[type]=switch
pc1[type]=generic
pc2[type]=generic

# Podem-se definir quantos usuários e senhas forem desejados.
sw[8021x]=1:users=usuario1/senha1,usuario2/senha2

# A interface eth0 do switch é uma porta autenticadora, mas a interface eth1 não.
sw[eth0]=port0:8021x_authenticator=1
sw[eth1]=port1

pc1[eth0]=port0:8021x_user=usuario1/senha1:ip=10.0.0.1/24
pc2[eth0]=port1:ip=10.0.0.2/24

Ao executar a rede acima, deve-se conseguir fazer um ping entre pc1 e pc2. Se quiser testar com maiores detalhes o controle de acesso e vê-lo em ação, experimente fazer o seguinte:

  1. No pc2 deixe o ping em execução (ping 10.0.0.1)
  2. No pc1 execute o utilitário wpa_cli. Esse programa permite controlar o supplicant, que vem a ser o programa responsável por realizar a autenticação com IEEE 8021x. Ao iniciar o wpa_cli mostra um prompt (>), onde se podem executar comandos de consulta ou modificacão do supplicant.
    1. Execute status, e veja as informações sobre a autenticação mantidas pelo supplicant.
    2. Execute logoff, e em seguida observe como estão as resposta do ping no pc2. As respostas devem etr parado ...
    3. Execute logon, e novamente observe o ping no pc2. Após alguns segundos as respostas devem voltar a ser recebidas.
Definindo um IP de gerenciamento

Um switch pode possuir um endereço IP para fins de gerenciamento. No momento, isso é usado somente para que um switch consiga rodar um servidor Radius e atender pedidos de acesso vindos de outros switches. O IP de gerenciamento precisa estar vinculado a uma das VLANs do switch:

sw[management_ip]=192.168.0.10/24:vlan=5

No exemplo acima, o switch sw possui o IP de gerenciamento 192.168.0.10, que está vinculado a VLAN 5. Apenas um IP por switch hpode ser definido.

Como o tipo switch especializa o tipo generic, é possível definir rotas em um switch que possui um IP de gerenciamento. Isso pode ser feito da mesma forma que em máquinas virtuais genéricas (i.e. usando os atributos default_gateway ou route).

Usando um servidor Radius

Em uma infraestrutura de controle de acesso IEEE 8021.X, usualmente o servidor de autenticação reside em um equipamento em separado. Desta forma, os autenticadores (switches e access points) podem efetuar a autenticação usando uma base de usuários comum. Apesar do padrão IEEE 8021.X não definir como deve ser implementado o servidor de autenticação, os fabricantes de equipamentos adotaram o serviço Radius para assumir esse papel. Com isso, para implantar o servidor de autenticação deve-se instalar um servidor Radius em algum equipamento, e fazer com que os autenticadores o utilizem para para autenticar os acessos.

No Netkit a implantação de um servidor Radius foi simplificada e integrada à configuração do controle de acesso descrita no início desta seção. Por questão de simplicidade, o servidor Radius deve ser implantado em um switch. assim, a configuração de um switch que deve operar como servidor Radius é:

sw2[8021x]=1:users=u1/p1,u2/p2:radius_clients=10.0.0.10,10.0.0.254

O parâmetro users lista os usuários e senhas autenticados pelo Radius, e radius_clients lista os endereços IP dos clientes Radius (que são os demais switches). Em ambos os casos, as informações devem ser escritas como listas separadas por vírgulas.

Os clientes Radius precisam definir que servidor Radius irão utilizar. A configuração de um switch que é cliente Radius poderia ser esta:

sw[8021x]=1:radius_server=10.0.0.5

Note que os clientes Radius devem ser capazes de alcançarem o servidor Radius. Quer dizer, se clientes e servidor Radius estiverem em subredes IP diferentes, devem existir rotas para que eles possam se comunicar.

Um exemplo de uma rede com dois switches, sendo um deles um servidor Radius, está mostrada a seguir:

pc1[type]=generic
pc2[type]=generic
sw[type]=switch
sw2[type]=switch

sw[8021x]=1:radius_server=10.0.0.5
sw2[8021x]=1:users=aluno/teste:radius_clients=10.0.0.10

sw[management_ip]=10.0.0.10/24:vlan=1
sw2[management_ip]=10.0.0.5/24:vlan=1

pc1[eth0]=sw-port0:ip=10.0.0.1/24:8021x_user=aluno/teste
pc2[eth0]=sw-port1:ip=10.0.0.2/24:8021x_user=aluno/teste
sw[eth0]=sw-port0:8021x_authenticator=1
sw[eth1]=sw-port1:8021x_authenticator=1
sw[eth2]=sw-port2

sw2[eth0]=sw-port2
Ex-radius.png
Usando múltiplas VLANs
  • isto ainda não funciona ...

Quando um switch que é autenticador IEEE 802.1x possui múltiplas VLANs,

Usando freeradius

Agregação de enlace (bonding)

O Linux possui suporte a agregação de enlaces, em que se agrupam interfaces ethernet de forma a parecerem uma única interface (chamado de Linux Channel Bonding). A interface agregada tem prefixo bond, e assim deve ser identificada como bond0, bond1 e assim por diante. Para criar um enlace agregado no Netkit basta declarar em um switch uma interface desse tipo. A sintaxe da declaração é praticamente idêntica a de interfaces ethernet, como se pode ver abaixo:

pc1[type]=generic
pc2[type]=generic
sw1[type]=switch
sw2[type]=switch

pc1[eth0]=sw1-port0:ip=192.168.0.1/24
pc2[eth0]=sw2-port0:ip=192.168.0.2/24

sw1[eth0]=sw1-port0
sw2[eth0]=sw2-port0

# Define em cada switch uma interface bond0 que agrega dois enlaces.
# O enlace agregado deve ser composto por uma ou mais interfaces ethernet.
# O nome do enlace agregado é sw1-sw2 no exemplo.

sw1[bond0]=sw1-sw2:interfaces=eth1,eth2
sw2[bond0]=sw1-sw2:interfaces=eth1,eth2

Nesse exemplo o enlace agregado foi criado entre os switches sw1 e sw2. Como se pode notar, existe uma opção de configuração adicional interfaces, usada para listar as interfaces ethernet a serem agrupadas. Essas interfaces não devem ser declaradas explicitamente. Além disso, não se podem configurar VLANs na interface agregada (bond0 no exemplo). Por fim, mais de um enlace agregado pode ser criado no mesmo switch, bastando identificá-los por interfaces bond diferentes (bond1, bond2, ...).

O exemplo acima cria a seguinte rede:

Bond.png

Máquinas com suporte a PPPoE

A configuração de uma infraestrutura de acesso baseada em PPPoE implica o ajuste de vários detalhes tanto nos clientes quanto no AC (servidor PPPoE). Muitos desses detalhes podem ser abreviados explorando-se opções existentes no Netkit.

Na configuração do Netkit um AC PPPoE deve ser uma máquina virtual do tipo pppoe, que é uma extensão do tipo gateway. Desta forma, todas as capacidades apresentadas por gateway estão presentes no tipo pppoe. Já as opções necessárias para o funcionamento de um AC devem ser especificadas usando-se o atributo pppoe. O cliente PPPoE, por sua vez, precisa apenas indicar em que interface ethernet será iniciado o enlace PPPoE. O exemplo abaixo mostra uma pequena rede com um AC e dois clientes:

sw1[type]=switch
sw2[type]=switch
ac[type]=pppoe
cliente1[type]=generic
cliente2[type]=generic
servidor[type]=generic

# define as opções do AC PPPoE
ac[pppoe]=nome_ac:interface=eth0:users=(aluno1,blabla),(aluno2,rruahhh):range=172.18.1.1,172.18.1.10:ip=172.18.1.20

sw1[eth0]=sw1-port0
sw1[eth1]=sw1-port1
sw1[eth2]=sw1-port2

sw2[eth0]=sw2-port0
sw2[eth1]=sw2-port1

ac[eth0]=sw1-port0
ac[eth1]=sw2-port0:ip=192.168.0.1/24

servidor[eth0]=sw2-port1:ip=192.168.0.10/24

# Define que a interface eth0 de cliente1 e cliente2 devem operar em modo PPPoE.
cliente1[eth0]=sw1-port1:mode=pppoe:pppoe_user=aluno1:pppoe_password=blabla:pppoe_ac=nome_ac
cliente2[eth0]=sw1-port2:mode=pppoe:pppoe_user=aluno2:pppoe_password=rrruahh:pppoe_ac=nome_ac

A configuração acima gera uma rede com dois computadores clientes, um AC PPPoE e um servidor, como mostrado na seguinte figura:

Netkit-pppoe.png


A definição do AC PPPoE precisa de algumas opções específicas do PPPoE. Elas devem ser listadas no atributo pppoe da máquina virtual que representa o AC:

# define as opções do AC PPPoE
ac[pppoe]=nome_ac:interface=eth0:users=(aluno1,blabla),(aluno2,rruahhh):range=172.18.1.1,172.18.1.10:ip=172.18.1.20

A primeira opção mostrada acima (nome_ac) corresponde ao nome do AC, usado durante a etapa de descoberta PPPoE feita pelos clientes. As demais opções do AC são:

  • interface: a interface ethernet onde o AC vai esperar por pedidos de estabelecimento de enlace PPPoE.
  • range: a faixa de endereços IP a serem concedidos aos clientes.
  • ip:o endereço IP a ser usado pelo AC na sua ponta dos enlaces PPPoE.
  • users: a lista de usuários e respectivas senhas, usados para autenticar os acessos vindos dos clientes.

Os clientes precisam definir que interface ethernet deve operar em modo PPPoE, e junto a isso especificar suas opções PPPoE, como destacado abaixo:

cliente1[eth0]=sw1-port1:mode=pppoe:pppoe_user=aluno1:pppoe_password=blabla:pppoe_ac=teste

As opções PPPoE do cliente são:

  • pppoe_user: o nome de usuário para fins de autenticação PPP.
  • pppoe_password: a senha do usuário para fins de autenticação PPP.
  • pppoe_ac: o nome do AC com que se deseja estabelecer o enlace.

Uma vez estabelecido um enlace PPPoE, é criada automaticamente uma rota default no cliente usando o AC como gateway.

Roteadores

Roteadores podem ser criados no Netkit usando máquinas virtuais do tipo router. Um roteador tem sua função de gateway ativada automaticamente, e executa o programa Quagga, que implementa protocolos de roteamento (tais como OSPF, RIP e BGP). O exemplo abaixo mostra a criação de uma pequena rede com dois roteadores interligados por um link PPP.

r1[type]=router
r2[type]=router
pc1[type]=generic
pc2[type]=generic

r1[ppp0]=link0:ip=10.0.0.1/30
r1[eth0]=lan0:ip=192.168.0.254/24
r1[route]=default:dev=ppp0

r2[ppp0]=link0:ip=10.0.0.2/30
r2[eth0]=lan1:ip=192.168.1.254/24
r2[route]=default:dev=ppp0

pc1[eth0]=lan0:ip=192.168.0.1/24
pc1[default_gateway]=192.168.0.254

pc2[eth0]=lan1:ip=192.168.1.2/24
pc2[default_gateway]=192.168.1.254

Exp-routers.png


Ao iniciar, um roteador apresenta um shell parecido com o de um roteador Cisco real, como pode ser visto nas duas telas abaixo.


Netkit-router1.png Netkit-router2.png


Esse shell provê somente os comandos de configuração do Quagga. Para executar programas da máquina virtual Linux deve-se usar o comando start-shell. Isso abre um shell usual (bash), onde se podem executar programas do Linux.

Switches MPLS

MPLS é uma tecnologia para redes WAN que usa o conceito de circuitos virtuais (chamados no MPLS de LSP - Label Switched Path). Existe um projeto no Linux para implementar parte da funcionalidade MPLS, o qual está disponível nas máquinas virtuais do Netkit. Apesar desse projeto estar incompleto, algumas funcionalidades básicas podem ser experimentadas, tais como criação de LSP estáticos e túneis MPLS. No entanto, ainda não é possível criar VPNs MPLS (chamadas de VPLS) ou estabelecer LSP dinâmicos. Assim, no Netkit podem-se criar experimentos explorando essas funções elementares do MPLS.

Um equipamento que comuta rótulos, ou switch MPLS, pode ser criado usando uma máquina virtual do tipo mpls. Em cada switch MPLS devem-se configurar:

  • FEC: classes de equivalência de tráfego, que classificam PDUs não-MPLS que entram na rede MPLS. Essa classificação será usada para definir posteriormente (via NHLFE) que rótulo deve ser adicionado.
  • NHLFE: definem o que deve ser feito com uma PDU (usualmente que rótulo adicionar e por que interface transmiti-la).
  • Labelspace: especificam conjuntos de interfaces por onde se recebem PDUs MPLS.
  • ILM: define que rótulos são aceitos vindos de cada labelspace.

Assim, um switch MPLS precisa usualmente ter configuradas essas quatro informações. A configuração do Netkit mostrada abaixo cria umapequena rede com dois switches MPLS e dois computadores comuns.

sw1[type]=mpls 
sw2[type]=mpls
h1[type]=generic
h2[type]=generic

# FEC: mapeia subrede destino para nhlfe
sw1[fec]=192.168.1.0/24:nhlfe=1
sw2[fec]=192.168.0.0/24:nhlfe=1

# NHLFE: como encaminhar uma PDU MPLS
sw1[nhlfe]=1:interface=eth0:label=100:ip=10.0.0.2
sw2[nhlfe]=1:interface=eth0:label=200:ip=10.0.0.1

# ILM: como identificar PDUs MPLS recebidas
sw1[ilm]=200:labelspace=0
sw2[ilm]=100:labelspace=0

# Labelspace: os mapeamentos de labelspaces a interfaces
sw1[labelspace]=0:interfaces=eth0
sw2[labelspace]=0:interfaces=eth0

sw1[eth1]=lan0:ip=192.168.0.254/24
sw1[eth0]=link1:ip=10.0.0.1/24
sw2[eth0]=link1:ip=10.0.0.2/24
sw2[eth1]=lan1:ip=192.168.1.254/24

h1[eth0]=lan0:ip=192.168.0.1/24
h2[eth0]=lan1:ip=192.168.1.1/24

h1[default_gateway]=192.168.0.254
h2[default_gateway]=192.168.1.254

Mpls1.png

Para configurar cada ítem do switch MPLS devem-se usar alguns atributos:

  • FEC: usa-se o atributo fec
    sw1[fec]=192.168.1.0/24:nhlfe=1
    
    Esse atributo possui apenas duas opções:
    • IP/Máscara: a rede destino (192.168.1.0/24 no exemplo)
    • nhfe=um_número: o número do NHLFE a ser usado (nhlfe=1 no exemplo)
  • NHLFE: usa-se o atributo nhlfe
    sw1[nhlfe]=1:interface=eth0:label=100:ip=10.0.0.2
    
    As seguintes opções existem:
    • um_número: o número do NHLFE. Funciona como um identificador a ser usado no ILM ou FEC.
    • label=um_número: o número de rótulo a ser adicionado.
    • interface=nome_interface: a interface por será trabsmitida a PDU MPLS.
    • ip=um_IP: endereço IP do próximo switch MPLS (o que deve receber as PDUs transmitidas de acordo com esta NHLFE)

      Além dessa opções pode-se especificar um NHLFE de forma a empilhar rótulos (adicionar dois ou mais rótulos a uma mesma PDU), o que é necessário na entrada de túneis MPLS:
      sw1[nhlfe]=1:label=200:nhlfe=2
      
      Nesse caso não se usam as opções ip e interface, porém adiciona-se a seguinte opção:
    • nhlfe=um_número: identificador da NHLFE a ser usada depois da aplicação desta NHLFE.
  • ILM: usa-se o atributo ilm
    sw1[ilm]=1000:labelspace=0:nhlfe=2
    
    As opções que podem ser usadas são:
    • um_número: o número do rótulo que será reconhecido.
    • labelspace=um_número: o número do labelspace de onde se aceitará o rótulo.
    • nhlfe=um_número: o identificador do NHLFE a ser usado para encaminhar essas PDUs MPLS.

      Uma forma alternativa de definir o ilm omite a opção nhlfe. Nesse caso a PDU MPLS será aceita, o rótulo será removido e a PDU será então processada normalmente pela camada de rede IP.
  • Labelspaces: usa-se o atributo labelspace
    sw1[labelspace]=0:interfaces=eth0,eth1
    
    Suas opções são apenas:
    • um_número: o número do labelspace.
    • interfaces=if1,if2,...: a lista de uma ou mais interfaces que pertencem a esse labelspace.

Qualquer um desses atributos pode ser especificado múltiplas vezes, como exemplificado abaixo:

sw1[nhlfe]=1:interface=eth0:label=100:ip=192.168.0.2
sw1[nhlfe]=2:label=1000:nhlfe=1

A configuração acima irá adicionar duas NHLFE em sw1.

Um exemplo de uma rede um pouco maior contém três switches MPLS:

sw1[type]=mpls 
sw2[type]=mpls
sw3[type]=mpls
h1[type]=generic
h2[type]=generic
h3[type]=generic

# FEC: mapeia subrede/mask para nhlfe
sw1[fec]=192.168.1.0/24:nhlfe=1
sw1[fec]=192.168.2.0/24:nhlfe=2
sw2[fec]=192.168.0.0/24:nhlfe=1
sw2[fec]=192.168.2.0/24:nhlfe=2
sw3[fec]=192.168.0.0/24:nhlfe=1
sw3[fec]=192.168.1.0/24:nhlfe=2

# NHLFE: como encaminhar uma PDU MPLS ... (push)
sw1[nhlfe]=1:interface=eth0:label=110:ip=10.0.0.2
sw1[nhlfe]=2:interface=eth0:label=120:ip=10.0.0.2
sw2[nhlfe]=1:interface=eth0:label=210:ip=10.0.0.1
sw2[nhlfe]=2:interface=eth1:label=220:ip=10.0.2.3
sw2[nhlfe]=3:interface=eth1:label=130:ip=10.0.2.3
sw3[nhlfe]=1:interface=eth0:label=310:ip=10.0.1.1
sw3[nhlfe]=2:interface=eth1:label=320:ip=10.0.2.2

# ILM: como identificar PDUs MPLS recebidas (implicitamente faz um pop)
sw1[ilm]=210:labelspace=0
sw1[ilm]=310:labelspace=0
sw2[ilm]=110:labelspace=0
sw2[ilm]=120:labelspace=0:nhlfe=3
sw2[ilm]=320:labelspace=0
sw3[ilm]=130:labelspace=0
sw3[ilm]=220:labelspace=0

# Labelspace: os mapeamentos de labelspaces a interfaces
sw1[labelspace]=0:interfaces=eth0,eth1
sw2[labelspace]=0:interfaces=eth0,eth1
sw3[labelspace]=0:interfaces=eth0,eth1

sw1[eth0]=link1:ip=10.0.0.1/24 
sw1[eth1]=link2:ip=10.0.1.1/24 
sw1[eth2]=lan0:ip=192.168.0.254/24 

sw2[eth0]=link1:ip=10.0.0.2/24 
sw2[eth1]=link3:ip=10.0.2.2/24 
sw2[eth2]=lan1:ip=192.168.1.254/24

sw3[eth0]=link2:ip=10.0.1.3/24 
sw3[eth1]=link3:ip=10.0.2.3/24 
sw3[eth2]=lan2:ip=192.168.2.254/24

h1[eth0]=lan0:ip=192.168.0.1/24
h2[eth0]=lan1:ip=192.168.1.1/24
h3[eth0]=lan2:ip=192.168.2.1/24

h1[default_gateway]=192.168.0.254
h2[default_gateway]=192.168.1.254
h3[default_gateway]=192.168.2.254

Mpls2.png

Opções e configurações avançadas

Preferências

Atributos globais definem parâmetros válidos para o experimento como um todo. Esses atributos devem ser especificados com a sintaxe global[nome_do_atributo]=valor_do_atributo. No momento há apenas o atributo path, que define o diretório onde devem ser criados os arquivos temporários e discos virtuais do experimento. O diretório de trabalho pode ser especificado com um caminho relativo, como exemplificado abaixo:

# o diretório de trabalho do experimento será o subdiretório "tmp" dentro do diretório onde
# está o arquivo de configuração (i.e. diretorio_do_arquivo_de_configuracao/tmp)
global[path]=tmp

... ou um caminho absoluto:

# o diretório de trabalho do experimento será o subdiretório "/home/aluno/tmp".
global[path]=/home/aluno/tmp

Se o atributo global path não for definido, o gnome-netkit irá criar um subdiretório dentro do diretório onde está o arquivo de configuração, e usá-lo como diretório de trabalho. O nome desse subdiretório será da forma tmp-xxxxx, sendo xxxxx um número aleatório.

Projetos

Modo de instalação de software

Uma biblioteca de exemplos de experimentos

Para facilitar o aprendizado de como usar o Netkit foi criada uma pequena coleção de experimentos.

Experimentos com LANs

  • LAN simples: uma LAN com quatro computadores (pc1, pc2, pc3, pc4). Os computadores virtuais têm IPs 192.168.1.X, sendo X o número computador (ex: pc1 tem IP 192.168.1.1). Use ping para fazer testes de comunicação. Veja o arquivo Lab.conf (configuração da rede) e pc1.startup, pc2.startup, pc3.startup e pc4.startup (scripts que configuram cada máquina virtual após o boot). A rede criada nesse experimento está mostrada abaixo:

Exemplo-Lan1-netkit.png


Ao executar esse experimento quatro terminais surgirão (um para cada máquina virtual). A figura abaixo mostra o experimento em execução, e nele a máquina virtual pc fazendo um ping em broadcast e em pc2 e pc3 sendo executado tcpdump para ver as mensagens ICMP geradas pelo ping:

Ier-lan1-netkit.png


  • Duas LANs interligadas com PPP: uma LAN com quatro computadores (pc1, pc2, pc3, pc4) ligada com PPP a outra LAN (pc5, pc6 e pc7). O link PPP é implantado sobre as portas seriais das máquinas virtuais pc4 e pc5. Ver os arquivos Lab.conf, pc4.startup e pc5.startup. A rede do experimento está mostrada abaixo:

Lan-ppp.png


  • LAN com switch: uma LAN com quatro computadores (pc1, pc2, pc3, pc4) interligados por um switch. O switch é implementado por um computador com Linux com 4 portas ethernet. Ver os arquivos Lab.conf e switch.startup. A rede do experimento está mostrada abaixo:

Exemplo-Bridge-netkit.png


  • LAN com dois switches: uma LAN com 6 computadores (pc1 a pc6) interligados por dois switches (switch1 e switch2). Ambos switches são implementados por computadores com Linux com 4 portas ethernet. Ver os arquivos Lab.conf, switch1.startup e switch2.startup. A rede do experimento está mostrada abaixo:

Exemplo-lan2.png

Experimentos com VLAN

Observar os quadros com tag nas interfaces que operam em modo tagged. Teste também o isolamento entre VLANs.

  • Switch e duas VLANs: duas VLANs com quatro computadores cada. VLAN 5 tem IPs 192.168.1.0/24 e contém pc1, pc2, pc3, pc4; VLAN 10 tem IPs 192.168.2.0/24 e contém pc4, pc5, pc6, pc7. O switch Linux foi configurado para que a interface eth3 esteja nas VLANs 5 e 10 (i.e. em modo tagged), as interfaces eth0, eth1, eth2 estejam na VLAN 5 em modo untagged, e as interfaces eth4, eth5 e eth6 estejam na VLAN 10 em modo untagged. O computador pc4 opera como gateway entre as VLANs, usando duas interfaces virtuais (i.e. a interface eth0 foi posta nas VLANs 5 e 10 em modo tagged). Nesse exemplo se usa VLAN tagging IEEE 802.1q.

Bridge2.png


  • Dois switches e duas VLANs: duas VLANs com quatro computadores cada. VLAN 5 tem IPs 192.168.1.0/24 e contém pc1, pc2, pc3, pc4; VLAN 10 tem IPs 192.168.2.0/24 e contém pc5, pc6, pc7, pc8. O switch Linux foi configurado para que a interface eth3 esteja nas VLANs 5 e 10 (i.e. em modo tagged), as interfaces eth0, eth1, eth2 estejam na VLAN 5 em modo untagged, e as interfaces eth4, eth5 e eth6 estejam na VLAN 10 em modo untagged. O computador pc4 opera como gateway entre as VLANs, usando duas interfaces virtuais (i.e. a interface eth0 foi posta nas VLANs 5 e 10 em modo tagged). Nesse exemplo se usa VLAN tagging IEEE 802.1q. O diagrama abaixo ilustra essa rede:

Bridge3.png

Leia os arquivos de inicialização switch1.startup, switch2.startup e pc4.startup para entender como foram configuradas as VLANs.

API do Netkit

O Netkit possui uma API para iniciar e parar experimentos, entre outras coisas. Ela está implementada no módulo ${NETKIT_HOME}/bin/netkit.py. Para usá-la, seu programa Python deve incluir o seguinte:

import netkit


O trecho de programa abaixo ilustra como a API pode ser usada para iniciar um experimento e interagir com as consoles das VM. As classes usadas nesse programa são descritas nas próximas subseções.

# Cria um experimento Netkit
parser = netkit.NetkitParser2(conf)

# Cria um gerador de terminais
pool = TermPool()

# Inicia o experimento usando o gerador de terminais
parser.startNetwork2(pool)

# Inicia todos os terminais e, consequentemente, todas as VM do experimento
pool.start()

# Obtém o terminal da VM pc1
term = pool.get_term('pc1')

# Através do objeto term se pode conversar com a console da VM pc1 ...

Classe NetkitParser2

Definida em netkit.py


Um objeto da classe NetkitParser2 representa um experimento. Por meio dele se pode iniciar ou parar um experimento.


constructor: NetkitParser2(conf, prefs=None)

Parâmetro Descrição
conf objeto com interface de arquivo (ex: um arquivo aberto) contendo a configuração do experimento
prefs Preferências da execução contidas em um dicionário. Os parâmetros possíveis são:

path: pathname do experimento
mem: memória em MB para cada VM
rw: modo escrita, em que modificações em arquivos ficam gravadas permanentemente no disco virtual do Netkit (usado basicamente para instalar novos softwares)


Métodos:

startNetwork2(termPool=None): inicia um experimento usando termPool como o gerador de terminais para as VM. Esse gerador deve ser um objeto cuja classe implemente a interface TerminalPool. Se termPool não for especificado, o experimento usa um gerador interno que executa o terminal padrão do sistema (usualmente xterm).

stopNetwork(): termina o experimento, parando todas suas VM.

set_path(path): define o caminho do diretório de trabalho do experimento.

interface TerminalPool

OBS: Deve-se implementar uma classe que realize esta interface, a qual é necessária para que possa usar NetkitParser2.


A interface TerminalPool define um gerador de terminais para as VM. Sua função é criar um terminal para cada VM a ser executada. Esses terminais devem ser objetos que implementam a interface Terminal, os quais desempenham esse papel para as VM. Quer dizer, cada objeto Terminal deve se associar à console de uma VM e agir como um terminal de fato.

Métodos:

addVM(nome, comando): adiciona a especificação de uma VM denominada nome. Essa VM deve ser iniciada executando-se comando. Desta forma, é responsabilidade do terminal executar essa VM e capturar seu console.

start(): inicia todas as VM em seus respectivos terminais.

stop(): para todas as VM.

get_terms(): retorna um dicionário com todos os terminais indexados pelos nomes de suas VM.

get_term(nome): retorna o terminal da VM nome.


Exemplo de classe que realiza TerminalPool:

class TermPool:

  def __init__(self):
    self.terms = {}

  def addVM(self, name, cmd):
    self.terms[name] = NetTerm(name, cmd)

  def start(self):
    for vm in self.terms:
      self.terms[vm].start()

  def stop(self):
    for vm in self.terms:
      self.terms[vm].stop()

  def get_term(self, name):
    return self.terms[name]

  def get_terms(self):
    return self.terms

interface Terminal

OBS: Deve-se implementar uma class que realize esta interface, a qual é necessária para TerminalPool.


A interface Terminal define como devem se apresentar objetos as serem usados como terminais para as VM do Netkit. Objetos que implementam essa interface não devem ser instanciados diretamente, pois são criados por TerminalPool.


Construtor: Terminal(nome, comando)

Parâmetro Descrição
nome o nome da VM (string)
comando o comando a ser executado pelo terminal para iniciar a VM (string). Esse comando é fornecido por NetkitParser2. O terminal não deve executar esse comando dentro do construtor, mas apenas armazená-lo para execução posterior (via método start)


Métodos:

start(): inicia a VM, conectando seu console ao lado escravo de um pseudo-terminal. Esse pseudo-terminal deve ser criado pelo Terminal.

stop(): para a VM.


Atributos públicos:

fd: objeto do tipo arquivo vinculado ao lado mestre do pseudo-terminal. Pode ser usado para enviar e receber dados da VM.


Exemplo de classe que realiza Terminal:

class NetTerm:

  def __init__(self, name, cmd):
    self.name = name
    self.cmd = cmd
    self.fd = None

  def start(self):
    pass

  def stop(self):
    pass

API REST

Recurso Método Parâmetros Resultado Descrição
/netkit GET status 200: lista de URIs para as redes existentes (JSON) obtém a lista de redes existentes no controlador
/netkit POST name, config status 201: URI da rede criada (header location)
status 403: rede já existe
cria uma nova rede identificada por name e com configuração dada por config
/netkit/ID GET
/netkit/ID POST
/netkit/ID DELETE
/netkit/ID/config GET
/netkit/ID/config PUT
/netkit/ID/preferences GET
/netkit/ID/preferences PUT
/netkit/ID/image GET
/netkit/ID/dot GET
/netkit/ID/NUM GET
/netkit/ID/NUM PUT
/netkit/ID/NUM DELETE