Questão:
Criar ponto de acesso automaticamente se nenhuma rede estiver disponível
jake
2019-07-02 02:53:47 UTC
view on stackexchange narkive permalink

Desejo criar automaticamente um ponto de acesso, se nenhuma rede for encontrada, para que eu possa me conectar ao meu Raspberry Pi em qualquer lugar.

Se ninguém estiver conectado ao hotspot por um tempo, ele deve procurar as redes definidas em wpa_supplicant.conf novamente.

Eu não quero instale qualquer software adicional e use apenas wpa_supplicant , wpa_cli e systemd-networkd .

Um responda:
jake
2019-07-02 02:53:47 UTC
view on stackexchange narkive permalink

Primeiro, precisamos mudar completamente para systemd (que pode ser o futuro de qualquer maneira), como Ingo explicou aqui:

  # desinstala o clássico networkingsudo -Es # se ainda não foi feito --autoremove purge ifupdown dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslogapt-mark hold ifupdown dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog raspberrypi-net-mods openresolvrm -r / etc / network / etc / dhcp # setup / enable systemd-resolution and systemd-networkdapt --autoremove purge avahi-daemonapt-mark hold avahi -daemon libnss-mdnsapt install libnss-resolveln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.confsystemctl enable systemd-networkd.service systemd-resolvido.service  

1. Configure wpa_supplicant

Seu wpa_supplicant-wlan0.conf deve ser semelhante a:

  country = FRctrl_interface = DIR = / var / run / wpa_supplicant GROUP = netdevupdate_config = 1ap_scan = 1 ### seu ponto de acesso / ponto de acesso ### rede = {ssid =" RaspberrypiAP "# seu ponto de acesso name mode = 2 key_mgmt = WPA-PSK psk = "passphrase" # frequência da senha do seu hotspot = 2462} ### sua (s) rede (s) ### network = {priority = 10 # adicionar uma prioridade maior que 0 a qualquer rede ssid = "seuWifi" # exceto o do ponto de acesso! psk = "passphrase"} 

Temos que adicionar uma priority = maior que 0 para qualquer seção de rede exceto a do ponto de acesso, então wpa_supplicant código> vai preferir eles. Somente se nenhuma dessas redes for encontrada, wpa_supplicant criará um ponto de acesso / ponto de acesso. Se wpa_supplicant criou um hotspot, a interface deve receber um endereço estático e precisamos de um servidor DHCP, para que possamos conectar nossos dispositivos a ele. Isso será feito por systemd-networkd .


2. Configure a interface wireless com systemd-networkd Budap

Precisamos criar os seguintes arquivos. O primeiro irá configurar seu dispositivo como cliente, o segundo como ponto de acesso. O primeiro é o padrão devido ao número menor.

sudoedit /etc/systemd/network/08-CLI.network

  [Match] Name = wlan0 [Network] DHCP = yesLinkLocalAddressing = yesMulticastDNS = yes  

sudoedit / etc / systemd / network / 12-AP .network

  [Match] Name = wlan0 [Network] Address = 192.168.4.1 / 24DHCPServer = yesLinkLocalAddressing = yesMulticastDNS = yes  código> 

3. Configure um systemd.service para configurar automaticamente a interface com base em eventos wpa_supplicant

Este serviço executará wpa_cli , que executa o script abaixo em determinados eventos.

Execute sudo systemctl edit --full --force wpa_cli@wlan0.service e cole as seguintes linhas nele:

  Description = Wpa_cli para criar automaticamente um ponto de acesso se nenhuma conexão de cliente estiver disponívelAfter = wpa_supplicant @% i.serviceBindsTo = wpa_supplicant @% i.service [Serviço] ExecStart = / sbin / wpa_cli -i% I -a /usr/local/bin/autoAP.shRestart=on-failureRestartSec=1[Install]WantedBy=multi-user.target

4. O script necessário para o serviço

Este script deve ser salvo no caminho definido na seção ExecStart = . Ele configurará o dispositivo como cliente se estiver conectado a algum wi-fi, ou como ponto de acesso se wpa_supplicant tiver criado um, o que fará automaticamente se nenhuma outra rede for encontrada.

Se ninguém está conectado ao ponto de acesso por um tempo ele irá reiniciar o wpa_supplicant para fazê-lo procurar redes wi-fi novamente.

