mesh/delivery merged: source.main moved to novox/mesh-catalog@94805575379f
mesh/check checking c88be88ccf2f on 94805575379f
The two server lines were literals in the template, so changing an upstream needed a build. They are now the config keys upstream-resolver-first (1.1.1.1) and upstream-resolver-second (8.8.8.8), placed with ${config:...}; the service already restarts on its config file. no-resolv and every other line stay.
Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
182 lines
5.5 KiB
JSON
182 lines
5.5 KiB
JSON
{
|
|
"module": "dnsmasq",
|
|
"version": "1",
|
|
"upgrade": {
|
|
"policy": "record",
|
|
"why": "the mesh's resolver: a build that breaks it can stop a machine resolving the bus, and then neither the gate's rollback nor a push reaches it (hq ADR 0236, issue 260)"
|
|
},
|
|
"provides": [
|
|
{
|
|
"name": "wildcard-resolution",
|
|
"scope": "mesh",
|
|
"identity": false,
|
|
"credential": {
|
|
"form": "none"
|
|
}
|
|
}
|
|
],
|
|
"requires": [
|
|
"mesh-addressing"
|
|
],
|
|
"emits": [
|
|
"name.added",
|
|
"name.removed",
|
|
"restarted",
|
|
"restart-judged"
|
|
],
|
|
"own-secrets": {
|
|
"broker": "${dir:mesh-state}/broker"
|
|
},
|
|
"claims": [
|
|
{
|
|
"name": "mesh-dns-resolver",
|
|
"scope": "mesh"
|
|
}
|
|
],
|
|
"tools": [
|
|
"dnsmasq_health",
|
|
"dnsmasq_names",
|
|
"dnsmasq_resolve"
|
|
],
|
|
"config": {
|
|
"upstream-resolver-first": {
|
|
"type": "string",
|
|
"description": "The first public resolver this resolver forwards to for every name that is not the mesh's own, as an IP address. It is placed as a server line beside no-resolv, so it must never be an address that resolves through this machine; both upstreams should validate DNSSEC, since the authenticated-data bit is passed down (ADR 0194, ADR 0223). Set per node or for the whole mesh.",
|
|
"trusted": false,
|
|
"pattern": "^[0-9A-Fa-f.:]+$",
|
|
"default": "1.1.1.1"
|
|
},
|
|
"upstream-resolver-second": {
|
|
"type": "string",
|
|
"description": "The second public resolver this resolver forwards to, as an IP address, tried beside the first so one upstream being down does not stop name resolution. The same rules as upstream-resolver-first.",
|
|
"trusted": false,
|
|
"pattern": "^[0-9A-Fa-f.:]+$",
|
|
"default": "8.8.8.8"
|
|
}
|
|
},
|
|
"listens": [
|
|
{
|
|
"name": "dns-udp",
|
|
"port": 53,
|
|
"protocol": "udp",
|
|
"from": "mesh",
|
|
"why": "one of the mesh's resolvers (ADR 0194, 0223): every node's and every container's resolver, beside any other holder of the seat — the mesh's own names answered here, a module's zone forwarded to it, the rest forwarded upstream",
|
|
"fixed": true
|
|
},
|
|
{
|
|
"name": "dns-tcp",
|
|
"port": 53,
|
|
"protocol": "tcp",
|
|
"from": "mesh",
|
|
"why": "the same names over tcp, which a resolver answers on as well and is asked for whenever an answer will not fit in a datagram. Declared because the daemon serves it: a declaration that covers one of the two protocols its own service listens on leaves the other closed while everything reports success",
|
|
"fixed": true
|
|
}
|
|
],
|
|
"resources": [
|
|
{
|
|
"id": "mesh-state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"place": "mesh",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "package",
|
|
"type": "package",
|
|
"package": "dnsmasq"
|
|
},
|
|
{
|
|
"id": "config",
|
|
"type": "file",
|
|
"path": "/etc/dnsmasq.conf",
|
|
"mode": "0644",
|
|
"template": "files/dnsmasq.conf"
|
|
},
|
|
{
|
|
"id": "drop-ins",
|
|
"type": "directory",
|
|
"path": "/etc/systemd/system/dnsmasq.service.d",
|
|
"mode": "0755",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "wait-for-address",
|
|
"type": "file",
|
|
"path": "/etc/systemd/system/dnsmasq.service.d/mesh.conf",
|
|
"mode": "0644",
|
|
"template": "files/mesh.conf"
|
|
},
|
|
{
|
|
"id": "service",
|
|
"type": "service",
|
|
"unit": "dnsmasq.service",
|
|
"state": "running",
|
|
"boot": "enabled",
|
|
"restart-on": [
|
|
"config",
|
|
"wait-for-address",
|
|
"dnsmasq.fact-node-zones",
|
|
"dnsmasq.fact-zones"
|
|
],
|
|
"health": {
|
|
"kind": "unit"
|
|
}
|
|
},
|
|
{
|
|
"id": "watch-dir",
|
|
"type": "directory",
|
|
"path": "/var/lib/dnsmasq-watch",
|
|
"mode": "0755",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "watch",
|
|
"type": "process",
|
|
"name": "dnsmasq-watch",
|
|
"artifact": "tools",
|
|
"run": [
|
|
"./dnsmasq-tools",
|
|
"watch"
|
|
],
|
|
"health": {
|
|
"kind": "tool",
|
|
"tool": "dnsmasq_health",
|
|
"interval": "20s",
|
|
"timeout": "10s",
|
|
"looks": 2,
|
|
"grace": "60s"
|
|
}
|
|
}
|
|
],
|
|
"facts": {
|
|
"node-zones": {
|
|
"path": "/etc/mesh-resolver/nodes.conf",
|
|
"template": "# Generated by the mesh. Do not edit — this file is replaced whenever a machine\n# joins or leaves, and an edit would survive until then and vanish.\n\nlocal=/{{.Suffix}}/\n# A machine's own name is a host record as well as a wildcard: asked for an IPv6 address, the\n# resolver then says the name exists and has none, where the wildcard alone said there is no such\n# name — and a resolver that reads that as final (musl, so every Alpine container) failed to find\n# the machine at all (novox/hq issue 262).\n{{range .Machines}}address=/{{.FQDN}}/{{.Address}}\nhost-record={{.FQDN}},{{.Address}}\n{{end}}"
|
|
},
|
|
"zones": {
|
|
"path": "/etc/mesh-resolver/zones.conf",
|
|
"template": "# Generated by the mesh. Do not edit — this file is replaced whenever a module declares a zone or\n# its machine moves (novox/hq ADR 0199). One forwarding line per zone, to the module answering it.\n\n{{range .Zones}}server=/{{.Zone}}/{{.Address}}#{{.Port}}\n{{end}}"
|
|
}
|
|
},
|
|
"build": {
|
|
"artifacts": [
|
|
{
|
|
"name": "tools",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/dnsmasq-tools",
|
|
"binary": "dnsmasq-tools",
|
|
"loads": [
|
|
"dnsmasq-tools"
|
|
]
|
|
},
|
|
{
|
|
"name": "files",
|
|
"kind": "archive",
|
|
"from": "files"
|
|
}
|
|
]
|
|
}
|
|
}
|