119 lines
5.2 KiB
Markdown
119 lines
5.2 KiB
Markdown
ha-parental-controls
|
||
A Home Assistant dashboard for per-user, per-device internet blocking via OPNsense firewall alias management. Assign devices to users by MAC address, block/unblock individually or per-user, and optionally enforce scheduled access windows.
|
||
|
||
How it works
|
||
|
||
OPNsense maintains a firewall alias called parental_blocked
|
||
A LAN rule blocks all traffic from IPs in that alias
|
||
The HA dashboard looks up each device's current IP from device_tracker entities (provided by the OPNsense integration), then adds/removes IPs from the alias via OPNsense API
|
||
|
||
Because devices are identified by MAC address, blocks re-apply automatically when a device reconnects with a new IP (handled by a state change listener in the dashboard).
|
||
|
||
Step 1 — OPNsense setup
|
||
1.1 Create the firewall alias
|
||
Firewall → Aliases → +
|
||
FieldValueNameparental_blockedTypeHost(s)DescriptionParental Controls — blocked devicesContent(leave empty — managed via API)
|
||
Save, then Apply.
|
||
1.2 Create the blocking rule
|
||
Firewall → Rules → LAN → +
|
||
FieldValueActionBlockInterfaceLANDirectioninProtocolanySourceSingle host or alias → parental_blockedDestinationanyDescriptionParental Controls — block internet
|
||
Position this rule above your default allow-all LAN rule. Save and Apply.
|
||
1.3 Create an API key
|
||
System → Access → Users → (your admin user or a dedicated user) → API Keys → +
|
||
Permissions needed: Firewall: Alias (read + write)
|
||
Note the Key and Secret — you'll need them for secrets.yaml.
|
||
|
||
Step 2 — Home Assistant setup
|
||
2.1 Add secrets to /config/secrets.yaml
|
||
Replace values with your actual OPNsense details:
|
||
yamlopnsense_alias_add_url: "https://YOUR_OPNSENSE_IP/api/firewall/alias_util/add/parental_blocked"
|
||
opnsense_alias_del_url: "https://YOUR_OPNSENSE_IP/api/firewall/alias_util/delete/parental_blocked"
|
||
opnsense_apply_url: "https://YOUR_OPNSENSE_IP/api/firewall/alias/reconfigure"
|
||
|
||
# Generate with: echo -n "APIKEY:APISECRET" | base64
|
||
opnsense_basic_auth: "Basic BASE64_OF_KEY_COLON_SECRET"
|
||
To generate the base64 string on any Linux/macOS machine:
|
||
bashecho -n "your_api_key:your_api_secret" | base64
|
||
2.2 Copy files into place
|
||
bash# From your config directory
|
||
cp packages/parental_controls.yaml /config/packages/
|
||
cp www/parental_controls.html /config/www/
|
||
|
||
If you don't use packages yet, add this to /config/configuration.yaml:
|
||
yamlhomeassistant:
|
||
packages: !include_dir_named packages
|
||
|
||
2.3 Add the sidebar panel
|
||
Add to /config/configuration.yaml:
|
||
yamlpanel_iframe:
|
||
parental_controls:
|
||
title: "Parental Controls"
|
||
icon: mdi:shield-account
|
||
url: /local/parental_controls.html
|
||
require_admin: true
|
||
2.4 Restart Home Assistant
|
||
Check for errors in Settings → System → Logs. The input_text.parental_control_config entity should now exist.
|
||
|
||
Step 3 — Dashboard first run
|
||
|
||
Open the Parental Controls sidebar panel
|
||
On first load, you'll see a setup screen. Enter:
|
||
|
||
HA URL: your HA URL (e.g. https://ha.hideawaygaming.com.au)
|
||
Long-Lived Token: from your HA Profile → Security → Long-Lived Access Tokens → Create Token
|
||
|
||
|
||
Click Connect
|
||
|
||
Your credentials are saved to browser localStorage — you won't need to enter them again on the same device.
|
||
|
||
Usage
|
||
Adding users
|
||
Click + Add User, give them a name and pick a colour.
|
||
Adding devices
|
||
On a user card, click + Add Device. Either:
|
||
|
||
Pick from the discovered devices list (devices seen by the OPNsense integration)
|
||
Or enter a MAC address manually
|
||
|
||
|
||
Tip: Set DHCP static leases in OPNsense for kids' devices so their IPs stay consistent, though the dashboard handles IP changes automatically.
|
||
|
||
Blocking
|
||
|
||
User toggle (top right of card): blocks/unblocks all devices for that user simultaneously
|
||
Device toggle (on each device row): individual device control
|
||
|
||
If a device is offline when you block it, the dashboard marks it blocked and will apply the firewall rule automatically when the device reconnects.
|
||
Scheduling
|
||
Expand the 🕐 Schedule section on any user card:
|
||
|
||
Enable the schedule toggle
|
||
Set block and unblock times for weekdays and weekends
|
||
Times are enforced every minute while the dashboard page is open
|
||
|
||
The time range is the blocked window — e.g. 21:00 → 07:00 means blocked from 9pm until 7am (overnight ranges work correctly).
|
||
HA-native schedule enforcement (optional)
|
||
For schedules to be enforced even when the dashboard isn't open, uncomment the automation: block at the bottom of packages/parental_controls.yaml and restart HA. Note: the YAML automation requires the from_json Jinja2 filter and HA 2023.4+.
|
||
|
||
Troubleshooting
|
||
Block doesn't seem to apply
|
||
|
||
Confirm the parental_blocked alias exists in OPNsense → Firewall → Aliases
|
||
Check the blocking rule is above the default LAN allow rule
|
||
Verify your API credentials: test in a browser → https://YOUR_OPNSENSE/api/firewall/alias_util/aliases — should return JSON
|
||
|
||
Device not appearing in discovered list
|
||
|
||
Make sure the OPNsense integration is installed and the device has been seen recently
|
||
Try using a manual MAC entry instead
|
||
|
||
"Failed to save config"
|
||
|
||
Check HA logs for input_text.parental_control_config errors
|
||
Ensure the package loaded correctly (no YAML errors in startup logs)
|
||
|
||
Dashboard won't connect
|
||
|
||
Confirm the Long-Lived Token is correct
|
||
If using a self-signed cert on HA, the page may have cert warnings — trust the cert first by visiting the HA URL directly |