# opnwall/opnsense-repo architecture

> Architecture diagram of the GitHub repository opnwall/opnsense-repo, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/opnwall/opnsense-repo
- Repository: https://github.com/opnwall/opnsense-repo

## Overview

This repository is a collection of OPNsense community plugins, spanning proxy tools, DNS enhancements, DDNS, localization, network utilities, and diagnostics. The clearest end-to-end workflow in the supplied source is the enhanced DDNS plugin: users manage account and settings data through OPNsense controllers and fields, while a daemon runs polling and provider-update logic. Other README-listed plugins are represented as separate capability branches; their sampled files show plugin entry pages, but not enough internal wiring to infer their runtime flows.

Main entry points: [`src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php`](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php) (Config validation), [`src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/poller.py`](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/poller.py) (Address poller), [`src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/account`](https://github.com/opnwall/opnsense-repo/tree/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/account) (Provider adapters), [`src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/AccountsController.php`](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/AccountsController.php) (Accounts API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ddns["Dynamic DNS"]
  node_ddns_page["DDNS page"]
  node_ddns_accounts_api["Accounts API"]
  node_ddns_settings_api["Settings API"]
  node_ddns_service_api["Service API"]
  node_ddns_model["Config validation<br/>[DynDNS.php]"]
  node_ddns_account_fields["Account fields<br/>[AccountField.php]"]
  node_ddns_service_fields["Service fields<br/>[ServiceField.php]"]
  node_ddns_checkip_fields["Check-IP fields<br/>[CheckipField.php]"]
  node_ddns_widget["DDNS widget<br/>[Dyndns.js]"]
  node_ddns_daemon["DDNS daemon<br/>[ddclient_opn.py]"]
  node_ddns_poller["Address poller<br/>[poller.py]"]
  node_ddns_address["Address discovery<br/>[address.py]"]
  node_ddns_providers["Provider adapters"]
  node_hetzner_api["Hetzner DNS API"]
  node_ddnsgo["DDNS-Go"]
end

subgraph group_dns["DNS tools"]
  node_unbound_page["Unbound custom settings"]
end

subgraph group_proxy["Proxy tools"]
  node_mihomo_page["Mihomo proxy<br/>[mihomo.php]"]
  node_mihomo_subscriptions["Mihomo subscriptions<br/>[mihomo_sub.php]"]
  node_mihomo_logs["Mihomo logs<br/>[mihomo_logs.php]"]
  node_mihomo_unbound["Unbound setup<br/>[setup_unbound.php]"]
  node_singbox_page["sing-box proxy<br/>[sing-box.php]"]
  node_singbox_subscriptions["sing-box subscriptions<br/>[sing-box_sub.php]"]
  node_singbox_logs["sing-box logs<br/>[sing-box_log.php]"]
end

subgraph group_network["Network utilities"]
  node_easytier["EasyTier VPN<br/>[easytier.php]"]
  node_lucky["Lucky tools<br/>[lucky.php]"]
  node_staticarp["Static ARP"]
end

subgraph group_diagnostics["Diagnostics and localization"]
  node_speedtest["Speedtest"]
  node_pftop["pfTop diagnostics<br/>[diag_pftop.php]"]
  node_ttyd["ttyd terminal<br/>[diag_ttyd.php]"]
  node_lang["Chinese localization<br/>[lang_update.php]"]
end

node_operator(("OPNsense operator"))

node_operator -.->|"opens"| node_ddns_page
node_ddns_accounts_api -->|"uses model"| node_ddns_model
node_ddns_settings_api -->|"uses model"| node_ddns_model
node_ddns_service_api -->|"configures service"| node_ddns_model
node_ddns_account_fields -->|"extends model fields"| node_ddns_model
node_ddns_service_fields -->|"reads backend setting"| node_ddns_model
node_ddns_checkip_fields -->|"reads backend setting"| node_ddns_model
node_ddns_daemon -->|"starts poller"| node_ddns_poller
node_ddns_poller -->|"loads adapters"| node_ddns_providers
node_ddns_providers -->|"updates DNS records"| node_hetzner_api

click node_ddns_page "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/IndexController.php"
click node_ddns_accounts_api "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/AccountsController.php"
click node_ddns_settings_api "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/SettingsController.php"
click node_ddns_service_api "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/ServiceController.php"
click node_ddns_model "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php"
click node_ddns_account_fields "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/AccountField.php"
click node_ddns_service_fields "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/ServiceField.php"
click node_ddns_checkip_fields "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/CheckipField.php"
click node_ddns_widget "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/www/js/widgets/Dyndns.js"
click node_ddns_daemon "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/ddclient_opn.py"
click node_ddns_poller "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/poller.py"
click node_ddns_address "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/address.py"
click node_ddns_providers "https://github.com/opnwall/opnsense-repo/tree/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/account"
click node_ddnsgo "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddns-go/src/usr/local/www/services_ddnsgo.php"
click node_unbound_page "https://github.com/opnwall/opnsense-repo/blob/main/src/os-unboundcustom/src/opnsense/mvc/app/controllers/OPNsense/Unboundcustom/GeneralController.php"
click node_mihomo_page "https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/www/mihomo.php"
click node_mihomo_subscriptions "https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/www/mihomo_sub.php"
click node_mihomo_logs "https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/www/mihomo_logs.php"
click node_mihomo_unbound "https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/opnsense/scripts/mihomo/setup_unbound.php"
click node_singbox_page "https://github.com/opnwall/opnsense-repo/blob/main/src/os-sing-box/src/usr/local/www/sing-box.php"
click node_singbox_subscriptions "https://github.com/opnwall/opnsense-repo/blob/main/src/os-sing-box/src/usr/local/www/sing-box_sub.php"
click node_singbox_logs "https://github.com/opnwall/opnsense-repo/blob/main/src/os-sing-box/src/usr/local/www/sing-box_log.php"
click node_easytier "https://github.com/opnwall/opnsense-repo/blob/main/src/os-easytier/src/usr/local/www/easytier.php"
click node_lucky "https://github.com/opnwall/opnsense-repo/blob/main/src/os-lucky/src/usr/local/www/lucky.php"
click node_staticarp "https://github.com/opnwall/opnsense-repo/blob/main/src/os-staticarp/src/usr/local/www/services_staticarp.php"
click node_speedtest "https://github.com/opnwall/opnsense-repo/blob/main/src/os-speedtest/src/usr/local/www/diagnostics_speedtest.php"
click node_pftop "https://github.com/opnwall/opnsense-repo/blob/main/src/os-pftop/src/usr/local/www/diag_pftop.php"
click node_ttyd "https://github.com/opnwall/opnsense-repo/blob/main/src/os-ttyd/src/usr/local/www/diag_ttyd.php"
click node_lang "https://github.com/opnwall/opnsense-repo/blob/main/src/os-lang/src/usr/local/www/lang_update.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_ddns_page,node_ddns_accounts_api,node_ddns_settings_api,node_ddns_service_api,node_ddns_model,node_ddns_account_fields,node_ddns_service_fields,node_ddns_checkip_fields,node_ddns_widget,node_ddns_daemon,node_ddns_poller,node_ddns_address,node_ddns_providers,node_hetzner_api,node_ddnsgo toneBlue
class node_unbound_page toneAmber
class node_mihomo_page,node_mihomo_subscriptions,node_mihomo_logs,node_mihomo_unbound,node_singbox_page,node_singbox_subscriptions,node_singbox_logs toneMint
class node_easytier,node_lucky,node_staticarp toneRose
class node_speedtest,node_pftop,node_ttyd,node_lang,node_operator toneIndigo
```

## Components

### Dynamic DNS

- [DDNS page](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/IndexController.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/IndexController.php`
- [Accounts API](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/AccountsController.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/AccountsController.php`
- [Settings API](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/SettingsController.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/SettingsController.php`
- [Service API](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/ServiceController.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/ServiceController.php`
- [Config validation](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.php`
- [Account fields](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/AccountField.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/AccountField.php`
- [Service fields](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/ServiceField.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/ServiceField.php`
- [Check-IP fields](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/CheckipField.php): `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/CheckipField.php`
- [DDNS widget](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/www/js/widgets/Dyndns.js): `src/os-ddclient-opnwall/src/usr/local/opnsense/www/js/widgets/Dyndns.js`
- [DDNS daemon](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/ddclient_opn.py): `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/ddclient_opn.py`
- [Address poller](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/poller.py): `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/poller.py`
- [Address discovery](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/address.py): `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/address.py`
- [Provider adapters](https://github.com/opnwall/opnsense-repo/tree/main/src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/account): `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/account`
- **Hetzner DNS API**
- [DDNS-Go](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ddns-go/src/usr/local/www/services_ddnsgo.php): `src/os-ddns-go/src/usr/local/www/services_ddnsgo.php`

### DNS tools

- [Unbound custom settings](https://github.com/opnwall/opnsense-repo/blob/main/src/os-unboundcustom/src/opnsense/mvc/app/controllers/OPNsense/Unboundcustom/GeneralController.php): `src/os-unboundcustom/src/opnsense/mvc/app/controllers/OPNsense/Unboundcustom/GeneralController.php`

### Proxy tools

- [Mihomo proxy](https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/www/mihomo.php): `src/os-mihomo/src/usr/local/www/mihomo.php`
- [Mihomo subscriptions](https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/www/mihomo_sub.php): `src/os-mihomo/src/usr/local/www/mihomo_sub.php`
- [Mihomo logs](https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/www/mihomo_logs.php): `src/os-mihomo/src/usr/local/www/mihomo_logs.php`
- [Unbound setup](https://github.com/opnwall/opnsense-repo/blob/main/src/os-mihomo/src/usr/local/opnsense/scripts/mihomo/setup_unbound.php): `src/os-mihomo/src/usr/local/opnsense/scripts/mihomo/setup_unbound.php`
- [sing-box proxy](https://github.com/opnwall/opnsense-repo/blob/main/src/os-sing-box/src/usr/local/www/sing-box.php): `src/os-sing-box/src/usr/local/www/sing-box.php`
- [sing-box subscriptions](https://github.com/opnwall/opnsense-repo/blob/main/src/os-sing-box/src/usr/local/www/sing-box_sub.php): `src/os-sing-box/src/usr/local/www/sing-box_sub.php`
- [sing-box logs](https://github.com/opnwall/opnsense-repo/blob/main/src/os-sing-box/src/usr/local/www/sing-box_log.php): `src/os-sing-box/src/usr/local/www/sing-box_log.php`

### Network utilities

- [EasyTier VPN](https://github.com/opnwall/opnsense-repo/blob/main/src/os-easytier/src/usr/local/www/easytier.php): `src/os-easytier/src/usr/local/www/easytier.php`
- [Lucky tools](https://github.com/opnwall/opnsense-repo/blob/main/src/os-lucky/src/usr/local/www/lucky.php): `src/os-lucky/src/usr/local/www/lucky.php`
- [Static ARP](https://github.com/opnwall/opnsense-repo/blob/main/src/os-staticarp/src/usr/local/www/services_staticarp.php): `src/os-staticarp/src/usr/local/www/services_staticarp.php`

### Diagnostics and localization

- [Speedtest](https://github.com/opnwall/opnsense-repo/blob/main/src/os-speedtest/src/usr/local/www/diagnostics_speedtest.php): `src/os-speedtest/src/usr/local/www/diagnostics_speedtest.php`
- [pfTop diagnostics](https://github.com/opnwall/opnsense-repo/blob/main/src/os-pftop/src/usr/local/www/diag_pftop.php): `src/os-pftop/src/usr/local/www/diag_pftop.php`
- [ttyd terminal](https://github.com/opnwall/opnsense-repo/blob/main/src/os-ttyd/src/usr/local/www/diag_ttyd.php): `src/os-ttyd/src/usr/local/www/diag_ttyd.php`
- [Chinese localization](https://github.com/opnwall/opnsense-repo/blob/main/src/os-lang/src/usr/local/www/lang_update.php): `src/os-lang/src/usr/local/www/lang_update.php`

### Other components

- **OPNsense operator**

## Connections

- OPNsense operator → DDNS page: opens
- Accounts API → Config validation: uses model (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/AccountsController.php`)
- Settings API → Config validation: uses model (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/SettingsController.php`)
- Service API → Config validation: configures service (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/controllers/OPNsense/DynDNS/Api/ServiceController.php`)
- Account fields → Config validation: extends model fields (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/AccountField.php`)
- Service fields → Config validation: reads backend setting (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/ServiceField.php`)
- Check-IP fields → Config validation: reads backend setting (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/mvc/app/models/OPNsense/DynDNS/FieldTypes/CheckipField.php`)
- DDNS daemon → Address poller: starts poller (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/ddclient_opn.py`)
- Address poller → Provider adapters: loads adapters (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/poller.py`)
- Provider adapters → Hetzner DNS API: updates DNS records (evidence: `src/os-ddclient-opnwall/src/usr/local/opnsense/scripts/ddclient/lib/account/hetzner.py`)
