Commit Graph
100 Commits
Author SHA1 Message Date
Cuong Manh Le efb5a92571 Using time interval for probing ipv6
A backoff with small max time will flood requests to Control D server,
causing false positive for abuse mitiation system. While a big max time
will cause ctrld not realize network change as fast as possible.

While at it, also sync DoH3 code with DoH code, ensuring no others place
can trigger requests flooding for ipv6 probing.
2023-11-08 23:51:18 +07:00
Cuong Manh Le 8e0a96a44c Fix panic dues to quic-go changes
quic.DialEarly requires separate UDP connection for each
quic.EarlyConnection instead of re-using the same one.
2023-11-08 23:51:18 +07:00
Cuong Manh Le 43ff2f648c internal/router/dnsmasq: disable cache
So multiple upstreams config could work properly.
2023-11-08 23:51:18 +07:00
Cuong Manh Le 4816a09e3a all: use private resolver for private IP address
These queries could not be resolved by Control D upstreams, so it's
useless and less performance to send them to servers.
2023-11-08 23:51:18 +07:00
Cuong Manh Le 3fea92c8b1 Bump golang.org/x/net to v0.17.0 2023-11-08 23:51:08 +07:00
Cuong Manh Le 63f959c951 all: spoof loopback ranges in client info
Sending them are useless, so using RFC1918 address instead.
2023-11-06 20:01:57 +07:00
Cuong Manh Le 44ba6aadd9 internal/clientinfo: do not complain about net.ErrClosed
The probeLoop may have closed the connection before readLoop return, and
we don't care about this error. So prevent it from annoying the log.
2023-11-06 20:01:42 +07:00
Cuong Manh Le d88cf52b4e cmd/cli: always rebootstrap when check upstream
Otherwise, network changes may not be seen on some platforms, causing
ctrld failed to recover and failing all requests.

While at it, also doing the check DNS in separate goroutine, prevent it
from blocking ctrld from notifying others that it "started". The issue
was seen when ctrld is configured as direct listener, requests are
flooded before ctrld started, causing the healtch process failed.
2023-11-06 20:01:25 +07:00
Cuong Manh Le 58a00ea24a all: implement reload command
This commit adds reload command to ctrld for re-fetch new config from
ContorlD API or re-read the current config on disk.
2023-11-06 20:01:03 +07:00
Cuong Manh Le 712b23a4bb cmd/cli: initialize upstream proto for mobile 2023-11-06 20:00:28 +07:00
Cuong Manh Le baf836557c cmd/cli: fix wrong checking condition in removeProvTokenFromArgs
The provision token is only used once, then do not have any effect after
Control D uid is fetched. So making it appears in "ctrld run" command is
useless.
2023-11-06 20:00:10 +07:00
Cuong Manh Le 904b23eeac cmd/cli: add --proto flag to set upstream type in cd mode 2023-11-06 19:59:52 +07:00
Cuong Manh Le 6aafe445f5 cmd/cli: add nextdns mode
Adding --nextdns flag to "ctrld start" command for generating ctrld
config with nextdns resolver id, then use nextdns as an upstream.
2023-11-06 19:59:31 +07:00
Cuong Manh Le df4e04719e cmd/cli: relax service dependency on systemd-networkd-wait-online
ctrld wants systemd-networkd-wait-online starts before starting itself,
but ctrld should not be blocked waiting for it started.
2023-11-06 19:58:32 +07:00
Cuong Manh Le 2440d922c6 all: add MAC address base policy
While at it, also update the config doc to clarify the order of matching
preference, and the matter of rules order within each policy.
2023-11-06 19:57:50 +07:00
Cuong Manh Le 79076bda35 scripts: fix wrong package path 2023-10-10 22:04:59 +07:00
Cuong Manh Le 9d2ea15346 internal/clientinfo: ignoring localhost entry for hostsfile mapping
Otherwise, actual hostname will be overriden with "localhost", which is
rather confusing/bad for UX.
2023-10-10 22:04:59 +07:00
Cuong Manh Le 77c1113ff7 Excluding nameservers from /etc/resolv.conf for private resolver
Since these ones are either ctrld itself or direct listener that ctrld
is being upstream for, which makes health check query always succeed.
2023-10-06 08:57:47 +07:00
Cuong Manh Le e03ad4cd77 cmd/cli: ensure cd/cd-org flags must be non-empty 2023-10-04 16:34:47 +07:00
Cuong Manh Le 6e28517454 all: generalize vpn client info
VPN clients often have empty MAC address, because they come from virtual
network interface. However, there's other setup/devices also create
virtual interface, but is not VPN.

