Discuta este tópico no fórum

Se este conteúdo te ajudou, deixe um presente!

terça-feira, 20 de janeiro de 2015

OpenWRT: Servidor VPN com OpenVPN

Mais um artigo da série sobre o OpenWRT.

Uma das características que acho mais fascinante da a internet é a possibilidade de trabalhar de qualquer lugar. Muitas empresas já utilizam esta característica para permitir que seus funcionários trabalhem em viagem, de casa, de onde estiver. Afinal, cada posto de trabalho e o deslocamento custa um bom trocado. Para trabalhar, em geral, é necessário ter acesso as informações e serviços da rede interna da empresa.

Esta necessidade de acesso também é comum para o mundo residencial. Quando temos um serviço na rede interna em casa e que queremos acessar "de fora", a técnica mais comum é o encaminhamento de portas. Ela mapeia uma porta do roteador para um serviço de computador da rede interna. Contudo, isto expõe estes serviços a ataques externos. Normalmente, não é uma boa ideia para serviços muito populares ou sem segurança.

Também podemos fazer este acesso por encaminhamento de portas em uma conexão SSH. Funciona muito bem e, desde que o SSH não seja comprometido, é seguro. Só não é muito prático. Configurar os encaminhamentos individualmente para cada serviço pode ser um tanto trabalhoso. Os acessos não ficam muito práticos pois tudo estará em portas locais (127.0.0.1:xxxx). Não fica transparente para o usuário. Para ter um acesso de forma mais simples e transparente, podemos usar uma conexão VPN.

A VPN (virtual private network) permite a conexão de dois pontos através de uma rede virtual, como se existisse um cabo de rede ligando diretamente as duas pontas. Para os programas que utilizarem este "cabo virtual", não existirá diferença entre estar ligado diretamente na rede local ou estar a milhares de quilômetros (exceto que a velocidade da internet é algumas vezes mais lenta que a rede local). Como a internet não é um meio dos mais seguros para trafegar informações internas (alô Obama!), se tornou quase implícito a utilização de criptografia nas conexões VPN.

Existem algumas formas de prover esta conectividade. As mais comuns são pelo protocolo PPTP, L2TP/IPSEC, ou pelo OpenVPN. O primeiro, apesar de ser um dos mais antigos e mais largamente disponíveis, não é muito seguro e vou deixar de lado. O segundo também é bem comum e disponível nativamente em diversos ambientes, como Windows e Android. O OpenVPN é ótimo mas depende da disponibilidade e da instalação do cliente OpenVPN para seu ambiente. Como é um serviço completo em si, o OpenVPN é mais fácil de implementar o servidor. Vou começar por este.

O OpenVPN é relativamente tranquilo de instalar e possui clientes para diversos ambientes, inclusive plataformas mobile. A parte mais complicada é a autenticação. Esta normalmente é feita através de certificados emitidos por uma CA, que criaremos durante o processo (não precisa comprar certificados).

Você vai precisar de um roteador com OpenWRT (utilizarei o Barrier Breaker - BB - mas o AA também funciona), com 8 MB de flash ou disco expandido via unidade USB. Você também precisará editar alguns arquivos pelo terminal (SSH/Telnet). Seria bom conhecer ao menos o básico do editor vi. A interface WEB não é suficiente.

Na versão Barrier Breaker, existe 3 opções de openvpn:
  • openvpn-nossl (sem criptografia)
  • openvpn-openssl
  • openvpn-polarssl

A primeira é mais enxuta mas não utiliza criptografia, o que normalmente é um requisito de um serviço VPN. Os dois seguintes são equivalentes, variando apenas a implementação de ssl que será utilizada. O polarssl é mais enxuto tanto em funcionalidades como em tamanho. É muito interessante para ambientes com restrição de recursos como o roteador e provavelmente terá tudo que você precisa. Contudo, se você já tem o libopenssl instalado por requisito de outro pacote, não vale a pena instalar o polarssl em paralelo. No meu caso, como tenho outros pacotes que já exigem o openssl, vou instalar o segundo pacote (em destaque).

Também é interessante instalar o openvpn-easy-rsa. Ele cria a infraestutura de uma CA de fácil gerenciamento. Você poderia utilizar o certificado de outra autorizade certificadora. Porém, considero uma CA dedicada ao VPN a solução mais atraente, tanto por simplificar o gerenciamento como para restringir problemas de segurança. Afinal, o comprometimento desta CA dedicada fornecerá ao atacante acesso ao roteador, que já seria previamente um requisito para poder comprometer a CA.

opkg update
opkg install openvpn-openssl openvpn-easy-rsa

Já adiantando, se o roteador fosse utilizado como um cliente OpenVPN, o pacote seria o mesmo (openvpn-{nossl,openssl,polarssl}). Só não seria necessário o openvpn-easy-rsa.

Antes de configurar o openvpn, vamos montar a CA. O easy-rsa trabalha apenas com scripts para fornecer toda a funcionalidade de uma CA necessária para o OpenVPN. Os parâmetros que você deve querer alterar estão em /etc/easy-rsa/vars. Você vai querer alterar estes campos:

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

Existem outros campos como tamanho de chave e expiração do certificado que você pode querer aumentar ou desativar:

export KEY_SIZE=2048
# In how many days should the root CA key expire?
export CA_EXPIRE=3650
# In how many days should certificates expire?
export KEY_EXPIRE=3650

Agora é só criar a CA:

# clean-all # opcional para primeira execução
# build-ca # (com o /etc/easy-rsa/vars configurado, só seguir)
# build-dh # vai demorar...

Não é necessário mas gosto de sempre gerar a lista de certificados revogados e configurá-la no OpenVPN. Caso precise revogar um certificado, tudo está pronto. Porém, a versão do easy-rsa do OpenVPN só gera o crl.pem ao revogar um certificado. Você pode gerá-lo manualmente com este comando:

