Skip to main content

A Python client library for both OPNsense and pfSense.

Project description

Routers

Project Overview

The Routers project is a Python-based tool designed to manage firewall aliases across different routers, specifically pfSense (v1 and v2) and OPNsense. It provides a unified interface for creating, updating, deleting, and renaming firewall aliases, while abstracting away the differences between the APIs of these platforms.

This tool leverages client libraries for pfSense and OPNsense APIs, allowing seamless interaction with their respective firewall alias management functionalities. The core of the project is the Router class which handles connection to different router types, and the alias adapters which convert between internal data structures and router-specific models.

Features

  • Unified Router Management: Connect to pfSense v1, pfSense v2, and OPNsense routers using a common interface.
  • Advanced Alias Operations: Create, update, delete, and rename firewall aliases without needing to know the details of the underlying API.
  • Secure Configuration Storage: Store router connection details securely using Redis with encryption.
  • Adapter Architecture: Flexible adapter system to handle different router types and API versions.
  • Difference Detection: Identify differences between aliases across routers to help with synchronization.
  • Comprehensive Testing: Includes a robust test suite with mock objects to ensure code correctness without needing live routers.

Installation

Prerequisites

  • Python 3.11 or higher
  • Core dependencies:
    • pyfsense-client - Client library for pfSense
    • opn-api - Client library for OPNsense
    • redis[hiredis] - For configuration storage
    • cryptography - For secure configuration storage
    • Additional dependencies specified in pyproject.toml

Steps

  1. Clone this repository:

    git clone https://github.com/devinbarry/routers.git
    cd routers
    
  2. Install the package in development mode:

    pip install -e ".[dev]"
    

Project Structure

routers/
│
├── src/routers/
│   ├── __init__.py
│   ├── settings.py                    # Environment configuration
│   ├── firewall.py                    # Firewall utilities
│   ├── alias/                         # Alias management
│   │   ├── types.py                   # Alias dataclass, AliasType enum
│   │   ├── operations.py              # High-level sync operations
│   │   ├── loader.py                  # JSON alias loading & reference lookup
│   │   ├── adapter_factory.py         # Creates adapter for a given router
│   │   ├── type_conversions.py        # Router-specific format conversions
│   │   ├── exceptions.py              # Alias exceptions
│   │   └── adapter/                   # Platform-specific adapters
│   │       ├── base.py                # Abstract adapter interface
│   │       ├── pfsense_v1.py          # pfSense v1 adapter
│   │       ├── pfsense_v2.py          # pfSense v2 adapter
│   │       └── opnsense.py            # OPNsense adapter
│   ├── client/
│   │   └── pfsense_v2.py              # PfSenseV2MetaClient wrapper
│   └── router/
│       ├── core.py                    # Router dataclass, RouterType, ClientFactory
│       ├── exceptions.py              # Router exceptions
│       └── config/
│           ├── encrypt.py             # Fernet-encrypted Redis wrapper
│           └── store.py               # ConfigLoader & CredentialStore
│
├── tests/                             # Test suite organized by module
├── pyproject.toml
└── README.md

Usage

Initialize a Router

from routers import Router, RouterType

router = Router(name="MyRouter", type=RouterType.PFSENSE_V2)

Router credentials are loaded from encrypted Redis via ConfigLoader. See router/config/ for setup.

Direct Alias Operations (Adapter)

Use the adapter for direct CRUD on individual aliases:

from routers.alias.adapter_factory import get_alias_adapter
from routers.alias.types import Alias, AliasType

adapter = get_alias_adapter(router)

# List all aliases
aliases = adapter.get_all_aliases()

# Create
alias = Alias(
    name="BlockList",
    alias_type=AliasType.HOST,
    description="Block list of IPs",
    content=["192.168.1.1", "192.168.1.2"],
    detail=["IP1", "IP2"],
)
adapter.create_alias(alias)

# Update
alias.description = "Updated block list"
adapter.update_alias(alias)

# Delete
adapter.delete_alias("BlockList")

# Rename
adapter.rename_alias(alias, "NewBlockList")

Sync Operations (Reference-Based)

The operations module syncs router aliases against reference definitions:

from routers.alias.operations import (
    print_differing_client_aliases,
    update_differences_on_client,
    create_new_on_client,
    delete_missing_reference_aliases,
)

# Show differences between router state and reference aliases
print_differing_client_aliases(router)

# Sync: update differing aliases, create missing ones
update_differences_on_client(router)

# Create only missing aliases (no updates)
create_new_on_client(router)

# Delete aliases not in the reference list
delete_missing_reference_aliases(router)

Test Suite

Run the tests with pytest:

pytest

Tests use mock objects -- no live routers required.

Contributing

Contributions are welcome. Fork the repository, submit a pull request, and include tests where applicable.

License

This project is licensed under the AGPLv3 License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

routers-0.1.2.tar.gz (42.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

routers-0.1.2-py3-none-any.whl (47.8 kB view details)

Uploaded Python 3

File details

Details for the file routers-0.1.2.tar.gz.

File metadata

  • Download URL: routers-0.1.2.tar.gz
  • Upload date:
  • Size: 42.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for routers-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c6af1e1b6acc8028da198ff8e742176d5c611897f0a4020c02c24bf432663e66
MD5 7f205d145f26b5fc5899cef45df4cf05
BLAKE2b-256 93eac733c1d603687a6f92acb10e734eb3d8c454d056a9ad6ebb881aadc6c8ee

See more details on using hashes here.

File details

Details for the file routers-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: routers-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 47.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for routers-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8039170d76b69613e7410b9a735fa95f177b6f96d9a910e4a1ac921d66c7c166
MD5 e98f21765c2e4688fd947165e5e860cc
BLAKE2b-256 2e00334745d663899014146fe98b95a327d6a48506d07af0460d090f75824735

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page