Installing Control D natively on LibreELEC
This guide installs the Control D binary as a local DNS proxy on LibreELEC, ideal for unblocking streaming services without a VPN.
Remember to BACKUP before you try to install Control D. Regard: Peter
1. Download the binary
SSH into your LibreELEC device and run:
mkdir -p /storage/ctrld && cd /storage/ctrld
curl -L -o ctrld https://dl.controld.com/linux-arm64/ctrld
chmod +x ctrld
QuoteARM64 (Raspberry Pi 4/5, Rockchip, Amlogic). For x86_64 (Intel NUC, old PC) use:
curl -L -o ctrld https://dl.controld.com/linux-amd64/ctrld
Verify the binary:
Should print ctrld version v1.5.1 (or similar).
2. Get your Control D Resolver ID
- Log into Control D dashboard.
- Profile → DNS over HTTPS → copy Resolver ID (e.g., abcdef123456).
- Replace YOUR_RESOLVER_ID in the commands below.
3. Generate the configuration (first time only)
/storage/ctrld/ctrld run --cd YOUR_RESOLVER_ID --config /storage/ctrld/ctrld.toml --skip_self_checks
Wait a few seconds, then press Ctrl+C. This creates a full config file with captive portal bypass rules.
Verify the config contains your ID:
Expected: endpoint = 'https://dns.controld.com/YOUR_RESOLVER_ID'
QuoteImportant: After this step, never use --cd again – the config file already has your ID.
4. Create the autostart script (runs on boot)
Paste exactly (without --cd):
#!/bin/sh
(
sleep 20
/storage/ctrld/ctrld run --config /storage/ctrld/ctrld.toml --skip_self_checks > /storage/ctrld/boot.log 2>&1
) &
Save (Ctrl+O, Enter, Ctrl+X), then:
5. Start Control D manually (test before reboot)
Check it’s listening on port 53:
You should see :::53 or 0.0.0.0:53 in LISTEN state.
If you have problems, run with debug output (-vv) – press Ctrl+C to stop.
6. Point LibreELEC’s DNS to localhost
Find your active network service:
Look for AO or AR (e.g., ethernet_2ccf678483b1_cable). Then set DNS:
Example:
7. Reboot (required for DNS change to fully apply)
After reboot, SSH back in and verify:
Should show a running process (e.g., 1179 /storage/ctrld/ctrld).
Test DNS:
First line must show Server: 127.0.0.1.
Test unblocking:
Should return a proxy IP like 147.185.34.1.
Troubleshooting
| Problem | Fix |
|---|---|
| nslookup shows 127.0.0.1 but verify.controld.com fails | Control D not running – check pgrep -a ctrld and /storage/ctrld/boot.log. |
| pgrep shows nothing after reboot | Autostart script not executable: chmod +x /storage/.config/autostart.sh. Also check boot.log. |
| “address already in use” when running manually | Control D is already running – that’s fine. Only one instance can bind to port 53. |
| “Invalid configuration code” error | You used --cd with --config – remove --cd from command and autostart script. |
| DNS reverts after reboot | Set static IP via LibreELEC GUI, or re-run the connmanctl config command and reboot. |
Control D - Help commands | /storage/ctrld/ctrld --help |
Uninstall / revert to normal DNS
Revert to normal DNS:
connmanctl config YOUR_SERVICE_NAME --nameservers auto
Uninstall:
pkill ctrld
rm -rf /storage/ctrld
rm /storage/.config/autostart.sh
reboot
Notes
- Works on LibreELEC 10+ (Kodi 19+).
- Low RAM/CPU usage.
- Files in /storage survive system updates.
- Reboot is essential after connmanctl DNS change.
- pgrep -a ctrld shows PID 1178 running → Control D is active.
- nslookup google.com shows Server: 127.0.0.1 → system DNS is using localhost.
- nslookup verify.controld.com returns 147.185.34.1 → Control D proxy is working.
- The “address already in use” error when you ran -vv manually is simply because you already had Control D
- running (PID 1178). That’s expected – you can’t have two instances on port 53.
- boot.log is empty because --skip_self_checks suppresses most logging unless there’s an error. That’s fine.
- Enjoy your unblocked LibreELEC streaming!