# (. /etc/easy-rsa/vars;  CRL="/etc/easy-rsa/keys/crl.pem"; KEY_CN="" KEY_OU="" KEY_NAME="" $OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG")

Agora podemos criar o certificado do servidor VPN e dos clientes:

# build-key-server server
# build-key cliente1
# build-key cliente2
# ...

Crie quantos clientes quiser e a qualquer tempo. Escolha nomes informativos como cliente-tablet-luiz. Quanto ao certificado do servidor, normalmente teremos apenas um durante toda a validade do certificado. Se trocar o nome de server para outra coisa, irá afetar os campos cert e key da configuração do OpenVPN.

Depois podemos configurar o servidor VPN. O arquivo de configuração fica em /etc/config/openvpn:


config 'openvpn' 'lan'

        option 'enable' '1'

        option 'port' '1194'

        option 'proto' 'udp'

        option 'dev' 'tun'
        option 'ca' '/etc/easy-rsa/keys/ca.crt'
        option 'cert' '/etc/easy-rsa/keys/server.crt'
        option 'key' '/etc/easy-rsa/keys/server.key'
        option 'dh' '/etc/easy-rsa/keys/dh2048.pem'
        option 'crl_verify' '/etc/easy-rsa/keys/crl.pem'
        option 'ifconfig_pool_persist' '/tmp/ipp.txt'
        option 'keepalive' '10 120'
        option 'comp_lzo' 'no'
        option 'persist_key' '1'
        option 'persist_tun' '1'
        option 'status' '/var/log/openvpn-status.log' 
        option 'verb' '3'
        option 'server' '192.168.2.0 255.255.255.0'
        option 'client_to_client' '1'
        list 'push' 'redirect-gateway def1'
        list 'push' 'dhcp-option DNS 192.168.1.1'
list 'push' 'route 192.168.1.0 255.255.255.0'

Os destaques tem as opções que você provavelmente quer alterar. A porta 1194 é a padrão e pode ser interessante trocá-la para evitar que uma varredura simples de rede achem seu OpenVPN. O crl_verify deve estar presente caso você tenha gerado o crl.pem que comentei anteriormente. Caso não deseje revogar certificados, remova-o. 

ifconfig_pool_persist permite que os endereços atribuídos a um cliente se mantenham na próxima conexão. Isto é equivalente ao arquivo leases do DHCP. Contudo, ao colocá-lo em /tmp, você irá perder este arquivo a cada reboot do roteador. Mude para /etc/openvpn/ipp.txt para manter mesmo após desligar o roteador ou remova a linha caso não queira manter os endereços.

A opção comp_lzo habilita a compactação do tráfego antes da criptografia. Isto poupa a quantidade de dados trafegados mas aumenta a carga sobre o roteador e também deixa a conexão um pouco mais lenta.

A opção server indica a faixa de endereços utilizada pelos clientes VPN. Ela não será a mesma da sua rede local. Procure escolher algo que não conflite com a rede local do servidor VPN e nem dos clientes (contudo algumas vezes não é possível conhecê-la previamente).

Os push finais são usados para enviar configurações ao cliente. As apresentadas criam a rota para seu cliente VPN falar com a LAN do servidor VPN. Caso contrário, ele somente irá ver o servidor VPN e não os clientes. Remova estas linhas se quer apenas acessar os serviço do roteador onde o servidor VPN está.

É hora de disparar o serviço:


/etc/init.d/openvpn start

Acompanhe pelo logread por possíveis erros. Isto é uma execução normal:

Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: OpenVPN 2.3.6 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on Jan  6 2015
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: library versions: OpenSSL 1.0.1j 15 Oct 2014, LZO 2.08
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: Diffie-Hellman initialized with 2048 bit key
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: Socket Buffers: R=[163840->131072] S=[163840->131072]
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: TUN/TAP device tun0 opened
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: TUN/TAP TX queue length set to 100
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: /sbin/ifconfig tun0 192.168.xx.1 pointopoint 192.168.33.2 mtu 1500
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: /sbin/route add -net 192.168.xx.0 netmask 255.255.255.0 gw 192.168.xx.2
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: UDPv4 link local (bound): [undef]
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: UDPv4 link remote: [undef]
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: MULTI: multi_init called, r=256 v=256
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: IFCONFIG POOL: base=192.168.xx.4 size=62, ipv6=0
Tue Jan 20 16:07:20 2015 daemon.notice openvpn(server)[7991]: Initialization Sequence Completed

Já está funcionando? Sim, mas não para os clientes externos. Disparamos o serviço neste ponto para o OpenVPN criar o dispositivo tun0. Isto permite que seja utilizado o Luci (interface web) para configurar o firewall. Você pode visualizar esta interface pelo "ifconfig" ou "ip add show".

No firewall, abra a porta 1194 UDP ou a que você definiu anteriormente para receber conexões externas. Está em "Rede/Firewall/Regras de Tráfego/Abrir portas no roteado".

Neste momento, os clientes já podem conectar ao serviço. Todavia, ao conectarem, existirá um cabo virtual entre o cliente e o dispositivo tun0 do roteador (versão simplificada da topologia). O problema é que tun0 não pertence a nenhuma interface do OpenWRT (e consequentemente, a nenhuma zona do firewall). Por padrão, este tráfego será descartado.

Pela interface Luci, adicione uma nova interface (sugestão de nome: vpn) no OpenWRT em Rede/Interfaces. Configure-a para ser não gerenciada e escolha o dispositivo tun0. Nesta mesma interface, você já pode atribuir uma zona do firewall. Se os clientes VPN terão privilégios iguais aos da rede local, basta adicionar a interface vpn à zona lan. Se quiser algo diferenciado, crie uma nova zona e defina a vontade as regras de filtragem.

