- Go 98.1%
- Makefile 1.1%
- Dockerfile 0.8%
Generic SRV records checker for happyDomain.
For each SRV record attached to an svcs.UnknownSRV service, the checker
resolves every target and probes reachability:
- DNS resolution (A/AAAA), CNAME detection (RFC 2782 violation),
null-target detection (RFC 2782 "service explicitly unavailable")
- TCP connect to target:port for _tcp SRVs
- UDP probe for _udp SRVs, using ICMP port-unreachable detection
The checker also publishes TLS endpoints (host, port, SNI) for every
SRV target hitting a well-known direct-TLS port (443, 465, 636, 853,
993, 995, 5061, 5223, …) via the EndpointDiscoverer SDK interface, so
a downstream TLS checker can pick them up.
The HTML report groups records as cards and surfaces the most common
failure scenarios (DNS failure, CNAME target, TCP unreachable,
null-target) at the top with remediation guidance.
|
||
|---|---|---|
| checker | ||
| plugin | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| README.md | ||
checker-srv
Generic SRV records checker for happyDomain.
For every SRV record attached to a service, verifies:
- DNS resolution of each target (A/AAAA)
- RFC 2782 compliance: target is not
"."(null), target is not a CNAME - TCP reachability on
target:port(for_tcpSRVs) - UDP reachability on
target:port(for_udpSRVs), via ICMP port-unreachable detection
TLS/certificate testing is intentionally out of scope, it belongs to a dedicated TLS checker.
The HTML report surfaces the most common failure scenarios at the top with actionable remediation guidance (DNS failure, CNAME-as-target, TCP unreachable, explicit null-target).
Usage
Standalone HTTP server
# Build and run
make
./checker-srv -listen :8080
The server exposes:
GET /health, health checkGET /definition, checker definition (options, rules, availability)POST /collect, collect SRV observations (happyDomain external checker protocol)POST /evaluate, evaluate observations against the rulesPOST /report, render the HTML report
Docker
make docker
docker run -p 8080:8080 happydomain/checker-srv
happyDomain plugin
make plugin
# produces checker-srv.so, loadable by happyDomain as a Go plugin
The plugin exposes a NewCheckerPlugin symbol returning the checker
definition and observation provider, which happyDomain registers in its
global registries at load time.
Versioning
The binary, plugin, and Docker image embed a version string overridable at build time:
make CHECKER_VERSION=1.2.3
make plugin CHECKER_VERSION=1.2.3
make docker CHECKER_VERSION=1.2.3
happyDomain remote endpoint
Set the endpoint admin option for the SRV checker to the URL of the running checker-srv server (e.g., http://checker-srv:8080). happyDomain will delegate observation collection to this endpoint.
Protocol
POST /collect
Request:
{
"key": "srv_records",
"target": {"userId": "...", "domainId": "...", "serviceId": "..."},
"options": {
"service": {"_svctype": "svcs.UnknownSRV", "Service": {"srv": [ /* dns.SRV records */ ]}},
"subdomain": "_sip._tcp",
"domain": "example.com",
"tcpTimeout": 3000,
"udpTimeout": 2000
}
}
Response:
{
"data": {
"serviceDomain": "_sip._tcp.example.com",
"records": [
{
"service": "sip",
"proto": "tcp",
"owner": "_sip._tcp.example.com",
"target": "sip1.example.com",
"port": 5061,
"priority": 10,
"weight": 20,
"addresses": ["203.0.113.5"],
"probes": [
{
"address": "203.0.113.5:5061",
"proto": "tcp",
"connected": true,
"latencyMs": 12.4
}
]
}
]
}
}
Discovered TLS endpoints
As a by-product of every /collect, this checker publishes
DiscoveryEntry records of type tls.endpoint.v1 (see
checker-tls/contract)
so that the TLS checker can probe the targets without re-parsing SRV data:
- Direct TLS entries (empty
STARTTLS) for service names that imply implicit TLS on connect:_https,_ldaps,_sips,_imaps,_pop3s,_smtps,_submissions,_xmpps-client,_xmpps-server,_ftps,_nntps,_ircs,_telnets,_ipps,_mqtts,_coaps,_stuns,_turns. - STARTTLS entries for service names that upgrade mid-stream:
_smtp(opportunistic),_submission(required),_imap(required),_pop3(required),_xmpp-client(required),_xmpp-server(opportunistic),_ldap,_nntp,_ftp,_sieve,_postgresql.
Null targets (.) and unknown service names are skipped. SNI is set to
the SRV target hostname.
Rules
| Name | Description |
|---|---|
srv_records_present |
At least one SRV record is published. |
srv_null_target |
Detects "." targets (RFC 2782, service intentionally unavailable). |
srv_target_not_cname |
Warns when an SRV target is a CNAME (RFC 2782 violation). |
srv_targets_resolve |
Every target resolves to at least one A/AAAA. |
srv_tcp_reachable |
Every _tcp SRV target:port accepts a TCP connection. |
srv_udp_reachable |
UDP targets do not return ICMP port-unreachable. |
srv_redundancy |
At least two distinct targets exist (no single point of failure). |
License & licensing roadmap
This project is currently licensed under the GNU Affero General Public
License v3.0 (see LICENSE), because it still imports
happydns.ServiceMessage from the happyDomain server module
(git.happydns.org/happyDomain/model), which is itself distributed under
AGPL-3.0 and a commercial license.
The core checker types (CheckerOptions, CheckerDefinition,
ObservationProvider, CheckRule, …) have already been migrated to
checker-sdk-go; only the
service-message types remain on the AGPL side.
Planned relicensing: as soon as the remaining ServiceMessage
dependency has been removed (moved into a dedicated permissively licensed
module), this project will be relicensed under the MIT License, in
line with the rest of the happyDomain checker ecosystem (see
checker-dummy for the target shape).
Contributors notice: by submitting a contribution to this repository, you accept that your contribution will be relicensed from AGPL-3.0 to MIT at the time of the relicensing described above. If you do not agree with this, please do not submit contributions until the relicensing has taken place.
The third-party Apache-2.0 attributions for checker-sdk-go are recorded
in NOTICE and must accompany any binary or source redistribution of this
project.