Voice Chat no MSN Messenger atras de um Firewall+NAT

Ricardo Iramar dos Santos - Agent Smith
04/11/2002 - Versão 0.1

Objetivo

Implementação do UPnP (Universal Plug and Play) Internet Gateway Device para emulação do Microsoft's ICS (Internet Connection Service) possibilitando a conversa com vídeo e voz, transferência de arquivos e assistência remota entre duas máquinas de redes distintas através de um Firewall NAT pela internet.

Introdução

Como todos sabem nunca será possivel para cada PC do mundo atribuir um endereço IP (Internet Protocol) IPv4 fixo, pessando nisso um carinha chamado Rusty Russell desenvolveu uns pacotes para o kernel chamado NAT.

Basicamente o NAT altera o destino e/ou origem em um pacote, desta forma diversas máquinas em uma intranet podem usar um único IP fixo para se conectar a internet. Maiores informações consulte: http://www.netfilter.org.

Entretanto existem softwares, como o MSN Messenger, utilizam portas dinâmicas acima de 1024 juntamente com protocolos TCP (Transmission Control Protocol), UDP (User Datagram Protocol) e RTP (Real Time Transport Protocol) inviabilizando o uso do NAT.

Por exemplo, para uma conversa com vídeo e voz o MSN Messenger utiliza o protocolo RTP em um range de portas dinâmicas (5004-65535). Maiores informações consulte: http://www.microsoft.com/windowsxp/pro/techinfo/deployment/natfw/default.asp.

OBS: Para mensagens instantâneas o MSN Messenger utiliza somente protocolos TCP via porta 1863, podendo assim ser usado sem a implementação desta solução.

Procedimento

Primeiramente precisamos instalar o Intel Linux UPnP SDK, faça o download dos arquivos fontes do site http://upnp.sourceforge.net em um diretório qualquer, eu usarei o /usr/local/src. Quando estava escrevendo este tutorial era versão 1.0.4 se desejar fazer o download desta versão clique aqui http://prdownloads.sourceforge.net/upnp/upnpsdk-1.0.4.tar.gz.

Descompacte o pacote com o seguinte comando:

  	root@trinity:/usr/local/src# tar -zxvf upnpsdk-1.0.4.tar.gz

Antes de compilar e instalar os arquivos binários edite o seguinte arquivo:

  	root@trinity:/usr/local/src# cd upnpsdk-1.0.4/src/ssdp/
  	root@trinity:/usr/local/src/upnpsdk-1.0.4/src/ssdp# vi ssdplib.c

Altere a linha número 406 deste arquivo de:

  	SelfAddr.sin_addr.s_addr = inet_addr(SSDP_IP);

para:

  	SelfAddr.sin_addr.s_addr = htonl(INADDR_ANY);

Execute os comandos "make" e "make install" para compilar e instalar os arquivos binários em /usr/bin/ e os arquivos de configuração em /etc/linuxigd da seguinte forma:

  	root@trinity:/usr/local/src/upnpsdk-1.0.4/src/ssdp# cd ../../
  	root@trinity:/usr/local/src/upnpsdk-1.0.4# make
  	root@trinity:/usr/local/src/upnpsdk-1.0.4# make install

Adicione a seguinte regra na tabela de roteamento:

  	root@trinity:/usr/local/src/upnpsdk-1.0.4# route add -net 239.0.0.0 netmask 255.0.0.0 [int_if]

Onde [int_if] é nome da sua placa de rede interna (exemplo: eth1). Exemplo:

  	root@trinity:/usr/local/src/upnpsdk-1.0.4# route add -net 239.0.0.0 netmask 255.0.0.0 eth1

Dica: Você pode adicionar esta linha em um arquivo de inicialização para que seja executada na inicialização do sitema.

Agora vamos fazer o download do UPnP Internet Gateway Device do do site http://linux-igd.sourceforge.net. Quando estava escrevendo este tutorial era versão 0.75 se desejar fazer o download desta versão clique aqui http://telia.dl.sourceforge.net/sourceforge/linux-igd/gateway-0.75.tgz.

Descompacte os arquivos fontes da seguinte forma:

  	root@trinity:/usr/local/src/upnpsdk-1.0.4# cd..
  	root@trinity:/usr/local/src# tar -zxvf gateway-0.75.tgz

Compilando e instalando o UPnP Internet Gateway Device:

  	root@trinity:/usr/local/src# cd gateway-0.75
  	root@trinity:/usr/local/src/gateway-0.75# make
  	root@trinity:/usr/local/src/gateway-0.75# make install

Antes de executar o arquivo upnpd certifique-se que o arquivo iptables se encotra no diretório /usr/sbin/ caso contrário crie um link simbólico para este diretório com nome de iptables.

Execute o daemon upnpd da seguinte forma:

  	root@trinity:/usr/local/src/gateway-0.75# upnpd [ext_if] [int_if]

Onde [ext_if] é a sua placa de rede externa (exemplo: eth0) e [int_if] é a sua placa de rede interna (exemplo: eth1). Exemplo:

  	root@trinity:/usr/local/src/gateway-0.75# upnpd eth0 eth1

Se tudo estiver correto as messagens de debug serão gravadas em /var/log/debug mas se ocorrer algum erro as menssagens serão gravadas em /var/log/messages.

Observação: O upnpd assume que a política padrão no iptables para a chain FORWARD seja ACCEPT, assim como para a chain INPUT seja ACCEPT para todas as estações da sua intranet (protocolos TCP e UDP). Na verdade o upnpd usará somente portas randônicas acima de 1024.

Para parar o processo upnpd basta executar o seguinte comando:

  	root@trinity:/usr/local/src/gateway-0.75# killall upnpd

ou se preferir pelo número do processo:

  	root@trinity:/usr/local/src/gateway-0.75# ps ax | grep upnpd
  	1160 ? S 0:00 upnpd eth1 eth0
  	1161 ? S 0:00 upnpd eth1 eth0
  	1162 ? S 0:00 upnpd eth1 eth0
  	1163 ? S 0:00 upnpd eth1 eth0
  	1164 ? S 0:00 upnpd eth1 eth0
  	1165 ? S 0:00 upnpd eth1 eth0
  	1166 ? S 0:00 upnpd eth1 eth0
  	1167 ? S 0:00 upnpd eth1 eth0
  	1168 ? S 0:00 upnpd eth1 eth0
  	1169 ? S 0:00 upnpd eth1 eth0
  	1170 ? S 0:00 upnpd eth1 eth0
  	1171 ? S 0:00 upnpd eth1 eth0
  	1172 ? S 0:00 upnpd eth1 eth0
  	1173 ? S 0:00 upnpd eth1 eth0
  	1174 ? S 0:00 upnpd eth1 eth0
  	1176 pts/0 S 0:00 grep upnpd
  	root@trinity:/usr/local/src/gateway-0.75# kill [process_id]

Onde [process_id] é o número de cada processo listado pelo comando "ps ax | grep upnpd".

Referências

- http://upnp.sourceforge.net

- http://linux-igd.sourceforge.net

- http://gus-br.linuxmag.com.br

- http://www.netfilter.org

- http://www.microsoft.com/windowsxp/pro/techinfo/deployment/natfw/default.asp


Dúvidas, críticas e sugestões devem ser enviadas para ricardo.iramar@gmail.com.

Quer saber mais um pouco sobre o autor desta documentação? Acesse minha home page em http://ricardo-iramar.com.