Está pronto. Seus clientes devem estar prontos para conectar ao seu novo serviço.
Para isto, eles vão precisar:
  • /etc/easy-rsa/keys/<cliente>.crt
  • /etc/easy-rsa/keys/<cliente>.key
  • /etc/easy-rsa/keys/ca.crt
  • O endereço internet do seu roteador (pode ser o FQDN de um DNS dinâmico)
  • Saber se está usando a compactação (lzo) ou não
Para alguns clientes você vai precisar de um profile xxx.opvn. Existem algumas alternativas para criá-lo. Uma seria fazê-lo manualmente. É um arquivo texto neste formato

client
remote-cert-tls server
remote endereco-internet porta
comp-lzo yes
<ca>
conteúdo de ca.crt
</ca>
<key>
conteúdo de <cliente>.key
</key>
<cert>
conteúdo de <cliente>.crt
</cert>

Retire o comp-lzo se não usar a compactação no servidor. Também existem ferramentas para Linux e Windows que geram o .ovpn. Alternativamente, use este script diretamente no roteador.

Caso a conexão de um cliente não funcione, observe os logs tanto do OpenWRT (logread) como do cliente OpenVPN. Um sniffer de rede escutando na interface externa também ajuda. Testes de clientes VPN vindos da rede local para o endereço IP do roteador externo não irão funcionar automaticamente pois ele irá responder com o endereço IP interno e o cliente recusará a resposta vinda de outro endereço. É um problema muito parecido ao apresentado em um post antigoSe for testar de dentro da sua rede, use o IP interno do roteador (por padrão, 192.168.1.1).

Mas eu queria ter um endereço de dentro da rede (LAN) e não em uma faixa diferente (VPN). Tem como? Sim. Neste caso, o modo do túnel deve ser tap e não tun. Além disto, a interface tap0 teria que ser adicionada a br-lan. Porém, isto faz com que todas as mensagens broadcast da LAN sejam enviadas pelo túnel. Normalmente isto resulta em um bom desperdício de rede. Outro problema é que alguns clientes não suportam tap, como o android, devido a limitação da API VpnService (reclamem com o Google).

No próximo post mostro como fazer o outro lado configurando um cliente OpenVPN no roteador.

Atualizando: Alguma dúvida? Criei um fórum para o blog e vou criar um tópico para cada novo artigo.

Até a próxima.

sexta-feira, 5 de dezembro de 2014

OpenWRT: Balanceamento e redundância da sua conexão internet com mwan3

No passado, já escrevi sobre como fazer o balanceamento no OpenWRT utilizando o pacote multiwan. Porém, na nova versão BB foi disponibilizado uma nova solução, o mwan3, que permite um melhor gerenciamento de suas conexões, além de resolver alguns problemas da solução anterior como a impossibilidade de encaminhamento de portas.

Múltiplas conexões com a internet servem para duas funções. A primeira é manter o acesso com a internet mesmo que um dos provedores tenha algum problema (claro, opte por provedores independentes). Fora a redundância da sua conexão internet, você pode balancear o uso da internet entre as duas conexões, praticamente somando a velocidade disponibilizada.

Hoje, contratar uma nova conexão é barato, ficar sem internet é caro. A disponibilidade de mais de uma conexão com internet é fundamental para um negócio que dependa da internet. Além disto, mesmo em residências, estamos cada vez mais dispondo de múltiplas conexões com a internet. Provavelmente você tem um celular com 3G que pode compartilhar a internet, talvez um modem 3G ou mesmo utilizar a internet do vizinho (sempre pedindo autorização).

Existem soluções prontas no mercado para realizar esta tarefa. Contudo, neste post vamos utilizar um roteador com OpenWRT para realizar esta tarefa (e creio que com mais versatilidade do que qualquer outra solução).

O primeiro passo é instalar as suas múltiplas conexões internet no seu roteador. Você pode utilizar VLAN e transformar uma porta LAN em uma WAN2, conectar um 3G, ou acessar uma outra rede WIFI, seja ela do seu vizinho ou a internet compartilhada do seu celular. Claro, teste se ela está funcionando utilizando cada conexão com a internet isoladamente.

E se eu conectar as duas ao mesmo tempo? O roteador vai se perder? Não, existe um campo na configuração da interface, em avançado, onde você especifica a métrica da sua conexão. A métrica é o custo de usar a conexão. Desta forma, a conexão que estiver com a menor métrica será usada. Por padrão, este valor não está definido. Se for o mesmo valor ou não definido, ainda assim o roteador ainda vai escolher uma delas. Contudo, a definição da métrica é necessária para fazer o mwan3 funcionar.

Então só definir a métrica e terei redundância (mas não balanceamento)? Não é tão fácil assim. A conexão com a menor métrica será usada enquanto a interface relacionada a esta estiver levantada. Porém, a sua conexão internet pode cair sem que a sua interface seja derrubada. Ela só cairá sozinha se o cabo da WAN for desconectado ou o equipamento em que a conexão WAN estiver for desligado. Normalmente não é o que acontece. O mais comum é que seu equipamento está ligado e você não tem conectividade. Para gerenciar isto entra o mwan3.

O mwan3 monitora as suas conexões com a internet através de PING para verificar se esta está operando. Caso falhe, ela será desativada e os novos pedidos de conexões não irão mais utilizá-la. Enquanto estiver desativada, o mwan3 verifica repetidamente se ela voltou a operar. Caso detecte que está tudo bem, a sua conexão volta a operar junto com as demais.

Para balancear a carga, cada novo pedido de conexão pode ser atendido por uma das conexões WAN disponíveis. A escolha é aleatória (não é um Round-Robin), podendo utilizar um peso para aumentar a probabilidade de utilizar uma das conexões. Quanto mais clientes (pedidos de conexão) forem gerenciadas, maior a probabilidade do número de pedidos de conexão de cada WAN se aproximar do configurado e maior a probabilidade dos canais estarem distribuídos.

