wifi-connect

repository·master·Indexed 23 days ago

https://github.com/balena-os/wifi-connect

A utility for Linux devices that enables WiFi configuration via a captive portal. It creates a temporary access point allowing users to select and join a local WiFi network using a mobile phone or laptop. The tool relies on NetworkManager and supports customization of the portal SSID, passphrase, and gateway via CLI flags or environment variables. It includes specific integration guides for balenaOS applications and a React-based UI.

Tokens
3.4K
Snippets
7
Records
22
Agent score
81%

What's inside wifi-connect

  1. How WiFi Connect works

    master

    WiFi Connect enables dynamic WiFi configuration on Linux devices via a captive portal. It relies on NetworkManager being the active network manager on the host OS. The workflow follows these steps:

    1. Advertise: The device detects available WiFi networks and creates an access point (AP).
    2. Connect: The user connects a mobile phone or laptop to the device's AP. By default, the SSID is WiFi Connect.
    3. Portal: The device triggers a captive portal on the connected client's browser.
    4. Credentials: The user selects a local WiFi network from a list and enters the passphrase via the portal.
    5. Connected!: The device disables the AP and attempts to connect to the chosen network using NetworkManager. If successful, the configuration is saved; if it fails, the AP is re-enabled for another attempt.
  2. Build the WiFi Connect UI for production

    master
    To generate a production-ready version of the UI, run npm build. This command bundles and minifies the React code, outputting the static resources into a build folder. You can serve the resulting index.html and the contents of the build folder using any web server.
    npm build
  3. Install WiFi Connect on Raspbian/Debian Stretch

    master

    Since Raspbian Stretch uses dhcpcd by default instead of NetworkManager, you must use the provided installation script. This script disables dhcpcd, installs NetworkManager, and installs WiFi Connect.

    Run the following command and follow the onscreen instructions:

    bash <(curl -L https://github.com/balena-io/wifi-connect/raw/master/scripts/raspbian-install.sh)
  4. Configure WiFi Connect for a multicontainer balenaOS app

    master

    When running WiFi Connect in a multicontainer environment, the container requires specific host-level privileges and networking configurations. You must:

    1. Set the container network mode to host.
    2. Enable DBUS access by adding the io.balena.features.dbus: '1' label and setting the DBUS_SYSTEM_BUS_ADDRESS environment variable.
    3. Grant the container NET_ADMIN capabilities.

    Example docker-compose.yml configuration:

    version: "2.1"
    
    services:
        wifi-connect:
            build: ./wifi-connect
            network_mode: "host"
            labels:
                io.balena.features.dbus: '1'
            cap_add:
                - NET_ADMIN
            environment:
                DBUS_SYSTEM_BUS_ADDRESS: "unix:path=/host/run/dbus/system_bus_socket"
        ...
  5. Integrate WiFi Connect into a balenaOS application

    master

    To use WiFi Connect in a single-container balenaOS application, you need to manage two files:

    1. Dockerfile: Use a template to manage dependencies. Ensure all application dependencies are included alongside WiFi Connect requirements.
    2. Start Script: Add the WiFi Connect execution commands to the end of your start.sh script. This ensures WiFi Connect runs after your main application logic has initialized, allowing it to configure the network if needed.
  6. Set up the WiFi Connect UI development environment

    master

    The WiFi Connect UI is a React application bootstrapped by create-react-app. To develop locally, navigate to the UI folder and follow these steps:

    1. Install dependencies using npm install.
    2. Start the development server with npm start. The UI will be available at http://localhost:3000 by default.
    3. Benefit from Hot Module Replacement (HMR), as code changes will automatically reflect in the UI without manual refreshes.

    All networking requests utilize the fetch API, with polyfills included for fetch and Promise to ensure compatibility with older browsers.

    npm install
    npm start
  7. Run wifi-connect via CLI

    master

    The wifi-connect binary is the entrypoint for the service. When executed, it performs the following lifecycle steps:

    1. Signal Handling: Blocks exit signals to ensure clean shutdowns.
    2. Logging: Initializes the system logger.
    3. Configuration: Loads configuration settings (via get_config()).
    4. Privilege Check: Verifies that the process is running with root privileges (required for network manipulation).
    5. Networking Initialization: Sets up the necessary networking environment.
    6. Command Processing: Spawns a background thread to process network commands.
    7. Execution: Enters a blocking state waiting for exit signals or command results.

    If the application encounters an error, it prints the error message in red to stderr, followed by the chain of causes, and exits with a specific exit code.

  8. Initialize networking and the NetworkManager service

    master

    Before running WiFi Connect, you must ensure the NetworkManager service is active and any stale access point profiles from previous runs are cleaned up. Use init_networking to perform these steps. This function starts the NetworkManager service if it is not already active and deletes existing connection profiles that match the configured WiFi Connect SSID and are in access point mode.

    Note: This requires the config object to be properly initialized.

  9. Determine when to run WiFi Connect

    master

    The start.sh script provides logic to decide whether to launch the wifi-connect utility based on the current network state. If an active WiFi connection is detected, the utility is skipped.

    To implement custom connectivity checks in your own startup logic, you can use the following commands:

    1. Check for a default gateway: ip route | grep default
    2. Check for Internet connectivity (NetworkManager): nmcli -t g | grep full
    3. Check for Internet connectivity via Google: wget --spider http://google.com 2>&1
    4. Check for an active WiFi connection: iwgetid -r
    # Example: Check if an active WiFi connection exists
    if iwgetid -r; then
        printf 'Skipping WiFi Connect\n'
    else
        printf 'Starting WiFi Connect\n'
        ./wifi-connect
    fi
  10. Check WiFi Dongle compatibility

    master

    WiFi Connect requires a WiFi dongle or onboard WiFi that supports Access Point (AP) mode and is compatible with NetworkManager.

    Tested working chipsets:

    • Atheros (e.g., TP-LINK TL-WN722N with AR9271)
    • Ralink (e.g., ModMyPi with RT3070, ThePiHut with RT5370)
    • Raspberry Pi 3 onboard WiFi

    Known incompatible chipsets:

    • BCM43143 (Official Raspberry Pi dongle)
    • MT7601 (Addon NWU276)
    • RTL8188CUS (Edimax)
  11. Configure WiFi Connect Access Point settings

    master

    You can customize the access point created by WiFi Connect using command line arguments or environment variables:

    • SSID: Change the access point name using --portal-ssid or the PORTAL_SSID environment variable. The default is WiFi Connect.
    • Passphrase: Add WPA2 security to the access point using --portal-passphrase or the PORTAL_PASSPHRASE environment variable. By default, the network is unprotected.