Changing source of those clients to empty to prevent confustion in
clients list command output.
2023-10-04 16:34:47 +07:00
Cuong Manh Le 8ddbf881b3 Sync quic transport code with DOH transport
Otherwise, the old code will leave un-used connections open-ed, causing
ports leaking and prevent others from creating UDP conn.
2023-10-04 16:34:47 +07:00
Cuong Manh Le 34758f6205 Sending OS information in DoH header 2023-09-22 18:47:14 +07:00
Cuong Manh Le a9959a6f3d all: guarding against DNS forwarding loop
Based on how dnsmasq "--dns-loop-detect" mechanism.

See: https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
2023-09-22 18:46:43 +07:00
Cuong Manh Le 511c4e696f cmd/cli: add upstream monitor
Some users mentioned that when there is an Internet outage, ctrld fails
to recover, crashing or locks up the router. When requests start
failing, this results in the clients emitting more queries, creating a
resource spiral of death that can brick the device entirely.

To guard against this case, this commit implement an upstream monitor
approach:

 - Marking upstream as down after 100 consecutive failed queries.
 - Start a goroutine to check when the upstream is back again.
 - When upstream is down, answer all queries with SERVFAIL.
 - The checking process uses backoff retry to reduce high requests rate.
 - As long as the query succeeded, marking the upstream as alive then
   start operate normally.
2023-09-22 18:45:59 +07:00
Cuong Manh Le bed7435b0c cmd: refactoring Run function
So it's easier, more clear, more isolation between code on non-mobile
and mobile platforms.
2023-09-22 18:45:00 +07:00
Cuong Manh Le 2765487f10 cmd/cli: use better approach for detecting NetworkManager
Currently, ctrld assumes that NetworkManager is not available if writing
to /etc/NetworkManager/conf.d return directory not exist error. That
would work on most Linux distros. However, cloud provider may do some
hacks, causing ctrld confusion and think that NetworkManager is
available.

Fixing this by checking whether NetworkManager binary presents first.

While at it, also fixing a bug when restarting NetworkManager failed
causing ctrld hangs. The go-systemd library is not clear about this, but
the waitCh channel won't never be closed if error occurred, so we must
return immediately instead of receiving from it blindly.
2023-09-22 18:42:21 +07:00
Cuong Manh Le 80a88811cd cmd/cli: restart systemd-resolved after setting DNS
So the current selected DNS server will be reset, and the new one will
be used by systemd-resolved after first query made.
2023-09-22 18:41:48 +07:00
Cuong Manh Le 823195c504 internal/clientinfo: monitor nameserver health
In case the resolver could not reach nameserver, ptr discover should
only print error message once, then stop doing the query until the
nameserver is reachable. This would prevent ptr discover from flooding
ctrld log with a lot of duplicated messages.
2023-09-22 18:41:40 +07:00
Cuong Manh Le 0f3e8c7ada all: include client IP if ctrld is dnsmasq upstream
So ctrld can record the raw/original client IP instead of looking up
from MAC to IP, which may not the right choice in some network setup
like using wireguard/vpn on Merlin router.
2023-09-22 18:40:25 +07:00
Cuong Manh Le ee5eb4fc4e cmd/cli: another fix for finding default route IP
The current approach to get default route IP is finding the LAN
interface with the same MAC address. However, there could be multiple
interfaces like that, making ctrld confused.

This commit fixes this issue, by listing all possible private IPs, then
sorting them and use the smallest one for router self queries.
2023-09-22 18:39:47 +07:00
Cuong Manh Le d58d8074f4 internal/clientinfo: use jaytaylor/go-hostsfile for parsing hosts file
txn2/txeh lower the hostname, which is not suitable for ctrld use case.
2023-09-22 18:39:04 +07:00
Cuong Manh Le 94a0530991 cmd/cli: fix default route IP with public interface
For reporting router queries, ctrld uses private IP of the default route
interface. However, when the default route is conntected directly to
ISP, the interface will have a public IP, and another interface with the
same MAC address will be created for LAN ip. So when no private IP found
for default route interface, ctrld must look at the other interface to
find the corret LAN ip.
2023-09-22 18:38:40 +07:00
Cuong Manh Le 073af0f89c Always use ctrld bootstrap nameserver for ResolverTypeOS
So in case no nameservers can be found, default OS resolver could still
resolve queries.
2023-09-22 18:37:54 +07:00
Cuong Manh Le 6028b8f186 internal/router/edgeos: use /etc/version for checking USG
Since mca-cli-op may not be available during boot time.
2023-09-22 18:37:04 +07:00
Cuong Manh Le 126477ef88 all: do not depend on vyatta-dhcpd service on EdgeOS
The only reason that forces ctrld to depend on vyatta-dhcpd service on
EdgeOS is allowing ctrld to watch lease files properly, because those
files may not be created at the time client info table initialized.