Instalação do mwan3


O pacote do mwan3 pode ser instalado tanto pelo modo texto como pela interface Luci. Você também pode instalar o módulo do Luci para configurar o mwan3 sem precisar do modo texto. Instale:

* mwan3
* luci-app-mwan3 (somente se for usar via interface Luci)

Configuração do mwan3


O mwan3 permite configurações muito mais avançadas do que o multiwan. Para permitir esta gama maior de cenários, o mwan3 utiliza algumas abstrações:

Interfaces


São mapeamentos 1 para 1 das interfaces WAN do OpenWRT (que já são abstrações das interfaces físicas). A interface do mwan3 serve apenas para adicionar mais campos à interface do OpenWRT, como as informações referentes a checagem da sua conexão internet.

Para adicionar uma nova interface, você pode ir no Luci em "Network/Load balancing/Configuration/Interfaces" e adicionar no campo ao final da página. O nome deve ser o mesmo utilizado na interface do OpenWRT (lembre-se, é um mapeamento). Além disto, a interface já deve ter alguma métrica definida (ainda em "Network/Interfaces" e não no mwan3) e possuir rota padrão (definida na configuração estaticamente ou via DHCP).

Ao adicionar a interface wman3, você deve escolher qual endereço na internet será utilizado para verificar que a sua conexão está funcionando. O normal é usar os DNS do Google (8.8.8.8, 8.8.4.4) mas recomendo adicionar no mínimo mais uns dois extra pois o Google aprontou ano passado. O resto é configuração de ajuste, como o "Tracking reliability", que define quantos dos endereço listados devem responder ao PING para considerar que a conexão está funcionando.

Adicione uma interface para cada interface WAN que você deseja balancear. Ex: tenho duas interfaces WAN: wan e wan3g. Elas devem estar funcionado e com uma métrica definida antes mesmo de iniciar a configuração do mwan3. Eu devo criar duas interfaces com exatamente o mesmo nome no mwan3: wan e wan3g. Em cada uma destas, devo configurar um ou mais endereços para verificar a conectividade.

Se preferir editar o arquivo de configuração diretamente, pode fazê-lo pelo modo texto (SSH, em /etc/config/mwan3) ou mesmo pelo Luci em "Network/Load balancing/Advanced/MWAN Config":

config interface 'wan'
   option enabled '1'
   list track_ip '8.8.4.4'
   list track_ip '8.8.8.8'
   option reliability '1'
   option count '1'
   option timeout '2'
   option interval '5'
   option down '3'
   option up '8'

config interface 'wan3g'
   option enabled '1'
   list track_ip '8.8.4.4'
   list track_ip '8.8.8.8'
   option reliability '1'
   option count '1'
   option timeout '2'
   option interval '5'
   option down '3'

   option up '8'

Members (Membros)


Membros são um segundo mapeamento das interfaces do mwan3 para adicionar duas novas informações: métrica e peso. Diferente do caso do item anterior onde uma interface OpenWRT mapeava uma interface MWAN3, este é um mapeamento de 1 (interface MWAN3) para 1 ou mais (membro) pois assim podemos ter valores distintos para uma mesma interface em situações distintas.

Para adicionar uma nova interface, você pode ir no Luci em "Network/Load balancing/Configuration/Members". Os nomes são livres mas devem ser diferentes das interfaces. A sugestão é utilizar o formato: <interface>_m<métrica> _w<peso>. Ex:

  • wan_m1_w3
  • wan_m2_w3
  • wan_m1_w4
  • wan_m2_w4
  • wan3g_m1_w3
  • wan3g_m2_w3
  • wan3g_m1_w4
  • wan3g_m2_w4

Desta forma, já pelo nome, é possível identificar o que foi configurado no membro (interface, métrica e peso). Ao criar o membro, selecione a interface mwan3 desejada, a métrica e o peso.

A métrica no membro representa uma informação similar ao que representa a métrica da interface do OpenWRT. Caso esteja disponível mais de um membro para a mesma situação, ele selecionará a interface do membro que tem a menor métrica. Porém, existe uma diferença em relação a métrica da interface. No membro, caso a métrica seja a mesma, o mwan3 vai fazer o balanceamento e não escolher apenas uma das interfaces.

E o peso? Na situação onde o mwan3 está fazendo o balanceamento (existe mais de um membro operacional com a mesma métrica e esta é a menor do conjunto), ele dividirá as conexões em função do peso. Se um membro usar o peso 3 e outro o peso 2 enquanto estiverem balanceando as conexões, 3/5 serão antedidas pelo primeiro membro e 2/5 pelo segundo (5 da soma de 3 e 2). Se for igual, será dividido de forma igual. Com isto você pode ajustar o uso das conexões em função da capacidade de cada conexão. Ex:
  • wan_m1_w3
  • wan3g_m1_w3
Balanceará entre as duas conexões wan e wan3g de maneira uniforme.
  • wan_m1_w3
  • wan3g_m1_w1
Balanceará entre as duas conexões wan e wan3g, sendo que 3/4 das conexões utilizarão wan e 1/4 a wan3g.
  • wan_m1_w3
  • wan3g_m2_w2
Utilizará a wan enquanto estiver no ar. Quando esta estiver indisponível, a wan3g será utilizada. O peso não influencia.

Se preferir editar diretamente o arquivo, é no mesmo local da interface:

config member 'wan_m1_w3'
   option interface 'wan'
   option metric '1'
   option weight '3'

config member 'wan_m2_w3'
   option interface 'wan'
   option metric '2'
   option weight '3' 

config member 'wan3g_m1_w3'
   option interface 'wan3g'
   option metric '1'
   option weight '3'

