first commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
### Unifi Custom DNS Blocklist Manager: Project Summary and Web Application Template
|
||||
|
||||
#### Overview
|
||||
This project is inspired by a Bash script designed for Unifi network environments (or similar router/DNS setups) to manage a custom DNS blocklist for ad-blocking, malware prevention, phishing protection, and crypto-mining domain blocking. The original script monitors the CoreDNS process (a lightweight DNS server often used in containerized or edge router setups) for PID changes, indicating a restart or external modification. Upon detection, it automatically updates or merges a domain blocklist file (`/run/utm/domain_list/domainlist_0.list`) by fetching and processing lists from configurable URLs, applying removal rules from a whitelist file (`/run/utm/domain_list/domainlist_1.list`), cleaning invalid entries, and ensuring the active blocklist remains effective. It includes time-based throttling (e.g., full updates only every 3 days unless forced) to avoid excessive network fetches, while still handling external changes to the blocklist (e.g., from other system software) by merging them with the last known custom list (`/sdcard1/combined-blocklist.txt`). If the process isn't running, it resets monitoring. All actions are logged with timestamps for debugging.
|
||||
|
||||
The script's core functionality—automated blocklist updating, merging, validation, and DNS restarts—serves as the foundation for a modern web application. This app transforms the script into a user-friendly, secure web tool with a backend for automation and a frontend for interactive management. It maintains the script's logic for PID monitoring and auto-reapplication but adds a dark-themed web interface using Tailwind CSS for accessibility and aesthetics. The backend (preferably implemented in Go for efficiency and cross-platform compatibility) handles file operations, process management, and security, while the frontend provides intuitive controls. This setup is ideal for home lab enthusiasts, small network admins, or Unifi users seeking a Pi-hole or AdGuard Home-like experience with custom Unifi integration.
|
||||
|
||||
The app emphasizes security: all inputs are validated and sanitized to prevent code injection (e.g., via SQL injection if using a database, or command injection in shell calls). It supports a single administrative user with multi-factor authentication (MFA, e.g., TOTP via apps like Google Authenticator), configurable at runtime via command-line flags. Without authentication, no backend interactions are allowed—users are redirected to a login page. Configuration is stored in a JSON or YAML file (`config.json` or similar) in the executable's directory; if absent, the app generates a default config with placeholders for user credentials, paths, and settings.
|
||||
|
||||
#### Key Features and Architecture
|
||||
The web app replicates and extends the script's behavior, dividing responsibilities between backend and frontend while preserving modularity (e.g., via functions/services for update checks, merging, and restarts). It runs as a standalone executable (e.g., `./unifi-blocklist-manager -port=8080`), potentially as a service on a Unifi gateway or separate server.
|
||||
|
||||
##### Backend (Go-Recommended Implementation)
|
||||
- **PID Monitoring Loop**: Mirrors the script's infinite loop, checking CoreDNS PID every 5 seconds (configurable). If a change is detected without a user-initiated "Apply" action (tracked via an in-memory flag or timestamp), it triggers the blocklist update/merge logic automatically. Logs all actions to stdout or a file for auditing.
|
||||
- **Blocklist Update Logic**:
|
||||
- **Full Update**: If forced or 3+ days since last update (tracked via `/sdcard1/last_update.txt`), fetch domains from URLs in `/sdcard1/urllist.txt` (or a database equivalent for scalability). Merge with existing blocklist, clean invalid domains (e.g., using regex filters like the script's `grep` patterns), apply removals from `/run/utm/domain_list/domainlist_1.list` (via AWK-like logic in Go), and save to the active blocklist file. Update timestamp and restart CoreDNS (`pkill coredns`).
|
||||
- **Partial/Merge Update**: If time threshold not met, compare active blocklist with last custom list (`/sdcard1/combined-blocklist.txt`). If different (e.g., due to external modifications), merge uniquely (sort and dedupe), save, and restart CoreDNS.
|
||||
- Default URLs are pre-populated if the URL list file is missing, pulling from ad-blocking sources like AdGuard filters, Firebog, and Phishing Army.
|
||||
- **Process Management**: Securely execute system commands (e.g., `pgrep`, `pkill`) with input sanitization. Handle non-running CoreDNS by resetting PID file.
|
||||
- **Authentication and Config**:
|
||||
- Single user account: Configured via flags like `./app -setup-user=username -setup-pass=password -setup-mfa-secret=base32secret`. MFA uses TOTP; on first run, generate and display a QR code for scanning.
|
||||
- Config file: Auto-created if missing, containing encrypted credentials, file paths (e.g., blocklist locations), update delay (default 3 days), and check interval (default 5 seconds). Use Go libraries like Viper for config management.
|
||||
- Session-based auth: JWT or cookie sessions with short expiration; MFA required on login. Unauthenticated requests to management endpoints return 401/redirect.
|
||||
- **API Endpoints** (RESTful, e.g., using Gin framework):
|
||||
- GET `/api/urllists`: List current URLs (with status: enabled/disabled).
|
||||
- POST `/api/urllists/add`: Add new URL (validate as valid HTTP(S) URL).
|
||||
- DELETE `/api/urllists/remove`: Remove URL.
|
||||
- PATCH `/api/urllists/toggle`: Enable/disable URL.
|
||||
- GET `/api/domains/search?query=example*`: Search blocklist with wildcard support (e.g., using regex like `.*example.*` for `*example*`).
|
||||
- POST `/api/domains/add`: Add domain (validate as valid FQDN).
|
||||
- DELETE `/api/domains/remove`: Remove domain.
|
||||
- POST `/api/apply`: Trigger full/partial update and CoreDNS restart (sets a flag to indicate user-initiated change).
|
||||
- All endpoints require auth headers; validate inputs (e.g., no shell metachars, length limits).
|
||||
- **Security Measures**: Use prepared statements if database involved; escape all shell args; rate-limit API calls; HTTPS enforcement.
|
||||
|
||||
##### Frontend (Dark Theme with Tailwind CSS)
|
||||
- **Dashboard Layout**: A clean, responsive single-page app (SPA) or server-rendered pages (e.g., using Go templates or a framework like Echo with HTMX for interactivity). Dark theme by default (e.g., Tailwind's dark mode with slate/gray palettes, accents in blue for buttons).
|
||||
- **URL List Management**:
|
||||
- Table view of URLs from `/sdcard1/urllist.txt` (fetched via API), showing URL, description (auto-fetched or manual), enabled status, and actions (add, remove, toggle).
|
||||
- Add form: Input for new URL, with validation (client-side regex for URL format).
|
||||
- Similar to AdGuard Home's "Filters" tab or Pi-hole's "Adlists" under Group Management.
|
||||
- **Domain Search and Management**:
|
||||
- Search bar for final blocklist domains, supporting wildcards (e.g., `*google*` searches regex-matched entries). Results in a paginated table with domain, source (if trackable), and remove button.
|
||||
- Add domain form: Simple input for FQDN, append to blocklist or a custom additions file.
|
||||
- Inspired by Pi-hole's query log/search or AdGuard Home's domain filters.
|
||||
- **Apply Changes**: Prominent button that calls `/api/apply`, showing progress spinner and confirmation (e.g., "Changes applied, CoreDNS restarted"). Warns about potential network disruption.
|
||||
- **Login Page**: Form for username/password + MFA code. Responsive, with error messages for invalid creds.
|
||||
- **Additional Views**:
|
||||
- Logs page: Real-time or polled view of script-like logs (e.g., PID changes, updates).
|
||||
- Settings: View/edit config (e.g., update delay), but sensitive fields read-only.
|
||||
- **UI Best Practices**: Mobile-friendly (Tailwind responsive classes), accessible (ARIA labels), and minimalistic. No JavaScript-heavy if possible; use forms and HTMX for AJAX-like updates to keep it lightweight.
|
||||
|
||||
#### Usage and Deployment
|
||||
- Run: `./unifi-blocklist-manager [-port=8080] [-force] [-setup-user=...]`. The `-force` flag enables full updates on every trigger, overriding time checks.
|
||||
- Deployment: As a systemd service on Linux (e.g., Unifi OS). Expose on local network; use reverse proxy (e.g., Nginx) for HTTPS.
|
||||
- Similar Tools: Draws from Pi-hole (adlist management, group blocking) and AdGuard Home (filter lists, domain search) for UI inspiration, but tailored for Unifi/CoreDNS integration.
|
||||
|
||||
### Extra notes:
|
||||
- create Dark theme Tailwind CSS front end, what works good on desktop pc as on small mobile device screen
|
||||
- use html template, so the layout is preserved across all pages ( similar what Python Jinja templates do - i define base.html and then i referense it in index.html and extend it with page content...)
|
||||
- The user input should be secure and interaction with website and if someone would attempt to use some non-interactive access via bot or terminal it should not work for them, forms should use CSRF tokens - and only authenticated user should have access
|
||||
- as this will be small, you do not need database, file config for configuration should be enough ( the config would have hashed password and username, what can be set with command line flags used with the executable, for example `--new-user admin --password Admin123!`
|
||||
- to change password `--change-password admin <some strong new password>`
|
||||
- MFA would be possible to setup when user signs in to website, in their profile
|
||||
- the config file if does not exists will be created on first run in same folder as is executable
|
||||
Reference in New Issue
Block a user