Skip to content

linx-systems/pi-sentinel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PiSentinel

A Firefox Manifest V3 extension for Pi-hole v6 integration. Monitor DNS blocking statistics, control blocking status, and manage domains directly from your browser.

Install for Firefox

Features

  • Real-time Statistics - View blocked queries, block rate, and active clients
  • Blocking Control - Toggle DNS blocking with optional timer (30s to indefinite)
  • Multi-Instance Support - Manage multiple Pi-hole servers from a single extension
  • Domain Tracking - See all domains loaded by each tab, categorized as first-party or third-party
  • Quick Actions - Add domains to allowlist/denylist with one click
  • Query Log - Browse recent DNS queries with blocked/allowed filtering
  • 2FA Support - Full TOTP authentication support for secured Pi-hole instances

Screenshots

Settings Domain Sidebar
Settings Domain Sidebar

Requirements

  • Firefox 142 or later
  • Pi-hole v6 with the new REST API

Prerequisites

Before installing, ensure you have:

  • Node.js 20.x or later (LTS recommended)
  • Bun 1.x or later

Verify your installation:

node --version  # Should output v20.x.x or higher
bun --version   # Should output 1.x.x or higher

Installation

From Firefox Add-ons (Recommended)

Install directly from the official Firefox Add-ons store:

Install PiSentinel

From Source

  1. Clone the repository

    git clone https://github.com/linx-systems/pi-sentinel
    cd pi-sentinel
    # Optional: Go to release version ( the version soon to be uploaded )
    git checkout release
  2. Install dependencies

    npm install
    # or
    bun install
  3. Build the extension

    npm run build
    # or
    bun run build
  4. Load in Firefox

    • Open Firefox and navigate to about:debugging
    • Click "This Firefox" in the sidebar
    • Click "Load Temporary Add-on..."
    • Select the dist/firefox-mv3/manifest.json file

Development

Quick Start

# Install dependencies
bun install

# Development mode with hot reload
bun run dev

Then:

  • Open Firefox and navigate to about:debugging
  • Click "This Firefox" in the sidebar
  • Click "Load Temporary Add-on..."
  • Select the dist/firefox-mv3/manifest.json file

Packaging

To package the extension for Firefox:

bun run package

The unsigned .xpi file will be created in the web-ext-artifacts/ directory.

Debugging

Background Script

  1. Go to about:debugging#/runtime/this-firefox
  2. Find PiSentinel and click "Inspect"
  3. This opens DevTools for the background script where you can:
    • View console logs
    • Set breakpoints
    • Inspect network requests to Pi-hole API

Popup / Sidebar / Options

  1. Right-click inside the popup/sidebar/options page
  2. Select "Inspect" to open DevTools for that specific UI

Logging

The extension uses console.log/warn/error for logging. In development mode, useful logs include:

  • API calls: Check the Network tab in background script DevTools
  • State changes: Add console.log statements in background/state/
  • Message passing: Log in entrypoints/background.ts message handlers

To add temporary debug logging:

// In any source file
console.log("[PiSentinel]", "Debug message", { data });

Available Scripts

Command Description
bun run dev Development mode with hot reload
bun run build Production build to dist/firefox-mv3/
bun run lint Run ESLint on TypeScript files
bun run lint:fix ESLint with auto-fix
bun run format Prettier formatting
bun run test Run unit tests (Vitest)
bun run test:watch Unit tests in watch mode
bun run test:coverage Unit tests with coverage
bun run test:e2e E2E tests (Playwright)
bun run package Build and create unsigned .xpi for distribution
bun run sign Build and sign extension with Mozilla (requires AMO credentials)
bun run sign:channel Build and sign as unlisted (for self-distribution)

Signing the Extension

To distribute your extension outside of development, you'll need to sign it with Mozilla:

Setup Signing Credentials

  1. Get API credentials from Mozilla Add-ons Developer Hub

    • Sign in to your Mozilla account
    • Navigate to API Key Management
    • Generate new credentials (API Key + Secret)
  2. Configure environment variables

    # Copy the example file
    cp .env.example .env
    
    # Edit .env and add your credentials
    AMO_API_KEY=your_api_key_here
    AMO_API_SECRET=your_api_secret_here
  3. Sign the extension

    # For public distribution (listed on AMO)
    bun run sign
    
    # For self-distribution (unlisted)
    bun run sign:channel

The signed .xpi file will be created in the web-ext-artifacts/ directory.

Alternative: Load Unsigned Extension (Development Only)