config member 'wan3g_m2_w3'
   option interface 'wan3g'
   option metric '2'
   option weight '3'

Policies (Políticas)


As políticas são agrupamentos de membros. Seria o mais próximo de uma tabela de roteamento. Dentro das políticas, as métricas e pesos dos membros serão utilizados para definir por qual interface a conexão irá utilizar. Normalmente é criada uma política para cada uma das situações:

  • Usar exclusivamente cada interface;
  • Usar uma interface preferencialmente e outra caso a primeira falhe;
  • Balancear a carga entre as interfaces.

Novamente, os nomes não devem colidir com os nomes das interfaces e dos membros. Ex:

  • somente_wan           (política)
    • wan_m1_w3    (membro)
  • somente_wan3g
    • wan3g_m1_w3
  • wan_wan3g
    • wan_m1_w3
    • wan3g_m2_w3
  • wan3g_wan
    • wan_m2_w3
    • wan3g_m1_w3
  • balanceado
    • wan_m1_w3
    • wan3g_m1_w3

A ordem dos membros não importa. O que importa é a métrica definida no membro e, onde esta for igual, o seu peso relativo.

Para adicionar uma política pela interface Luci, vá em "Network/Load balancing/Configuration/Policies". Após adicionar uma nova política, você deve adicionar os membros desejados. Também é dado a opção de selecionar qual o comportamento em último caso (quando todas as interfaces dos membros desta política estiverem inoperantes). Pode-se optar rejeitar a conexão (reject - o usuário tem resposta imediata), descartar (drop - a conexão do usuário falhará por estouro de tempo) ou usar a rota padrão do sistema. Se não for especificado, o comportamento será o reject.

Para configurar as políticas diretamente no arquivo, é o mesmo das demais configurações:

config policy 'balanceado'
   list use_member 'wan_m1_w3'
   list use_member 'wan3g_m1_w3'
   option last_resort 'unreachable'

config policy 'wan3g_wan'
   list use_member 'wan_m2_w3'
   list use_member 'wan3g_m1_w3'
   option last_resort 'unreachable'

config policy 'wan_wan3g'
   list use_member 'wan_m1_w3'
   list use_member 'wan3g_m2_w3'
   option last_resort 'unreachable'

config policy 'somente_wan'
   list use_member 'wan_m1_w3'
   option last_resort 'unreachable'

config policy 'somente_wan3g'
   list use_member 'wan3g_m1_w3'
   option last_resort 'unreachable'

Rules (Regras)


Enfim, o último passo. As políticas definidas anteriormente devem ser chamadas segundo alguma regra, que pode ser baseada nos endereços e portas de origem e destino ou mesmo no protocolo (que você normalmente vai se limitar em TCP ou UDP).

As regras podem ser definidas pela interface Luci, vá em "Network/Load balancing/Configuration/Rules". Você deve definir um nome único (não utilizado por outros objetos), os critérios para selecionar o tráfego e qual política será aplicada a este tráfego. O mais comum é utilizar o balanceamento para tudo exceto o que deve manter o IP durante a sessão. Um exemplo onde deve-se preservar o IP externo são páginas de bancos. Como boa prática, deve-se preservar o endereço externo para todo tráfego HTTPS. Para estes casos, pode-se utilizar o endereço do cliente para balancear as conexões. Uma boa dica para balancear entre duas conexões é usar o último bit do endereço IP, que dividirá os clientes entre os com endereço IP terminando em par ou ímpar.

Diferentemente dos demais itens de configuração, as regras possuem ordem. Caso o tráfego case com uma delas, ele não será validado pela próxima. Assim, deve-se colocar as regras mais específicas antes da mais genéricas e uma global, que case com todo o tráfego, ao final. Ex:

  • cliente_par_https
    • origem 0.0.0.0/0.0.0.1
    • protocolo tcp
    • porta 443,8443
    • política wan_wan3g
  • cliente_impar_https
    • origem 0.0.0.1/0.0.0.1
    • protocolo tcp
    • porta 443,8443
    • política wan3g_wan
  • padrao
    • origem 0.0.0.0/0.0.0.0
    • política balanceado

Para configurar as políticas diretamente no arquivo, é o mesmo das demais configurações:

config rule 'cliente_par_https'
  option src_ip '0.0.0.0/0.0.0.1'
  option proto 'tcp'
  option use_policy 'wan_wan3g'
  option dest_port '443,8443'

config rule 'cliente_impar_https'
  option src_ip '0.0.0.1/0.0.0.1'
  option proto 'tcp'
  option use_policy 'wan_wan3g'
  option dest_port '443,8443'

config rule 'padrao'
  option dest_ip '0.0.0.0/0'
  option use_policy 'balanceado'

Caso tenha necessidade que algum cliente ou destino específico saia somente por um endereço (ex: uma aplicação remota liberara apenas para o seu endereço da internet), basta adicionar uma regra acima das demais. Também fixar a saída em apenas uma conexão pode ser uma estratégia interessante para isolar possíveis problemas de uma aplicação quando se suspeita que a causa seja o balanceamento.





A solução mwan3 possibilita ajustar o balanceamento a quase qualquer situação, inclusive melhor do que outros produtos de mercado. Além disto, ao utilizar um equipamento de uso geral, o custo também deve ser inferior as soluções dedicadas. De fato, mesmo as soluções dedicadas não utilizam um hardware muito diferente de um roteador geral. Em muitos casos, é apenas um software diferente.

