Por que a detecção do Portal Cativo do Android não aciona uma janela do navegador?

2

Eu tenho um Raspberry Pi que hospeda um site simples usando o nginx. o RPi está agindo como um ponto de acesso sem fio - os usuários podem se conectar ao seu wireless rede, o RPi dá a eles um IP (ele executa um servidor DHCP), e eles podem acessar o site.

Como o RPi na verdade não fornece aos usuários internet (apenas este site), facilitei a localização do site pelos usuários. Em vez de saber o URL exato do site, eu disse ao meu servidor dns (dnsmasq) que o servidor DHCP informa aos clientes para usar, para resolver todas as consultas ao IP da LAN do meu RPi (192.168.30.1).

Neste ponto, meu nginx tem uma entrada em sua configuração que diz:

  • se o campo do host da solicitação do usuário não for MyRPiServer.com, envie um redirecionamento 302 para MyRPiServer.com
  • se o host for MyRPiServer.com, veicule o site local

Isso funciona muito bem.

Eu queria dar um passo adiante. Quando o Android se conecta a uma rede sem fio, ele tenta se conectar ao link (ou a uma das outras páginas semelhantes do google) especificamente para verificar se a solicitação está sendo redirecionada. Se obtiver um código 204, assumirá que tudo está bem. Se isso não ocorrer, ele supõe que esteja atrás de um portal cativo e abre uma janela do navegador que abre o login do portal cativo.

Por alguma razão, quando eu digo ao nginx para responder aos pedidos da página generate_204 com um redirecionamento 302, ou até mesmo um 200 (com algum texto), o Android não aparece no navegador.

Eu tenho um roteador mikrotik com um recurso de hotspot integrado, que de fato tem o pop-up android no navegador com o login no portal cativo (no mesmo telefone de teste). Quando olho para o tráfego que ele envia ao meu cliente, ele é um simples HTTP 200, com algum texto, assim como o meu.

A única coisa que parece funcionar é se eu desabilitar meu servidor DNS de resolver tudo para 192.168.30.1 e usar iptables para redirecionar a porta 80 para localhost no meu RPi.

Alguém sabe por que o redirecionamento da porta 80 funciona quando se trata da detecção do portal cativo do Android, mas a configuração do servidor DNS para resolver tudo para o IP local do RPi não funciona?

Olhando para o código encontrado aqui link , parece que a única coisa com que o Android se preocupa é se ele pode se conectar a a host, e se recebe um HTTP 204 de volta. No meu caso, está definitivamente conectando e definitivamente não está recebendo um back de 204 (logs nginx mostram isso enviando HTTP 302 e HTTP 200).

Meu telefone está executando o Android 8, portanto, o código vinculado pode ser diferente agora que eu supus.

    
por Tal 19.03.2018 / 22:42

2 respostas

2

A solução que encontrei foi configurar meu dnsmasq para continuar a resolver tudo para 192.168.30.1, mas ter algumas exceções para servidores de teste de portal cativos:

10.45.12.1 clients3.google.com
10.45.12.1 clients.l.google.com
10.45.12.1 connectivitycheck.android.com
10.45.12.1 connectivitycheck.gstatic.com
10.45.12.1 play.googleapis.com

Basicamente, se qualquer coisa tentar resolver os domínios acima usando nosso servidor dns, eles receberão uma resposta de 10.45.12.1.

10.45.12.1 é um IP aleatório que não pertence a nada. Só não tem que ser 192.168.30.1.

A lista de domínios veio de aqui .

Com isso, assim que você se conectar ao WiFi do RPi, aparecerá a página do navegador mostrando meu site.

Esta é uma solução, mas não é realmente uma resposta para a questão de por que isso acontece. Se alguém puder explicar, eu agradeceria.

Editar:

Com essa solução, se eu me conectar e desconectar do Wi-Fi no dispositivo várias vezes, às vezes o Android abre a página de login, e às vezes não. Para alguém fazendo algo semelhante, no final, para uma solução melhor, eu fui com isso:

  • O DNSmasq resolve tudo para 10.45.12.1 (ou qualquer coisa fora da sub-rede 192.168.30.0/24)
    • DEVE estar fora da sub-rede 192.168.30.0/24 (ou qualquer que seja sua sub-rede LAN) ou o cliente tentará usar o ARP para descobrir o endereço MAC do dispositivo especificado e falhará, porque o dispositivo não na verdade existe
  • O iptables encaminha a porta 80, vindo da interface wifi para o localhost

Isso funciona para Android, OS X e Windows. Eu não tenho um dispositivo iOS para testar isso. De acordo com este , os dispositivos iOS podem exigir algum trabalho adicional.

Ainda estou curioso para saber por que isso foi necessário, e por que resolver tudo para 192.168.30.1 não funcionou em primeiro lugar.

    
por 20.03.2018 / 22:36
0

Eu passei muito tempo tentando descobrir isso e finalmente consegui. Você pode ver o código aqui link

É uma combinação de domínios que apontam para IPs públicos, iptables e redirecionamentos nginx.

    
por 27.11.2018 / 11:06