However, on some EdgeOS version, vyatta-dhcpd could not start with an
empty config file, causing restart loop itself, flooding systemd log,
making the router run out of memory.

To fix this, instead of depending on vyatta-dhcpd, we should just watch
for lease files creation, then adding them to watch list.

While at it, also making ctrld starts after nss-lookup, ensuring we have
a working DNS before starting ctrld.
2023-09-22 18:35:36 +07:00
Cuong Manh Le 13391fd469 Generating working default config in non-cd mode
Using the same approach as in cd mode, but do it only once when running
ctrld the first time, then the config will be re-used then.

While at it, also adding Dockerfile.debug for better troubleshooting
with alpine base image.
2023-09-22 18:34:46 +07:00
Cuong Manh Le 82e44b01af Add hosts file as source for hostname resolver 2023-09-22 18:29:37 +07:00
Cuong Manh Le e355fd70ab Upgrading quic-go to v0.38.0 2023-09-22 18:28:36 +07:00
Cuong Manh Le d5c171735e internal/clientinfo: make ptr lookup failure log level WARN 2023-09-22 18:27:22 +07:00
Cuong Manh Le bcf4c25ba8 Use 1.20-bullseye in Dockerfile
The current quic-go v0.32.0 could not be built with go 1.21, next
release of ctrld will upgrade it to latest version.

Fixes #82
2023-09-05 22:39:15 +07:00
Cuong Manh Le f39512b4c0 cmd/ctrld: only write to config file if listener config changed
Updates #149
2023-08-29 10:01:33 +07:00
Cuong Manh Le 7ce62ccaec Validate DoH/DoH3 endpoint properly
When resolver type is doh/doh3, the endpoint must be a valid http url.

Updates #149
2023-08-29 10:01:06 +07:00
Cuong Manh Le 44c0a06996 scripts: add missing build script 2023-08-17 16:52:04 +07:00
Cuong Manh Le 2bcba7b578 cmd/ctrld: workaround staticcheck complain on non-Linux OSes 2023-08-15 18:22:38 +07:00
Cuong Manh Le 829e93c079 cmd: allow import/running ctrld as library 2023-08-15 18:22:38 +07:00
Cuong Manh Le 4896563e3c Various improvements and bug fixes
- Watch more events for lease file changes
 - Improving network up detection by using bootstrap IPv6 along side
   IPv4 one.
 - Emitting log to notice user that ctrld is starting.
 - Using systemd wrapper to provide correct status.
 - Restoring DNS on stop on Windows.
2023-08-14 21:22:11 +07:00
Cuong Manh Le 0c096d5f07 internal/router: make router.Cleanup idempotent
On routers where we want to wait for NTP by checking nvram key. Before
waiting, we clean up the router to ensure it's restored to original
state. However, router.Cleanup is not idempotent, causing dnsmasq
restarted. On tomato/ddwrt, restarting have no delay, and spawning new
dnsmasq process immediately. On merlin, somehow it takes time to spawn
new dnsmasq process, causing ctrld wrongly think there's no one
listening on port 53.