Já estou usando o mwan3 sem problemas faz algum tempo. Mas podem aparecer algumas questões como "Meu download não duplicou, ficou no mesmo". Sim, qualquer solução baseada em NAT faz o balanceamento por conexão. Um download único não vai conseguir utilizar mais do que uma das WAN. Para utilizar as duas, você precisaria fazer dois downloads em paralelo (ou usar um gerenciador de download que baixe o arquivo por múltiplas conexões - alguém lembrou do GetRight?). Mesmo assim, a escolha da WAN é aleatória e pode ser que você tenha o "azar" de sair nas duas conexões pelo mesmo canal. Se estiver baixando de um HTTPS (cada vez mais comum) e você seguiu as configurações sugeridas aqui, você sempre vai sair pela mesma conexão a partir do mesmo computador e, sim, não vai utilizar mais do que uma WAN em um download, neste caso mesmo que use um gerenciador de download. E torrent? Vai funcionar perfeitamente! Seu download provavelmente se aproximará da soma das duas WAN pois o torrent utiliza diversas conexões em paralelo.

Alguma solução para não usar NAT? IPv6. Mas as Telecoms no Brasil estão meio atrasadas. Era para todos terem IPv6 em janeiro de 2014. Quem sabe em um futuro, quando todos estiverem com IPv6 e terem uma faixa de endereços própria (que nem é previsto), podemos buscar uma solução melhor.

Para finalizar, se você é daqueles que desmontava o relógio para saber como ele funcionava, o mwan3 é bem interessante. Olhe em:

  • iptables -t mangle -L
  • ip rule show
  • ip route show table 1
  • ip route show table 2
  • ip route show table 3
  • ...
  • ip route show table N (até que retorne uma tabela em branco)

O mwan3 usa as interfaces ativas e as métricas para construir as regras do iptables e as tabelas no ip route. A tabela mangle do iptables é utilizada para marcar os pacotes (onde são usados as regras e pesos). Cada marca representa uma interface de saída. Esta marcação é usada nas regras do "ip rule", que escolhe uma tabela de roteamento para cada marca. Tudo é ajustado caso alguma interface com menor métrica se torne operante ou deixe de funcionar.

Até a próxima.

sexta-feira, 21 de novembro de 2014

OpenWRT: Atualizando para versão 14.07

Com o lançamento da nova versão do OpenWRT 14.07 (comentários), é chegada a hora de mais um upgrade. Prepare suas duas horas de janela de mudança, avise seus clientes da indisponibilidade do serviço internet e mão na massa.

Sim, este artigo repete diversos pontos do artigo de atualização anterior.

96,72% dos problemas com instalação/atualização com OpenWRT que ajudo é em relação a escolha incorreta da imagem da firmware. Como sempre, recomendo a versão squashfs, que possui modo de recuperação. Pegue o arquivo no download do Barrier Breaker e nunca em um endereço qualquer, mesmo que seja na wiki do OpenWRT. Normalmente a wiki referencia a versão em desenvolvimento, que não é o que você quer. No diretório de download, navegue seguindo o caminho da "arquitetura alvo" em uso no seu roteador. Você pode vê-la olhando o arquivo /etc/openwrt_release:
root@router:~# cat /etc/openwrt_release
DISTRIB_ID="OpenWrt"
DISTRIB_RELEASE="12.09"
DISTRIB_REVISION="r36088"
DISTRIB_CODENAME="attitude_adjustment"
DISTRIB_TARGET="ar71xx/generic"
DISTRIB_DESCRIPTION="OpenWrt Attitude Adjustment 12.09"
A diferença entre a primeira instalação e a atualização é que não será usada a imagem "factory" e sim a "sysupgrade". Escolha o arquivo correspondente ao seu roteador (inclusive versão de hardware!). E muito importante, leia a wiki do seu roteador independente se ele já funcionava na versão anterior! São poucos minutos de leitura que podem salvar horas de trabalho ou mesmo seu roteador.

Bem, se eu simplesmente ir na interface, fornecer a nova imagem, ele vai funcionar? Provavelmente, mas talvez não é a maneira que dê menos trabalho. A atualização pode preservar as configurações mas não os programas instalados. Se você tem disco raiz em unidade externa, a encrenca é ainda maior. Quem usa WDS para conectar dois segmentos de rede via wireless também pode ter que fazer um pequeno ajuste nos clientes, já que o BB não muda o SSID com múltiplos SID.

Mas eu nunca instalei um programa! OK, use a interface web e provavelmente todas as configurações serão migradas sem problemas. Mas faça o backup antes! Caso contrário, continue lendo.

Em primeiro lugar, precisamos do plano de retorno caso a nova versão não se comporte como o esperado. Faça um backup geral do seu sistema. Sugiro três coisas diferentes: backup gerado pelo openwrt, lista de pacotes instalados e todos os arquivos do overlay.

A primeira e mais simples é o backup que pode ser gerado pela interface WEB do OpenWRT. Este é obtido na mesma página de atualização de firmware do seu roteador. Ele contém uma seleção prévia de várias configurações, inclusive tudo que está em /etc/config. Contudo, o backup não irá manter outros arquivos modificados em /etc ou em outro lugar. Por exemplo, se você fez alguma modificação no /etc/dnsmasq.conf, ele não será preservado pois este arquivo não está selecionado para ser copiado. Se criou um script em /bin ou para os botões em /etc/hotplug.d/button, ele não será preservado. Para incluir estes e outros casos, informe o caminho destes arquivos extras em /etc/sysupgrade.conf. Na interface WEB também tem a edição deste arquivo, no mesmo local da atualização da firmware, na parte de configuração. Gere um arquivo de backup novo e verifique se tudo que você quer está lá dentro. Somente estes arquivos serão preservados em um upgrade.
Dica: olhe todo o conteúdo em /overlay. Ele terá tudo o que foi modificado. Cuide principalmente dos arquivos em /etc.
Porém, o backup do openwrt não é feito para guardar os programas instalados. Ele se limita a scripts, dados e arquivos de configuração pré-configurados e os listados em /etc/sysupgrade.conf. Programas instalados por pacotes devem ser reinstalados manualmente. Por isto a próxima sugestão.

