Mozilla VPN Client

repository·main·Indexed 20 days ago

https://github.com/mozilla-mobile/mozilla-vpn-client

A privacy-focused VPN client supporting Linux, Android, Windows, macOS, iOS, and WebAssembly. The repository includes the core Android VPNService for WireGuard-based connections, a QML-based UI with Lottie animation support, and various build utilities for cross-platform deployment and CI validation.

Tokens
42.7K
Snippets
128
Records
221
Agent score
70%

What's inside mozilla-vpn-client

  1. Use the Inspector debugging tool

    main

    The Inspector is a debugging tool used to navigate and debug the VPN client. It is only available when the staging environment is activated.

    Available Tools

    • Shell: The default view. Type help to see a list of available commands.
    • Logs: Provides real-time output of app activities, including timestamps, components, and messages. You can filter by component using the left column.
    • Network Inspector: Displays a list of all incoming and outgoing network requests. Useful for debugging network issues or monitoring communication with external components like the Guardian.
    • QML Inspector: Mirrors the local VPN client and allows you to identify and inspect QML components by clicking on them in the UI.
  2. Overview of Accessibility Technologies supported in Mozilla VPN

    main

    Mozilla VPN supports several categories of Accessibility Technologies (ATs) to ensure usability for users with different needs. These categories include:

    • Vision: Includes Screen Reader support, Screen Magnification (with support for bringing focused elements into view), High Contrast Themes/Color Filters, Personalization of Text Size/Cursors/Pointers, Ability to Turn Off Animation, and Personalization of Notification Duration.
    • Hearing: Includes cues for audio notifications (e.g., screen flashes or vibrations).
    • Mobility: Includes Keyboard Access to all controls, and support for Voice Access, Voice Typing, Eye Control, and Switch Control.
    • Neurodivergence/Do-not-disturb: Includes Notification Suppression to respect system do-not-disturb modes.
  3. How Nimbus and Cirrus integration works

    main

    Mozilla VPN integrates with Nimbus (Mozilla's experimentation platform) via Cirrus, a server-side sidecar service.

    Instead of using Nimbus SDKs directly on the client, the VPN client communicates with the Guardian server. The Guardian server hosts the Cirrus sidecar, which queries Nimbus for active 'features' (experiment branches). This architecture allows the server to handle targeting logic while providing a unified API to the client.

    Key components:

    • Nimbus: The central experimentation platform where experiments are defined.
    • Cirrus: A server-side service deployed as a sidecar to the application server (Guardian) that exposes a /v1/features endpoint.
    • Guardian: The VPN server that proxies Cirrus's functionality to the client via the /featurelist endpoint.
  4. Android Daemon Implementation and Communication

    main

    The Android daemon runs as a background Service in a separate process to ensure the VPN tunnel persists even if the GUI is suspended.

    Communication

    Communication is achieved through Android Bindings. The protocol uses the following JSON structure: { "requestType": <int>, "data": <json> }

    Connectivity

    Connectivity is established by creating a raw TUN device via the VpnService.Builder API and running a wireguard-go process.

    {
      "requestType": 1,
      "data": {}
    }
  5. Accessibility Principles for Mozilla VPN

    main

    Mozilla VPN follows four core principles to ensure an inclusive user experience:

    1. Inclusive design: Aim to design for all users from the start to avoid the need for specialized adaptations later.
    2. Compatibility with major Assistive Technologies (ATs): Ensure support for Text Size, Screen Readers, Keyboard Access, Text Contrast, and Screen Magnification on all supported platforms.
    3. Alignment with Established Standards: Strive to meet WCAG standards where applicable.
    4. Collaborative Development and Testing: Involve developers, testers, and accessibility experts in the process, and prioritize testing with real users to detect issues early.
  6. Handle experimentation opt-out

    main

    Users can opt-out of telemetry and experimentation independently via the VPN application Settings.

    Behavioral Rules:

    • Opting out of telemetry: Automatically opts the user out of experiments.
    • Opting out of experiments: Does not automatically opt the user out of telemetry.
    • Active Experiments: If a user is already enrolled in an experiment when they opt out, they should be unenrolled from that experiment immediately. The application is responsible for storing this preference and ensuring no further requests are sent to Cirrus.
  7. Manage Add-on state (Session, Local, and Global)

    main

    Add-ons can maintain state using three different scopes. The State interface is consistent across all types, but the persistence and synchronization behavior differs.

    State Scopes

    • Session state: Not persisted. Wiped when the application is killed.
    • Local state: Persisted across sessions on a single device. Note: Currently not supported (see VPN-3929).
    • Global state: Persisted across sessions and synced among the user's devices. Note: Currently not supported (see VPN-2795).

    State Object Format

    State objects must not be nested. Supported value types are string, number, and boolean. Each key in the state object must define its type and a default value.

    interface State {
        [key: string]: {
            type: "string" | "number" | "boolean",
            default: string | number | boolean,
        }
    }
  8. The in-app authentication state machine

    main

    The in-app authentication process follows a complex finite state machine (FSM) to handle various account types (SSO, Stub, existing) and security requirements (TOTP, Unblock codes, Email verification).

    Key transitions include:

    • Account Discovery: Starting with an email address leads to CheckingAccount, which branches into SignIn (existing account), SignUp (new account), StubAccount (no password set), or SsoAccount (SSO-based).
    • Security Challenges: After SigningIn, the flow may branch into UnblockCodeNeeded, TOTPVerificationNeeded, or EmailVerification depending on the account's security state.
    • Account Lifecycle: The flow can also handle AccountDeletionRequest leading to DeletingAccount before returning to a finalized state.
    stateDiagram-v2
      Start: Start
      CheckingAccount: Checking Account
      SignIn: Sign In
      SignUp: Sign Up
      StubAccount: Stub account
      SsoAccount: SSO account
      Fallback: Fallback in the browser
      SigningIn: Signing In
      SigningUp: Signing Up
      UnblockCodeNeeded: Unblock code needed
      VerifyingUnblockCode: Verifying unblock code
      TOTPVerificationNeeded: TOTP verification needed
      VerifyingSessionTOTPCode: Verifying session TOTP code
      EmailVerification: Email verification
      VerifyingSessionEmailCode: Verifying session email code
      state signing_results <<choice>>
      AccountDeletionRequest: Account deletion request
      DeletingAccount: Deleting account
    
      Initializing --> Start
      Start --> CheckingAccount: email address received
      CheckingAccount --> SignIn: the account already exists
      CheckingAccount --> SignUp: new account is required
      CheckingAccount --> StubAccount: account exists but no password
      CheckingAccount --> SsoAccount: SSO account without password
      CheckingAccount --> Fallback: new account is required
      StubAccount --> CheckingAccount: retry after password setup
      SsoAccount --> CheckingAccount: retry after password setup
      SignIn --> SigningIn: password received
      SigningIn --> signing_results
      signing_results --> SignIn: invalid password or error
      signing_results --> UnblockCodeNeeded: unblock code required
      signing_results --> TOTPVerificationNeeded: TOTP code required
      signing_results --> Finalize: authentication completed
      UnblockCodeNeeded --> VerifyingUnblockCode: Unblock code received
      VerifyingUnblockCode --> signing_results: authentication completed
      VerifyingUnblockCode --> UnblockCodeNeeded: Unblock code invalid or error
      TOTPVerificationNeeded --> VerifyingSessionTOTPCode: TOTP code received
      VerifyingSessionTOTPCode --> signing_results: authentication completed
      VerifyingSessionTOTPCode --> TOTPVerificationNeeded: TOTP code invalid or error
      SignUp --> SigningUp: password received
      SigningUp --> EmailVerification: email sent
      SigningUp --> Start: error
      EmailVerification --> VerifyingSessionEmailCode: email code received
      VerifyingSessionEmailCode --> Finalize: authentication completed
      VerifyingSessionEmailCode --> EmailVerification: code invalid or error
      Finalize --> AccountDeletionRequest: account deletion is requested
      AccountDeletionRequest --> DeletingAccount: account deleted
      DeletingAccount --> Finalize: Operation is completed
  9. Understand the Subscription Management user flow

    main

    The Subscription Management view is located within the Settings 'Profile' view. Accessing this view depends on the user's authentication state:

    1. Settings View $\rightarrow$ Profile View request.
    2. Authentication Check: If authentication is required, the user is directed to the Authentication flow.
    3. Post-Authentication: If authentication succeeds, the user is directed to the Profile View (where subscription details are visible). If it fails, they are returned to the Settings View.

    Subscription information is only displayed if the user is authenticated and has the necessary permissions associated with their FxA Account.

  10. How session ID sharing works between the Main Application and Daemon

    main

    Mozilla VPN uses a split-process architecture: a Main Application (UI) and a Daemon (background process/network extension). On mobile platforms, the Main Application may be killed while the VPN is active, making it unreliable for managing session-based telemetry.

    To solve this, the Daemon acts as the source of truth for the VPN session. It manages a new metric called shared_session_id, which is used to join telemetry data from both processes. The Main Application communicates with the Daemon to retrieve this ID so that its vpnsession pings can be correlated with the Daemon's daemonsession pings.

  11. MacOS Daemon Implementation and Communication

    main

    On macOS, the daemon is provided by the org.mozilla.macos.FirefoxVPN.daemon tool and communicates via an XPC service named org.mozilla.macos.FirefoxVPN.xpc-daemon.

    Lifecycle and Management

    • macOS 13+: Managed via the SMAppService framework.
    • Older macOS versions: Managed via launchd using the org.mozilla.macos.FirefoxVPN.daemon.plist configuration (which sets KeepAlive to true).

    Connectivity

    Since macOS lacks native Wireguard support, the daemon manages wireguard-go to handle packet tunneling via /dev/net/tun. It also utilizes a tool called macosdnsmanager to reconfigure system DNS settings during connection and restore them upon disconnection.