For testing without signing:

  • Firefox Developer/Nightly Edition: Load temporary add-on via about:debugging
  • Firefox Release: Must disable signature verification in about:config (set xpinstall.signatures.required to false)

Project Structure

/
├── background/          # Background modules
│   ├── api/             # Pi-hole v6 REST client
│   ├── crypto/          # PBKDF2 + AES-256-GCM encryption
│   ├── services/        # Badge, notifications, domain tracker
│   └── state/           # Central state store
├── components/          # Shared UI components
├── entrypoints/         # WXT entry points
│   ├── background.ts    # Background script
│   ├── popup/           # Popup UI (Preact)
│   ├── sidebar/         # Sidebar UI (Preact)
│   └── options/         # Options page (Preact)
├── public/              # Static assets (icons)
├── tests/               # Unit + E2E tests
└── utils/               # Shared utilities

Tech Stack

  • TypeScript - Type-safe JavaScript with strict mode
  • Preact - Lightweight React alternative (~3KB gzipped)
  • WXT + Vite - Modern web extension toolkit with hot reload
  • webextension-polyfill - Cross-browser WebExtensions API compatibility
  • Vitest - Unit testing framework
  • Playwright - E2E testing framework

Testing

Run the test suite:

# Unit tests
bun run test

# Unit tests in watch mode
bun run test:watch

# Unit tests with coverage
bun run test:coverage

# E2E tests
bun run test:e2e

Configuration

  1. Click the PiSentinel icon in your toolbar
  2. If not configured, click "Configure Pi-hole"
  3. Enter your Pi-hole server URL (e.g., http://pi.hole or http://192.168.1.100)
  4. Enter your Pi-hole web interface password
  5. Click "Test Connection" to verify, then "Save & Connect"
  6. If 2FA is enabled, enter your TOTP code when prompted

Usage

Popup

Click the toolbar icon to view:

  • Connection status
  • Total queries and blocked count
  • Block rate percentage
  • Active clients
  • Toggle blocking on/off with optional timer

Sidebar

Open the sidebar (View → Sidebar → PiSentinel Domains) to see:

  • Domains tab: All domains loaded by the current page
    • First-party domains (green)
    • Third-party domains (orange)
    • Quick actions to allow/block each domain
  • Query Log tab: Recent DNS queries with filtering

Badge

The toolbar badge shows:

  • Number: Blocked query count
  • Green background: Blocking active
  • Red background: Blocking disabled
  • Gray background: Not connected

Security

  • Credentials are encrypted using PBKDF2 (100,000 iterations) + AES-256-GCM
  • Session tokens stored in browser.storage.session (cleared on browser close)
  • All API calls routed through background script (CORS bypass)
  • No credentials or tokens exposed to content scripts

Pi-hole v6 API Endpoints Used

Endpoint Purpose
POST /api/auth Authenticate and get session
DELETE /api/auth Logout
GET /api/stats/summary Fetch statistics
GET/POST /api/dns/blocking Check/toggle blocking
GET /api/queries Query log
POST /api/domains/allow/exact Add to allowlist
POST /api/domains/deny/exact Add to denylist
GET /api/search/{domain} Search domain status

Troubleshooting

"Connection failed" error

  • Verify Pi-hole URL is correct (no /admin suffix needed)
  • Ensure Pi-hole v6 is running
  • Check if Pi-hole is accessible from your browser

Session expires frequently

  • The extension automatically refreshes sessions every 4 minutes
  • If issues persist, check Pi-hole's session timeout settings

Extension not updating after code changes

  • Ensure bun run dev is running and shows successful rebuilds
  • Click "Reload" in about:debugging after each change
  • For popup changes, close and reopen the popup

Console errors not visible

  • Background script logs: Inspect via about:debugging
  • Popup/sidebar logs: Right-click → Inspect within the UI

macOS users

  • Recent macOS versions may require granting Firefox "Local Network" permission in System Preferences → Privacy & Security

Contributing

Contributions are welcome! Here's how to get started:

  1. Fork the repository and clone your fork
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Make your changes following the existing code style
  4. Run linting: bun run lint and fix any issues
  5. Test manually in Firefox using the development workflow above
  6. Commit your changes with a descriptive message
  7. Push to your fork and open a Pull Request

Code Style

  • Use TypeScript strict mode
  • Follow existing patterns in the codebase
  • Keep components small and focused
  • Use meaningful variable and function names

License

See LICENSE for details.

About

The Pi Hole Firefox Companion Extension!

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors

Languages