A segunda sugestão é gerar uma listagem de todos os pacotes instalados. Ela será usada de referência para reinstalar todos os seus programas. Como os programas não serão preservados (somente suas configurações e se estiverem no backup) você terá que reinstalá-los. Em geral, é uma meia dúzia de programas. A lista dos pacotes instalados pode ser obtido pela interface web ou pelo comando "opkg list-installed". Contudo, eu prefiro observar o diretório /overlay/usr/lib/opkg/info. Como cada pacote instalado cria um arquivo de controle neste diretório e o /overlay terá somente os arquivos modificados, você terá ao menos um arquivo por novo pacote instalado. O comando abaixo lista todos estes pacotes instalados após a gravação da firmware:
find /overlay/usr/lib/opkg/info/ -name '*.control' -exec basename {} \; | sed -e 's/\.control$//' | sort
Em geral, se não souber para que serve, ignore as bibliotecas (lib*). Elas serão instaladas automaticamente quando os pacotes que dependem delas forem instalados.

A terceira sugestão é fazer um backup completo de todo o /overlay. Afinal de contas, falamos de poucos megabytes mas que são fruto de algumas horas de trabalho. A cópia pode ser feita com um tar. É provável que você não tenha espaço para criar este tar diretamente no roteador. Você terá que fazê-lo jogando em um disco externo conectado pela USB ou, a forma que eu geralmente uso, diretamente pela rede. Pela rede seria assim:
meucomputador$ ssh root@roteador tar -czv /overlay | cat > overlay.tar.gz
A vantagem deste backup é que, se esquecer de colocar algo em /etc/sysupgrade.conf, você poderá recuperá-lo do arquivo tar.gz. Também, se precisar retornar ao firmware antigo, você já teria uma partição overlay pronta. Bastaria instalar a firmware antiga e jogar o conteúdo da overlay por cima (preferencialmente em modo de recuperação!).

Agora, finalmente, você está pronto para enviar a nova firmware. Se você usa um espaço externo para expandir o disco, leia até o final deste post. Faça o upgrade pela interface web ou pelo terminal. Inclusive, você pode baixar o arquivo diretamente no roteador. Ex:
cd /tmp
wget http://downloads.openwrt.org/barrier_breaker/14.07/..../openwrt...xxx...img
sysupgrade openwrt...xxx....img
 
Agora é a hora que você reza.

Se optar por preservar as configurações, tudo que seria guardado em um backup do sistema, inclusive o que está listado em /etc/sysupgrade.conf, será automaticamente levado ao novo sistema. Depois de o sistema iniciar na próxima versão e estiver funcionando, é hora de retornar os programas antigos. Se você guardou a lista dos programas instalados após a gravação da firmware que sugeri anteriormente, já terá a lista do que instalar.

A mudança nas versões dos pacotes é esperada e pode ser desconsiderada. Para facilitar, tente instalar primeiro os pacotes que dependem de outros, como os pacotes luci-app-*, antes de instalar os demais. É provável que, pela cadeia de dependências, grande parte será automaticamente instalada. Repita a geração dos programas instalados, a comparação e a instalação até estar satisfeito.

Não é comum no OpenWRT mas pode existir alguma atualização de segurança importante, como ocorreu com o Heartbleed. Na versão 14.07 apareceu uma vulnerabilidade do hostapd, que faz autenticação dos usuários. Se sua rede possui clientes não confiáveis (principalmente se você é um alvo em potencial), é bom atualizar. Os arquivos com a vulnerabilidade estão na imagem original e não foram atualizados. Para corrigir, você precisa instalar após a gravação da firmware. Esta atualização ocupará espaço a mais do seu disco (overlay) pois apagar ou substituir arquivos existentes na firmware original não recupera o espaço em disco usado.


Se quiser atualizar e estiver com espaço livre na overlay, a atualização é simples:
opkg update
opkg list-upgradable
E faça um "opkg install xxx" para os pacotes "xxx" listados. Ex:
opkg install wpad-mini hostapd-common
No futuro, novos pacotes com problemas de segurança podem ser atualizados e aparecerão no list-upgradable.

Por fim, faça um novo backup geral. É sempre bom preservar o seu trabalho.

Hum, e eu que uso um disco externo para expandir o espaço internoÉ um pouco mais complicado... Ao atualizar o sistema, você terá um kernel novo que é incompatível com os módulos de kernel existentes no disco externo ou mesmo com as bibliotecas deste pertencentes à versão anterior. Você precisaria reinstalá-los. Esta é a sugestão de como proceder:

Em primeiro lugar, gere todos os backups sugeridos anteriormente. É importante preservar seu trabalho anterior. Ainda sem instalar a nova firmware, reinicie o sistema sem o disco externo. Se você seguiu minha sugestão, você ainda terá um ambiente básico funcional. Com isto, ele vai usar somente a flash interna (com a configuração que você tinha antes de usar o disco externo). Faça todos os backups novamente, preservando os anteriores.

Agora à instalação.

Ainda com o disco externo desconectado, instale a nova firmware. Faça uma configuração básica, que será o que você terá caso o roteador seja ligado sem a unidade externa. Caso tenha optado por não preservar as configurações na gravação, você pode aproveitar o backup gerado ainda na versão anterior mas com o disco desconectado.

Agora precisamos nos livrar de todos os arquivos da versão anterior do OpenWRT presentes no disco externo. No disco externo, na partição usada como overlay, remova todo o conteúdo ou mova tudo para um subdiretório (ou para outro disco se não estiver com espaço livre) afim de que este não seja usado. Como sugestão, crie um "openwrt-versao-xxx" e mova tudo para lá. Refaça a configuração de uso do disco externo (que no mínimo será reinstalar os pacotes necessários). Reinicie o sistema. Você deve estar com mais espaço em disco agora.

