mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-05-27 12:52:27 +02:00
Created pfSense and OPNsense Operations Guide (markdown)
@@ -0,0 +1,281 @@
|
||||
# Overview
|
||||
This article will discuss how `ctrld` can be operated on FreeBSD based router/firewall devices with support for advanced use cases.
|
||||
|
||||
Since pfSense and OPNsense are very similar, this single guide applies to both (for the most part).
|
||||
|
||||
# Install
|
||||
The simplest and quickest way to get `ctrld` on your router machine is to run the 1-liner install command.
|
||||
|
||||
```
|
||||
sh -c 'sh -c "$(curl -sSL https://api.controld.com/dl)"'
|
||||
```
|
||||
|
||||
Take this command and execute it in the shell. This will download a totally safe bash script, and execute it with system privilege.
|
||||
|
||||
## Manual Install
|
||||
If you feel antsy about blindly running random bash scripts off the Internet with system privilege (don't blame you), you can simply download the appropriate FreeBSD binary from the [Releases section](https://github.com/Control-D-Inc/ctrld/releases) for your CPU architecture. Put it into a nice folder that's in your system path, like `/usr/local/bin/` and make it executable.
|
||||
|
||||
# Basic Operations
|
||||
Now that you got the binary downloaded, you can run it with no args and check out the commands you can use to operate it.
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: ctrld
|
||||
__ .__ .___
|
||||
_____/ |________| | __| _/
|
||||
_/ ___\ __\_ __ \ | / __ |
|
||||
\ \___| | | | \/ |__/ /_/ |
|
||||
\___ >__| |__| |____/\____ |
|
||||
\/ dns forwarding proxy \/
|
||||
|
||||
Usage:
|
||||
ctrld [command]
|
||||
|
||||
Available Commands:
|
||||
run Run the DNS proxy server
|
||||
service Manage ctrld service
|
||||
start Quick start service and configure DNS on interface
|
||||
stop Quick stop service and remove DNS from interface
|
||||
restart Restart the ctrld service
|
||||
reload Reload the ctrld service
|
||||
status Show status of the ctrld service
|
||||
uninstall Stop and uninstall the ctrld service
|
||||
clients Manage clients
|
||||
|
||||
Flags:
|
||||
-h, --help help for ctrld
|
||||
-s, --silent do not write any log output
|
||||
-v, --verbose count verbose log output, "-v" basic logging, "-vv" debug level logging
|
||||
--version version for ctrld
|
||||
|
||||
Use "ctrld [command] --help" for more information about a command.
|
||||
```
|
||||
|
||||
I also strongly encourage you to [RTFM](https://github.com/Control-D-Inc/ctrld/blob/main/docs/config.md) which documents all the params you can use while crafting a custom config. More on this later.
|
||||
|
||||
## Yolo
|
||||
The simplest way to run `ctrld` is using this command: `ctrld start --cd RESOLVER_ID_HERE` while templating your Device's unique DNS resolver ID from the web control panel. When you run this command, the following things will happen:
|
||||
- Basic config file is fetched from the API and written to `/etc/controld/ctrld.toml`
|
||||
- **`unbound` and `dnsmasq` processes are terminated as they already listen on port 53** !!!
|
||||
- `ctrld` starts listeners on TCP/UDP port 53 on all interfaces
|
||||
- `/etc/resolv.conf` file is updated to point to the listener
|
||||
- DNS is updated on the main interface to use `ctrld`
|
||||
- Init script is added to `/usr/local/etc/rc.d` so `ctrld` can auto-start on reboot
|
||||
|
||||
|
||||
The state of the machine will be something like this:
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: sockstat -l | grep ctrld
|
||||
root ctrld 85084 3 stream /etc/controld/ctrld_control.sock
|
||||
root ctrld 85084 8 udp4 *:5353 *:*
|
||||
root ctrld 85084 18 tcp46 *:53 *:*
|
||||
root ctrld 85084 19 udp46 *:53 *:*
|
||||
root ctrld 85084 21 udp6 *:5353 *:*
|
||||
```
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: cat /etc/resolv.conf
|
||||
# resolv.conf(5) file generated by ctrld
|
||||
# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN
|
||||
|
||||
nameserver 127.0.0.1
|
||||
```
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: cat /etc/controld/ctrld.toml
|
||||
# AUTO-GENERATED VIA CD FLAG - DO NOT MODIFY
|
||||
|
||||
[listener]
|
||||
[listener.0]
|
||||
ip = '0.0.0.0'
|
||||
port = 53
|
||||
|
||||
[network]
|
||||
[network.0]
|
||||
name = 'Network 0'
|
||||
cidrs = ['0.0.0.0/0']
|
||||
|
||||
[upstream]
|
||||
[upstream.0]
|
||||
type = 'doh'
|
||||
endpoint = 'https://dns.controld.com/abcd1234'
|
||||
timeout = 5000
|
||||
```
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: ctrld clients list
|
||||
+-----------------------------------------+--------------------------------------+-------------------+------------+
|
||||
| IP | Hostname | Mac | Discovered |
|
||||
+-----------------------------------------+--------------------------------------+-------------------+------------+
|
||||
| 0.0.0.0 | 64d4f0da-6012-4483-adff-d0d434ef6476 | | mdns |
|
||||
| 10.0.10.1 | | 00:50:56:9f:0e:84 | arp |
|
||||
| 10.0.10.209 | pfSense | 00:0c:29:f5:a3:55 | arp,dhcp |
|
||||
| 10.0.10.222 | test-virtual-machine | 00:0c:29:4a:5c:57 | arp,mdns |
|
||||
| 10.0.10.238 | Office-Box | 74:56:3c:44:eb:5e | arp,mdns |
|
||||
| 10.0.10.245 | Test-W11 | | mdns |
|
||||
| 127.0.0.1 | pfSense | 00:0c:29:f5:a3:55 | dhcp |
|
||||
| ::1 | pfSense | 00:0c:29:f5:a3:55 | dhcp |
|
||||
+-----------------------------------------+--------------------------------------+-------------------+------------+
|
||||
```
|
||||
|
||||
If all you wanted was to receive DNS queries and send them all to a single Control D upstream using DNS-over-HTTPS, you have succeeded. If you didn't like the whole "kill unbound" thing as you use it for other purposes, then read on!
|
||||
|
||||
## Custom Config Mode
|
||||
In order to be able to modify the generated config file on disk, you need to de-couple it from the API if you used the `--cd RESOLVER_ID_HERE` flag (if not, then you're already in this mode and can skip doing this).
|
||||
To do this, execute the following commands:
|
||||
|
||||
- `ctrld stop` - this will stop the service
|
||||
- `ctrld start` - this will start the service in "local config mode" which enforces the config on disk
|
||||
|
||||
Now you can make changes to it, and execute `ctrld reload` command to enforce your changes.
|
||||
|
||||
# Advanced Operations
|
||||
If you're running `ctrld` in local config mode, some "yolo behavior" will no longer occur. Namely, you are now responsible for listener conflicts. If `unbound` and/or `dnsmasq` are listening on port 53, `ctrld` will not be able to start and you will be greeted with an error:
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: sockstat -l | grep \:53
|
||||
nobody dnsmasq 644 4 udp4 *:53 *:*
|
||||
nobody dnsmasq 644 5 tcp4 *:53 *:*
|
||||
nobody dnsmasq 644 6 udp6 *:53 *:*
|
||||
nobody dnsmasq 644 7 tcp6 *:53 *:*
|
||||
unbound unbound 98986 3 udp6 ::1:53 *:*
|
||||
unbound unbound 98986 4 tcp6 ::1:53 *:*
|
||||
unbound unbound 98986 5 udp4 127.0.0.1:53 *:*
|
||||
unbound unbound 98986 6 tcp4 127.0.0.1:53 *:*
|
||||
```
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: ctrld start
|
||||
Dec 8 01:51:35.000 NTC Reading config: /etc/controld/ctrld.toml
|
||||
Dec 8 01:51:35.000 NTC Starting service
|
||||
Dec 8 01:51:35.000 ERR ctrld service may not have started due to an error or misconfiguration, service log:
|
||||
Dec 8 01:51:35.000 ??? ================================
|
||||
Dec 8 01:51:35.000 ??? Dec 8 01:51:35.000 FTL listener.0 failed to listen: listen udp 0.0.0.0:53: bind: address already in use
|
||||
listen tcp 0.0.0.0:53: bind: address already in use
|
||||
Dec 8 01:51:35.000 ??? ================================
|
||||
Dec 8 01:51:35.000 NTC Service uninstalled
|
||||
```
|
||||
|
||||
As you're probably aware, if you need to still run either service at the same time as `ctrld`, you need to put them on a different port (or run `ctrld` on a different port instead).
|
||||
|
||||
## Local Domains
|
||||
One of the most common use cases is delegating local DNS resolution to `unbound` for all your LAN-local domains and PTR records, while sending all external DNS queries to the Control D upstream.
|
||||
|
||||
### Do nothing option
|
||||
If you're using v1.3.2 (or newer) of `ctrld` you technically don't have to do anything, as `ctrld` (with client discovery enabled) will resolve any LAN-local A or PTR record for you, using the data it has in the client list.
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: dig +short Test-W11
|
||||
10.0.10.245
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: dig +short -x 10.0.10.245
|
||||
Test-W11.
|
||||
```
|
||||
|
||||
Well, that's pretty neat. However you may not be as impressed as I am, and still want to leverage your trusty `unbound` instance, or any other LAN-local DNS resolver. That's fine, we can do that too.
|
||||
|
||||
### Custom Upstreams
|
||||
I'm going to assume you already have `unbound` or another DNS server running on a non-standard port, say 5555 which is capable of resolving local domains and serving PTR records for devices on a different vlan. Let's steer traffic to it using a custom config, which would look something like this:
|
||||
|
||||
```
|
||||
[listener]
|
||||
[listener.0]
|
||||
ip = '0.0.0.0'
|
||||
port = 53
|
||||
|
||||
[listener.0.policy]
|
||||
name = 'My Policy'
|
||||
networks = [
|
||||
{'network.0' = ['upstream.0']},
|
||||
{'network.1' = ['upstream.1']}
|
||||
]
|
||||
|
||||
rules = [
|
||||
{ '*.cool.domain' = ['upstream.1']},
|
||||
{ '*.in-addr.arpa' = ['upstream.1']}
|
||||
]
|
||||
|
||||
macs = [
|
||||
{"14:54:4a:8e:08:2d" = ["upstream.1"]}
|
||||
]
|
||||
|
||||
[network]
|
||||
[network.0]
|
||||
name = 'Main Subnets'
|
||||
cidrs = ['10.0.0.0/24', '10.0.1.0/24']
|
||||
|
||||
[network.1]
|
||||
name = 'Secret Subnet'
|
||||
cidrs = ['10.0.99.0/24']
|
||||
|
||||
[upstream]
|
||||
[upstream.0]
|
||||
name = 'My Fancy CD Resolver'
|
||||
type = 'doh'
|
||||
endpoint = 'https://dns.controld.com/abcd1234'
|
||||
timeout = 5000
|
||||
|
||||
[upstream.1]
|
||||
name = 'Custom Resolver'
|
||||
type = 'legacy'
|
||||
endpoint = '10.0.0.1:5555'
|
||||
timeout = 1000
|
||||
```
|
||||
|
||||
Not all params are needed, and shown for illustrative purposes only. It's not as scary as it looks. Let's go over it.
|
||||
1. In the `[listener]` block we define our.... listener with an IP + port.
|
||||
2. In the `[listener.0.policy]` block we define the policy of how DNS traffic should be routed, let's skip that over for a second.
|
||||
3. In the `[network]` block we define our subnets if you want to leverage source IP based routing. If you do not, don't define any.
|
||||
4. In the `[upstream]` block we define our DNS upstreams where DNS traffic should be sent. You should have at least one of these, but here we have 2.
|
||||
5. Coming back to the `[listener.0.policy]` block. It strings together the defined `networks` and `upstreams`, as well as new concepts like `rules` and `macs` and defines which upstream should be used if there is a match.
|
||||
6. The matching order is: rules => macs => networks
|
||||
|
||||
So for example:
|
||||
- A DNS query from `10.0.0.5` would be sent to `upstream.0`, while a query from `10.0.99.123` would be sent to `upstream.1`
|
||||
- A DNS query for `my-host.cool.domain` from any subnet would be sent to `upstream.1` (since host rules match first)
|
||||
- A DNS query from a device with MAC address `14:54:4a:8e:08:2d` from any subnet would be sent to `upstream.1` (since MAC rules match 2nd).
|
||||
- All PTR queries would be sent to `upstream.1`
|
||||
|
||||
You can find more [example configs](https://github.com/Control-D-Inc/ctrld/wiki/Example-Configurations) for different use cases in the Wiki.
|
||||
|
||||
## Don't touch my configs
|
||||
If your existing router configs are dear to your heart and you don't want no stinkin' 3rd party processes messing with them, I get you, and there is a solution to that as well.
|
||||
|
||||
If you simply want `ctrld` to spawn a listener (or multiple listeners) in order to receive DNS queries and follow the config defined logic, while not making any changes to the system (modifying DNS on interface, editing resolv.conf, etc), then the `service start` sub-command is your friend.
|
||||
|
||||
In this mode you're likely running `ctrld` on a non-standard port, so modify your config and set it:
|
||||
|
||||
```
|
||||
[listener]
|
||||
[listener.0]
|
||||
ip = '0.0.0.0'
|
||||
port = 42069
|
||||
.....
|
||||
```
|
||||
Then execute the `service start` command (it's just like `start` but with `service` before it).
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: ctrld service start
|
||||
Dec 14 00:02:08.000 NTC Reading config: /etc/controld/ctrld.toml
|
||||
Dec 14 00:02:08.000 NTC Starting service
|
||||
Dec 14 00:02:13.000 NTC Service started
|
||||
```
|
||||
|
||||
You can check the listeners, and notice that `ctrld` is listening on the config defined port, as well as the mDNS port for client discovery (you can shut this off if you don't like it by setting the `discover_mdns` config param to false):
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: sockstat -l | grep ctrld
|
||||
root ctrld 36674 3 stream /etc/controld/ctrld_control.sock
|
||||
root ctrld 36674 8 udp4 *:5353 *:*
|
||||
root ctrld 36674 11 udp6 *:5353 *:*
|
||||
root ctrld 36674 19 tcp46 *:42069 *:*
|
||||
root ctrld 36674 20 udp46 *:42069 *:*
|
||||
```
|
||||
|
||||
If you send DNS queries to this port, they will be subject to your config defined rules, and will be sent to Control D (if that's what you want).
|
||||
|
||||
```
|
||||
[2.7.0-RELEASE][root@pfSense.home.arpa]/var: dig verify.controld.com +short @127.0.0.1 -p 42069
|
||||
api.controld.com.
|
||||
147.185.34.1
|
||||
```
|
||||
|
||||
Protip: `verify.controld.com` will only resolve if you're using a Control D upstream, so that's a good domain to VERIFY that it's working.
|
||||
|
||||
# Troubleshooting
|
||||
If you're having trouble you can always contact us and we'll help you. But you can also wear your big boy pants and check out the [troubleshooting guide ](https://github.com/Control-D-Inc/ctrld/wiki/Troubleshooting-Guide) and likely self-resolve the issue in no time.
|
||||
Reference in New Issue
Block a user