Fixing this by ensuring router.Cleanup is idempotent. While at it, also
adding "ntp_done" to nvram key, which is now using on latest ddwrt.
2023-08-14 21:22:11 +07:00
Cuong Manh Le 32219e7d32 internal/router: wait ntp synced on Synology 2023-08-11 20:28:03 +07:00
Cuong Manh Le d292e03d1b Satisfying staticcheck linter 2023-08-10 00:33:42 +07:00
Cuong Manh Le 5dd6336953 internal/router/synology: define normal exit condition 2023-08-10 00:00:24 +07:00
Cuong Manh Le 854a244ebb Fix restart command when ctrld service was already stopped 2023-08-09 23:57:52 +07:00
Cuong Manh Le 125b4b6077 cmd/ctrld: wait ctrld started during restart command 2023-08-09 23:57:41 +07:00
Cuong Manh Le 46e8d4fad7 cmd/ctrld: prevent race condition when ping socket control server 2023-08-09 23:57:30 +07:00
Cuong Manh Le e5389ffecb internal/clientinfo: use all possible source IP for listing clients 2023-08-09 23:57:20 +07:00
Cuong Manh Le 46509be8a0 cmd/ctrld: start service before restart on Windows
On Windows, calling s.Restart will fail if service is not running,
ensure ctrld is started before calling restart.
2023-08-09 23:57:08 +07:00
Cuong Manh Le d3d2ed539f cmd/ctrld: correct syscall.Errno for Windows
On Windows, the syscall error numbers are different, so correct the
value so we can detect right errors we want.
2023-08-09 23:56:55 +07:00
Cuong Manh Le 8496adc638 cmd/ctrld: make self-check process more resilient 2023-08-09 23:56:41 +07:00
Cuong Manh Le e1d078a2c3 Ignoring RFC 1918 addresses for ControlD upstream 2023-08-09 23:56:31 +07:00
Cuong Manh Le 0dee7518c4 cmd/ctrld: validate UID during start command 2023-08-09 23:56:20 +07:00
Cuong Manh Le 774f07dd7f internal/router: only do cleanup in cd mode on freebsd 2023-08-09 23:56:07 +07:00
Cuong Manh Le c271896551 all: add support for provision token 2023-08-09 23:55:56 +07:00
Cuong Manh Le 82d887f52d cmd/ctrld: preserve OS error when updating listener config 2023-08-09 23:55:45 +07:00
Cuong Manh Le 6e27f877ff internal/clientinfo: use ptr cache when listing clients 2023-08-09 23:55:29 +07:00
Cuong Manh Le 39a2cab051 internal/clientinfo: only do self discover with client id
While at it, also ensure that client info table was initialized before
doing any lookup.
2023-08-09 23:55:13 +07:00
Cuong Manh Le 72d2f4e7e3 internal/controld: add support for parsing client id from raw UID 2023-08-09 23:54:44 +07:00
Cuong Manh Le 19bc44a7f3 all: prevent data race when accessing zerolog.Logger 2023-08-09 23:54:23 +07:00
Cuong Manh Le 59dc74ffbb internal: record correct interfaces for queries from router on Firewalla 2023-08-09 23:54:23 +07:00
Cuong Manh Le 12c8ab696f cmd/ctrld: use RFC1918 addresses as nameservers if required 2023-08-09 23:54:23 +07:00
Cuong Manh Le 28f32bd7e5 cmd/ctrld: use controlServer register method 2023-08-09 23:54:23 +07:00
Cuong Manh Le 6b43639be5 cmd/ctrld: wait until ctrld listener ready to do self-check 2023-08-09 23:54:23 +07:00
Cuong Manh Le 6be80e4827 internal/router: generalize freebsd-like router support 2023-08-09 23:54:23 +07:00
Cuong Manh Le 437fb1b16d all: add clients list command to debug Mac discovery 2023-08-09 23:54:23 +07:00
Cuong Manh Le 61b6431b6e cmd/ctrld: trim os version on freebsd 2023-08-09 23:54:23 +07:00
Cuong Manh Le 7ccecdd9f7 cmd/ctrld: add more debugging information when self-check failed 2023-08-09 23:54:23 +07:00
Cuong Manh Le e43b2b5530 internal/clientinfo: add doc comments for mdns operations
While at it, also remove un-used channel argument of probe function.
2023-08-09 23:54:23 +07:00
Cuong Manh Le 2cd8b7e021 internal/clientinfo: remove dhcp from refresher list
dhcp lease files are watched separately using fsnotify, it does not need
to be in refresher list.
2023-08-09 23:54:23 +07:00
Cuong Manh Le d6768c4c39 internal/clientinfo: use default route IP as self client info 2023-08-09 23:54:23 +07:00
Cuong Manh Le 59a895bfe2 internal/clientinfo: improving mdns discovery
- Prevent duplicated log message.
 - Distinguish in case of create/update hostname.
 - Stop probing if network is unreachable or invalid.