Neste ponto, você ainda terá as mesmas configurações que tinha quando usou o sistema sem o disco externo. Envie o primeiro backup da versão anterior feito ainda com o disco externo e siga os passos de reinstalação dos pacotes, assim como é feito para ambientes sem o disco expandido. Complete o trabalho com aquele backup final.

Espero que apreciem a nova versão. De agora em diante, vou apenas focar em configurações específicas do 14.07, que ainda podem funcionar nas versões 12.09 e 10.03.1.

Até mais.

segunda-feira, 3 de novembro de 2014

OpenWRT: Barrier Breaker (14.07)

Salve pessoal! Mais um artigo da série do OpenWRT.

Quem está acompanhando as notícias do mundo de TI deve ter notado que foi lançada uma nova versão do OpenWRT, a Barrier Breaker (a.k.a BB, 14.07). Como fazem dois anos desde a última versão estável, é uma significativa mudança. Então quer dizer que eu vou atualizar e minha vida vai mudar?! Não é bem assim. Dependendo do caso, você nem vai notar. Afinal, o que a BB trouxe de novo? Vamos aos destaques:
  • Kernel atualizado para 3.10
Isto traz diversas correções, atualizações de drivers e outras funcionalidades desde o kernel 3.3. Se você nunca precisou olhar qual a versão do kernel no seu OpenWRT, provavelmente não sentirá diferença. Existe diversas correções para problemas com placas atheros, mas parece que nem todos os problemas antigos foram sanados. Atualização: mas resolveu todos os que eu tinha ;-)
  • Suporte nativo IPv6
Para sortudos que já tem acesso à redes IPv6 nativa, a nova versão do OpenWRT deve ser uma das mais adaptadas ao mundo de pilha dupla. Para os demais, continuamos a depender de gambi... estratégias de contorno técnicas como túneis, que já comentei anteriormente. Você vai observar também o surgimento de uma nova interface wan6, dedicada ao suporte IPv6. Ela muda a forma de configurar IPv6, a exemplo do uso de túneis. Devo atualizar o artigo de IPv6 em breve.
  • Novo init: procd
O procd seria o equivalente ao systemd no OpenWRT. Com a alteração, os scripts de iniciação dos serviços precisam de ajustes. Caso tenha feito algum, deve ser necessário atualizá-lo. Como ele substituiu o hotplug2, pode ter algum efeito colateral nos scripts em /etc/hotplug.d/, como as funções acionadas por botão. Entretanto, parece que ao menos nesta versão, ele tem comportamento compatível com scripts antigos.
  • Suporte a snapshot e rollback
Ainda não tive a oportunidade de mexer neste recurso mas ele permite que você crie fotos de seu ambiente (no caso, as mudanças da overlay) e permite que você retorne a um estado anterior em caso de falha. Contudo, isto mexe um pouco a forma de trabalho, exigindo que você explicitamente save o estado atual do disco antes de reiniciar o roteador. Vou deixar isto para um artigo futuro.
  • Pacotes atualizados!
Entre os diversos pacotes disponíveis no OpenWRT, muitos sofreram atualização. Isto pode trazer aquele recurso que você sentia falta e nem sabia. Ou não.
  • Novo tema no Luci
Esta sim é uma mudança perceptível! A parte de "melhoria visual" é pessoal mas achei o novo tema mais limpo.
Se nenhum dos itens acima te motivou, resta o argumento do suporte. A versão anterior cairá em desuso. Neste blog, por exemplo, todos os novos trabalhos serão em relação ao BB. Deixarei as referências ao AA e posso citar como deveria funcionar na versão anterior mas as configurações não serão testadas. O mesmo vale para fóruns, wiki e outros meios.

E algum motivo sério para não atualizar? Sim, se você tem uma conexão com a internet de mais de 180MBit/s. Houve relatos de redução na capacidade de roteamento via NAT, antes em algo como 240Mbit/s, com a atualização. Provavelmente é um problema do kernel ou mesmo do compilador (ou uma interação entre eles). De qualquer forma, vai ser difícil a solução. Melhorias já ocorreram na versão em desenvolvimento mas são marginais. Simplesmente falta capacidade de processamento da CPU (lembre-se, ela normalmente roda em algo como 400Mhz!).

Se você está neste limite e precisa de algo mais rápido, provavelmente o firmware original seja o mais indicado. Ele possui o recurso de aceleração de NAT por hardware, que libera o uso da CPU. Com ele, você vai poder realizar NAT a quase a velocidade do fio (uns 900MBit/s). Como não existe um driver aberto para este recurso, dificilmente ele estará no curto prazo no OpenWRT. Acredito que quem está com uma conexão internet via fibra de mais de 150Mbit/s já deve ter trocado o roteador de R$100 por algo melhor ;-)

Logo vou atualizar o artigo de atualização do OpenWRT para incluir o BB.

E a próxima versão? CC? Sim, Chaos Calmer. Prometeram para o final deste ano mas acho difícil. Não acredito no prazo não tanto pela base do OpenWRT mas sim pelos pacotes extras, os feeds. Muitos pacotes estavam abandonados e desatualizados. Um dos prováveis motivos era a necessidade de enviar as atualizações via lista e esperar a boa vontade de alguém com permissão de commit para aplicá-lo. Isto pode funcionar para o núcleo do OpenWRT mas não é muito prático para as várias centenas de pacotes extra. Desta forma, os pacotes anteriores foram congelados em oldpackages e uma nova fonte foi construída no github. Se seu pacote favorito já não estiver no novo repositório do github e você não quiser que seu pacote desapareça do OpenWRT CC, você pode adotá-lo. Eu já fiz a minha parte adotando o ruby.

Até a próxima.