O OpenWrt é uma distribuição Linux facilmente customizável que foi originalmente concebida para substituir a firmware padrão (e geralmente proprietária) de roteadores sem-fio (WiFi) comuns – desses que temos em casa.
A flexibilidade é sua principal característica. Ao substituir a firmware original de um roteador, ganha-se a liberdade e a capacidade de se integrar novas funcionalidades ao dispositivo, que antes não seriam possíveis. Por exemplo, é possível instalar o OpenVPN e criar um túnel. Ou instalar ferramentas de IoT, como um broker MQTT, sem a necessidade de adicionar mais um device à sua rede. Essas funções, normalmente, estão disponíveis apenas em dispositivos mais caros, e com o advento do OpenWrt podem ser implementadas em roteadores da faixa das poucas centenas de Reais.
O projeto nasceu em 2004, a partir da disponibilização do código-fonte da firmware do roteador Linksys WRT54G, que possuía muitas partes que estavam sob licença GPL. Em 2016, um grupo de desenvolvedores do OpenWrt criou um novo projeto derivado deste (fork) chamado LEDE (Linux Embedded Development Environment). Este grupo discordava de uma série de regras e políticas dentro do projeto original que, segundo eles, atrapalhavam o seu desenvolvimento. Essa separação perdurou até janeiro de 2018, quando o anúncio da reunificação dos projetos foi anunciada. A base de código adotada a partir de então passou ser a do projeto LEDE (v17.01), mas a marca OpenWrt foi mantida.
Arquitetura do OpenWrt
Estrutura de build
É possível fazer o download de imagens prontas do OpenWrt para diversos modelos de roteadores e placas de desenvolvimento, mas para aproveitar o máximo do projeto, o interessante é (cross-)compilá-lo a partir de seus fontes.
O sistema de build do OpenWrt é baseado no Buildroot – que já foi abordado anteriormente aqui no Embarcados, veja no final do artigo – com grandes customizações. Ao compilar o projeto, o sistema cria o ambiente de cross-compilação, compilando a cross-toolchain para o target selecionado na configuração. Por exemplo, no caso dos roteadores, é comum que o alvo seja um SoC de arquitetura MIPS.
A liberdade do projeto se estende também à toolchain. É possível escolher a versão do gcc e do binutils, e mais interessante ainda, a implementação da libc: entre o musl (padrão desde a versão 17) e o uClibc.
Sistema de arquivos
O OpenWrt adota o OverlayFS, o SquashFS e o JFFS2 para gerar o sistema de arquivos do sistema operacional. O layout de partições contém basicamente duas partições: a /rom e a /overlay. A /rom é uma partição somente leitura formatada como SquashFS, que contém todos os arquivos e estrutura de diretórios originais, do momento de criação (build) da imagem do OpenWrt. O /overlay é a partição, formatada com JFFS2, do sistema de arquivos que tem permissão de escrita. A /overlay é “sobreposta” a /rom para criar um / (root) transparente para o usuário. Essa sobreposição permite, por exemplo, que você possa alterar arquivos presentes na /rom, sem, de fato, alterá-los, pois as mudanças ocorrem na sobreposição, e não na partição /rom propriamente dita. Esse recurso facilita a recuperação do estado inicial do sistema (hard reset), tal qual quando o OpenWrt foi instalado no dispositivo.
Pacotes
As aplicações no OpenWrt são distribuídas em pacotes ipk que podem ser instaladas com o gerenciador opkg, comum em distribuições Linux Embarcado. Há mais de 2000 aplicações pré-compiladas.
Caso um software específico não faça parte do projeto, é possível integrá-lo com pacotes de contribuidores independentes ou criar seus próprios pacotes.
Criar os próprios pacotes não é tarefa complicada, basta criar um Makefile com macros específicas para o OpenWrt. O sistema de build se encarrega de baixar os arquivos de um repositório ou de um endereço na internet e posteriormente (cross-)compilá-los para a plataforma determinada nas configurações.
Componentes
O OpenWrt implementa cinco softwares básicos que, de maneira geral, são responsáveis pelo funcionamento de todo sistema operacional:
- UCI (Universal Configuration Interface): Responsável por centralizar e padronizar a configuração de (quase) todos os softwares integrados ao OpenWrt. Toda a configuração controlada pelo UCI fica armazenada exclusivamente no diretório /etc/config. Por exemplo, é possível configurar o servidor SSH, como o Dropbear, alterando as opções em /etc/config/dropbear. O UCI se encarrega de buscar e alterar os arquivos de configuração originais do Dropbear;
- procd (process daemon): É um gerenciador de processos. Responsável por inicializar e finalizar processos. Os processos são controlados por scripts em /etc/init.d/. Por exemplo, para iniciar o servidor SSH dropbear, basta rodar /etc/init.d/dropbear start. Para adicioná-lo à inicialização do sistema (para rodar automaticamente após o boot) basta rodar /etc/init.d/dropbear enable – esse comando cria um link simbólico em /etc/rc.d/ com um número de prioridade determinado no script em init.d;
- uBUS: É um barramento de comunicação entre processos e/ou aplicações. Permite que esses processos troquem mensagens via sockets UNIX. O comando ubus apresenta dados sobre serviços, devices e aplicações em formato JSON, o que facilita a integração com scripts e outras aplicações;
- netifd: É um daemon focado em configurar interfaces e conexões de rede. Dentre suas funcionalidades, destaca-se a não necessidade de reiniciar as interfaces de rede quando alguma configuração é alterada;
- LuCI: É a interface web de configuração do sistema. É semelhante às páginas de configuração presentes em roteadores, onde é possível configurar a rede wifi, acesso à internet, regras de firewall, etc.
Instalando na Raspberry Pi 3
É hora de experimentar o OpenWrt, compilando a distro para a Raspberry Pi 3.
Você precisará de algumas ferramentas para compilar o OpenWrt: make, gcc, binutils, bzip2, flex, python, perl, find, grep, diff, unzip, gawk, subversion, libz-dev e libc-dev.
Se você estiver usando o Ubuntu ou um de seus derivados, execute o comando abaixo para instalar essas ferramentas:
$ sudo apt-get install aptitude $ sudo aptitude install make gcc binutils bzip2 flex python perl grep git unzip gawk subversion libz-dev libc-dev libncurses-dev time wget g++ xz-utils
O primeiro passo é fazer o clone do repositório:
$ git clone https://github.com/openwrt/openwrt.git
Após o clone, recomenda-se dar checkout na branch da próxima versão estável – que é a 18.06 – pois por ser sua primeira vez com o OpenWrt é provável que você enfrente alguns problemas ao tentar compilar a partir do código dos commits mais recentes.
$ cd openwrt $ git checkout -b openwrt-18.06
Em seguida, é necessário sincronizar a base de pacotes disponíveis para a distro. Esta etapa disponibiliza os pacotes para serem (cross-)compilados junto aos demais componentes da distribuição (Kernel, uBUS, netfid UCI e etc.).
$ scripts/feeds update -a $ scripts/feeds install -a
Como citado anteriormente, é possível instalar os pacotes pré-compilados em tempo de execução, desde que o opkg seja habilitado durante a compilação da distro.
No próximo passo deve-se selecionar os pacotes que integrarão a imagem, a plataforma-alvo, a toolchain e etc. Para abrir o menu de configurações rode o seguinte comando:
$ make menuconfig
Na tela do menuconfig, deve-se escolher o sistema alvo. No caso da Raspberry Pi 3, em “Target System” selecione “Broadcom BCM27xx”. No item seguinte, “Subtarget”, selecione “BCM2710 based boards”. Por fim, em “Target Profile” selecione “Raspberry Pi 3 B/CM”. A tela do menuconfig deve ficar semelhante a esta:
A partir de “Base System”, os itens do menu abrem outras janelas que apresentam os pacotes que podem ser integrados à imagem. Por exemplo, para integrar um interpretador Python à imagem, selecione “Languages > Python > python”.
Para facilitar a configuração de rede, recomenda-se a instalação do pacote Luci. Para isso, no menu selecione LuCI. No próximo menu, selecione “Collections”, e em seguida, “luci”. Volte um menu, selecionando “exit”, movendo o cursor com as setas (esquerda ou direita) do teclado. Ainda do submenu LuCI, selecione “Modules”, em seguida, “Translations, e por fim “Brazilian Portuguese (pt-br)”.
Quando estiver satisfeito, selecione “exit”. Será perguntado se deseja salvar a configuração, responda “Yes”.
Por fim, basta dar o comando de build e aguardar (deve demorar um pouco).
$ make
(Este processo é demorado! Aguarde até que o build finalize completamente).
O resultado é uma imagem que fica armazenada no diretório openwrt/bin/targets/brcm2708/bcm2710/. O arquivo deve chamar algo como openwrt-brcm2708-bcm2710-rpi-3-ext4-sdcard.img.
Obs: caso o arquivo gerado seja do tipo .gz, é necessário descompactá-lo primeiramente com $ gunzip openwrt-brcm2708-bcm2710-rpi-3-ext4-sdcard.img.gz
Grave esse arquivo no sdcard com o comando dd.
$ sudo dd if=openwrt-brcm2708-bcm2710-rpi-3-ext4-sdcard.img of=/dev/<SDCARD>
Se preferir, utilize uma ferramenta gráfica para gravar o sdcard, como o Etcher.
Uma vez gravado o SDCard, conecte o cartão na Raspberry Pi 3 e conecte a placa na alimentação. A luz verde (led de atividade) da Raspberry deve piscar ao longo da inicialização. Neste primeiro momento só é possível conectar-se à placa através da rede cabeada. Conecte, então, um cabo de rede ao seu computador e à placa.
Cheque se seu computador conectou-se à Raspberry através da conexão cabeada. O IP da Raspi, que neste caso atua como gateway, normalmente é 192.168.1.1.
A seguir, já é possível acessar a placa através de ssh e, assim, ativar a conexão wireless.
$ssh root@192.168.1.1
Uma vez criado o acesso via SSH com a placa, é possível habilitar a interface de rede wifi da Raspberry através do sistema de configuração UCI:
$ uci set wireless.radio0.disabled=0 $ uci commit wireless
Recarregue as configurações na interface de rede com o comando:
$ wifi
A partir desse momento, o OpenWrt cria uma rede Wifi chamada “OpenWrt”, transformando a Raspberry Pi em um roteador Wifi. Conecte o cabo de rede a seu modem do provedor de internet e configure o acesso a internet pelo browser acessando a LuCI em 192.168.1.1. O login é root e não há senha, basta clicar em login.
Caso a interface da LuCi não esteja em português, vá até o menu “System”, e, em seguida, “System”, novamente. Vá até a aba “Language and Style”, e na caixa “Language” troque de “auto” para “Português do Brasil”. Salve as configurações em “Save and apply” (no final da página).
Para finalizar, configure a rede cabeada indo em “Rede” > “Interfaces”. Na interface “Lan” , clique no botão editar. Edite as configurações e salve no final da página.
Agradeço ao Eng. Tiago Medicci Serrano que colaborou na realização deste artigo.
Saiba mais
Criando uma imagem customizada para a BeagleBone Black com Buildroot
Linux customizado e início de programas após boot usando RPi e Buildroot
Arquiteturas de um projeto Wireless (Wi-Fi)