2023-08-09 23:54:23 +07:00
Cuong Manh Le cacd957594 internal/clientinfo: do not lower case hostname 2023-08-09 23:54:23 +07:00
Cuong Manh Le 2cd063ebd6 cmd/ctrld: do client info table init in separated goroutine
So it won't cause the listener take more times to be ready.
2023-08-09 23:54:23 +07:00
Cuong Manh Le 9ed8e49a08 all: make router setup/cleanup works more generally 2023-08-09 23:54:23 +07:00
Cuong Manh Le 66cb7cc21d cmd/ctrld: general UX improvement 2023-08-09 23:54:23 +07:00
Cuong Manh Le 4bf09120ff cmd/ctrld: spawn RFC1918 listeners if listen on 127.0.0.1:53 2023-08-09 23:54:23 +07:00
Cuong Manh Le be0769e433 cmd/ctrld: do not create config dir if not necessary 2023-08-09 23:54:23 +07:00
Cuong Manh Le 7b476e38be cmd/ctrld: do not spawn extra listener if conflicted in cd mode 2023-08-09 23:54:23 +07:00
Cuong Manh Le 0a7d3445f4 all: use 127.0.0.1 as nameserver when ctrld is an upstream 2023-08-09 23:54:23 +07:00
Cuong Manh Le 76d2e2c226 Improving Mac discovery 2023-08-09 23:54:23 +07:00
Cuong Manh Le 3007cb86ec cmd/ctrld: add control server/client via unix socket 2023-08-09 23:54:23 +07:00
Cuong Manh Le fa3af372ab Use ControlD anycast IP if no system DNS found 2023-08-09 23:54:23 +07:00
Cuong Manh Le 48a780fc3e cmd/ctrld: add workaround for default iface name on Ubios 2023-08-09 23:54:23 +07:00
Cuong Manh Le 28df551195 cmd/ctrld: prefix log with listener number when update listener config 2023-08-09 23:54:23 +07:00
Cuong Manh Le e65a71b2ae cmd/ctrld: do not try random local ip if IP is v4/v6 zero 2023-08-09 23:54:23 +07:00
Cuong Manh Le dc61fd2554 all: update handling of local config
For local config, we don't want to alter what user explicitly set, and
only try filling in missing value.

While at it, also remove the dnsmasq port delete on openwrt, we don't
need that hack anymore.
2023-08-09 23:54:23 +07:00
Cuong Manh Le a4edf266f0 all: workaround problem with EdgeOS dnsmasq config 2023-08-09 23:54:23 +07:00
Cuong Manh Le 7af59ee589 all: rework fetching/generating config in cd mode
Config fetching/generating in cd mode is currently weird, error prone,
and easy for user to break ctrld when using custom config.

This commit reworks the flow:

 - Fetching config from Control D API.
 - No custom config, use the current default config.
 - If custom config presents, but there's no listener, use 0.0.0.0:53.
 - Try listening on current ip+port config, if ok, ctrld could be a
   direct listener with current setup, moving on.
 - If failed, trying 127.0.0.1:53.
 - If failed, trying current ip + port 5354
 - If still failed, pick a random ip:port pair, retry until listening ok.

With this flow, thing is more predictable/stable, and help removing the
Config interface for router.
2023-08-09 23:54:23 +07:00
Cuong Manh Le 3f3c1d6d78 Fix Ping upstream cause ctrld crash
dohTransport returns a http.RoundTripper. When pinging upstream, we do
it both for doh and doh3, and checking whether the transport is nil
before performing the check.

However, dohTransport returns a concrete *http.Transport. Thus
dohTransport will always return a non-nil http.Roundtripper, causing
invalid memory dereference when upstream is configured to use doh3.

Performing ping upstream separately will fix the issue.
2023-08-09 23:54:23 +07:00
Cuong Manh Le ab1d7fd796 cmd/ctrld: lower status string before checking
Depending on system, the output of `/etc/init.d/ctrld status` can be
either "Running" or "running", we must do in-sensitive comparison to get
the right status of ctrld.
2023-08-09 23:54:23 +07:00
Cuong Manh Le 6c2996a921 cmd/ctrld: use sysv service wrapper for "unix-systemv" platform 2023-08-09 23:54:23 +07:00
Cuong Manh Le de32dd8ba4 cmd/ctrld: better error message for parsing/validation error 2023-08-09 23:54:23 +07:00
Cuong Manh Le d43e50ee2d cmd/ctrld: produce better message when "ctrd start" failed
The current error message is not much helpful, not all users are able to
investigate system log file to find the reason.

Instead, gathering the log output of "ctrld run" command, and if error
happens or self-check failed, print the log to users.
2023-08-09 23:54:23 +07:00