sudoedit / usr / local / bin / autoAP. sh

  #! / bin / bashdevice = wlan0configure_ap () {if [-e /etc/systemd/network/08-CLI.network]; então mv /etc/systemd/network/08-CLI.network /etc/systemd/network/08-CLI.network~ systemctl restart systemd-networkd fi} configure_client () {if [-e / etc / systemd / network / 08 -CLI.network ~] && wpa_cli -i $ status do dispositivo | grep -q "modo = estação"; então mv /etc/systemd/network/08-CLI.network~ /etc/systemd/network/08-CLI.network systemctl restart systemd-networkd fi} reconfigure_wpa_supplicant () {sleep "$ 1" if ["$ (wpa_cli -i $ device all_sta) "=" "]; então wpa_cli -i $ device reconfigure fi} case "$ 2" em # Configure access point se for criado AP-ENABLED) configure_ap reconfigure_wpa_supplicant 2m & ;; # Configurar como cliente, se conectado a alguma rede CONECTADO) configure_client ;; # Reconfigure wpa_supplicant para pesquisar seu wi-fi novamente, # se ninguém estiver conectado ao ap AP-STA-DISCONNECTED) reconfigure_wpa_supplicant 20 & ;; esac  

Torne o script executável chmod + x /path/to/script/autoAP.sh.

Agora, temos que executar sudo systemctl enable --now wpa_cli@wlan0.service , reinicie o Pi e tudo deve funcionar.

Eu também criei um repositório github para isso, de onde você pode instalá-lo facilmente.

Ficarei feliz por alguma sugestão sobre como melhorar esta configuração.

Desde Raspbian 2019-04-08 você não precisa mais instalar o rng-tools. Ocorreu um erro de digitação. Para arquivos de rede você usa `/ lib / systemd / network /` mas no script você usa `/ etc / systemd / network /`. Você não precisa de `network.target` se usar` network-online.target`, mas isso não importa. `Type = simple` é o padrão. Existem algumas ideias muito boas. Obrigado por isso.
Obrigado, @Ingo, eu editei! Estou usando `/ etc / systemd / network / 08-CLI.network` para mascarar o arquivo em` / lib / ... `. Você acha que é melhor renomeá-lo?
Eu costumo usar o systemctl para controlar os serviços devido à estabilidade. Não dei uma olhada detalhada nos links e não posso falar muito sobre eles, mas evito tocar em `/ lib /`.
@Ingo Mas você não pode gerenciar arquivos .network com `systemctl`, pode? Mas talvez seja melhor desabilitar `08-Client.network` com um arquivo drop-in e mover tudo para` / etc / systemd / network`. Vou testar isso.
Os arquivos e links de rede são gerenciados pelo systemctl. Pelo que entendi seu script, você verifica o status de um serviço e o inicia e interrompe. Você pode fazer isso com `systemctl is-active my.service` e` systemctl [en / dis] able --now my.service`.
Isso é ótimo! Obrigado pelo artigo. Eu tenho isso funcionando aqui. Alguns comentários: 1) Mudar para resolvido por rede não parece obrigatório com base em meus testes (limitados). Eu não resolvi como passar as configurações do domínio de pesquisa com meus endereços dhcp para pré-atribuídos. Ainda investigando, porque gostaria de chegar lá. 2) O comando 'ln' está sem um 'f' no final (deveria ser '.conf'). 3) Digitação nos comentários: wpa_supllicant-wlan0.conf. 4) Por último, algum tipo de convenção de nomenclatura para scripts e arquivos conf pode ser útil, mas não obrigatória.
Ah, encontrei uma solução para o meu problema. Eu configurei o dhcp fornecendo endereços fixos atribuídos (use IP X para endereço MAC Y). systemd-resolution não solicita a opção de domínio de pesquisa, mas é tratado corretamente se voltar. Assim, por resposta em https://github.com/systemd/systemd/issues/8174, posso usar a opção dhcp-parameter-request-list 1,3,6,12,15,42,119; (com 119 sendo o impt) para hosts afetados, e tudo está bem. Eu tenho uma ferramenta para gerenciar o banco de dados de configuração do dhcp, então é bem fácil. Obrigado novamente!
@Ingo, você poderia dizer por quais comandos você pode gerenciar arquivos .network? Não foi possível encontrá-los. Não quero iniciar ou parar serviços, mas reconfigurar a interface dependendo do seu estado (modo manged ou ap). Se houver uma maneira melhor do que mover o arquivo, diga-me!
Ah, agora eu entendo que você move os arquivos de configuração em `/ etc / systemd / network /`. Não vi isso antes. Esqueça meu comentário sobre isso. Eu olhei os links simbólicos em `/ etc / systemd / system /`, uma confusão. Se você disser que não deseja iniciar ou interromper os serviços: reinicie a configuração completa da rede com todos os serviços dependentes a cada mudança. Se você modificar a configuração de rede (como você faz), é recomendável executar `sudo systemctl daemon-reload`, mas se funcionar sem, pode não ser necessário no seu caso.
Não é também uma solução ter o ponto de acesso sempre ligado e deixar o wpa_supplicant fazer o roaming com suas conexões de cliente como de costume? Para ter mais ideias, devo configurar sua solução, mas agora estou com alguns problemas com o novo RPi 4. Voltarei em breve para sua configuração. Agora eu não entendo porque essa comutação não funciona automagicamente com a prioridade dos blocos de rede em wpa_supplicant.conf.
@Ingo Isso seria ótimo! wpa_supplicant não muda de volta se o ponto de acesso for habilitado uma vez, ou pelo menos não sei como dizer a ele para fazer isso. E preciso, é claro, reconfigurar a interface então. Eu também não gosto de fazer isso reiniciando o systemd-networkd, mas não consegui encontrar uma maneira melhor. Obrigado por ajudar! Acho que muitas pessoas ficariam satisfeitas com uma solução simples para isso (acho volumes de 300 linhas de JavaScript um pouco exagerado).
Mas gosto de usar um RPi 4B, então posso dar uma olhada em seu novo hardware. Uma comparação visual de `iw phy` com um RPi 3B + não mostra nenhuma diferença relevante na configuração wi-fi. Minha esperança era que RPi 4B suportasse WDS para fazer a ponte de conexões de cliente, mas não parece ser o caso. Mas isso está fora do assunto aqui ... E eu tenho [outro projeto] (https://raspberrypi.stackexchange.com/questions/92557/how-can-i-use-an-init-ramdisk-initramfs-on-boot- up-raspberry-pi / 100261 # comment165011_100261) no pipeline
Com base no meu conhecimento (reconhecidamente não profundo) do systemd, acho que a implementação é bastante elegante e "simplesmente funciona". Além disso, descobri um caso de uso maravilhoso para ele. Quando eu faço um cartão para um novo Pi, eu o coloco no lugar e garanto que ele não entrará na minha rede. Assim que o novo Pi for inicializado, posso entrar na rede Pi AP e configurar o Pi, bem como adicioná-lo à minha infraestrutura dhcp / bind. Isso é ótimo porque eu não preciso conectar um monitor ... apenas use ssh ou VNC para conectar ao AP.
@bls Obrigado! É exatamente para isso que eu fiz, que você pode acessar e configurar seu dispositivo sem cabeça, não importa se você digitou a senha de wifi errada ou não, etc. Fico feliz que funcione para você!
@jake Ainda não entendo porque mudar de ponto de acesso quando uma conexão de cliente é estabelecida. Por quê?
@ingo DESDE, eu acho, neste cenário, o ponto de acesso tem o único propósito de tornar o dispositivo acessível se ele não estiver conectado a nenhuma rede.
@user5950 Mas, novamente: por que desligar? Se estiver sempre ativado, você sempre poderá se conectar a ele. O ponto de acesso não deve ser desligado para estabelecer, além disso, uma conexão de cliente.
@Ingo Eu sei que você pode ter uma interface virtual gerando um ponto de acesso ao mesmo tempo. Mas por que deveria estar lá se não fosse necessário? Eu acho que é bom ter uma configuração simples para isso, para que você possa acessar seu pi mesmo se tiver digitado uma senha errada etc., e você mantenha o ambiente limpo de pontos de acesso desnecessários; mas talvez esses pensamentos sejam um pouco antiquados, quando cada lâmpada tem seu próprio ponto de acesso agora. Na verdade, eu queria encontrar uma solução melhor do que a de volumio. Eles fazem basicamente o mesmo, mas seu serviço atrasa o processo de inicialização por meio minuto em um RPI 0.
@ingo Se você usar uma lanterna em um ambiente escuro, para substituir um fusível quebrado, você pode deixar a lanterna acesa depois de substituí-la.
@jake Você perguntou como evitar reiniciar a pilha de rede completa com `systemctl restart systemd-networkd` em cada mudança de rede. Você deve ser capaz de usar ** wpa_cli ** para gerenciar as conexões. Com `wpa_cli -h | menos você encontrará muitas opções úteis. reassociar, reanexar, select_network e outros são opções interessantes para gerenciar manualmente as conexões.
@user5950 Sim, entendo agora que desligar um serviço desnecessário é um requisito válido.
Percebi que o@jake's GitHub foi removido. Peguei o código aqui, consertei a lógica de espera / reconfiguração e construí um instalador para ele. Ele está em https://github.com/gitbls/autoAP O README tem uma boa descrição de como ele opera e eu forneci um script para mudar de dhcpcd ou Network Manager para systemd-networkd.
@bls Bem, não é. Acabei de renomeá-lo e esqueci de atualizar aqui, mas estou feliz que você esteja usando o código!
Ah! Aí está! Obrigado!


Estas perguntas e respostas foram traduzidas automaticamente do idioma inglês.O conteúdo original está disponível em stackexchange, que agradecemos pela licença cc by-sa 4.0 sob a qual é distribuído.
Loading...