Initial commit
This commit is contained in:
commit
5a632a3b30
24 changed files with 2901 additions and 0 deletions
124
README.md
Normal file
124
README.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
# checker-dnssec
|
||||
|
||||
DNSSEC operational hygiene checker for [happyDomain](https://www.happydomain.org/).
|
||||
|
||||
Cryptographic chain validation is delegated to `checker-dnsviz`. This
|
||||
checker focuses on **policy and operational hygiene**:
|
||||
|
||||
- NSEC vs NSEC3 zone walking exposure
|
||||
- RFC 9276 NSEC3 parameter compliance (iterations, salt)
|
||||
- Algorithm policy and key sizes (allowed / forbidden / modern)
|
||||
- RRSIG presence, validity windows and freshness
|
||||
- TTL recommendations for DNSKEY / RRSIG
|
||||
- Per-name-server consistency of the DNSKEY RRset and denial scheme
|
||||
|
||||
The HTML report is laid out so the most common operator-facing failure
|
||||
scenarios appear first, with a fix line citing the relevant RFC.
|
||||
|
||||
## Usage
|
||||
|
||||
### Standalone HTTP server
|
||||
|
||||
```bash
|
||||
# Build and run
|
||||
make
|
||||
./checker-dnssec -listen :8080
|
||||
```
|
||||
|
||||
The server exposes:
|
||||
|
||||
- `GET /health`: health check
|
||||
- `POST /collect`: collect DNSSEC observations (happyDomain external checker protocol)
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
make docker
|
||||
docker run -p 8080:8080 happydomain/checker-dnssec
|
||||
```
|
||||
|
||||
### happyDomain plugin
|
||||
|
||||
```bash
|
||||
make plugin
|
||||
# produces checker-dnssec.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:
|
||||
|
||||
```bash
|
||||
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 DNSSEC checker to the URL of the
|
||||
running checker-dnssec server (e.g., `http://checker-dnssec:8080`).
|
||||
happyDomain will delegate observation collection to this endpoint.
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
make # standalone binary
|
||||
make docker # FROM scratch image
|
||||
make plugin # Go plugin (.so)
|
||||
make test # tests
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### Admin options
|
||||
|
||||
| Id | Type | Default | Description |
|
||||
|------------|--------|----------------------|--------------------------------------------------------------------------------------------------------------|
|
||||
| `resolver` | string | `/etc/resolv.conf` | Bootstrap recursive resolver (`host:port`) used to discover the apex name servers and look up the parent DS. |
|
||||
|
||||
### User options
|
||||
|
||||
| Id | Type | Default | Description |
|
||||
|---------------------------|--------|---------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `nsec3IterationsMax` | uint | `0` | RFC 9276 §3.1 ceiling on `NSEC3PARAM.Iterations`. Increase only if your signer cannot publish 0 yet. |
|
||||
| `nsec3IterationsSeverity` | choice | `warn` | Severity when iterations exceed the ceiling. Use `crit` to enforce RFC 9276 strictly. |
|
||||
| `signatureFreshness` | uint | `7` | Warn when the closest RRSIG expires in fewer than this many days. |
|
||||
| `signatureFreshnessCrit` | uint | `1` | Critical when the closest RRSIG expires in fewer than this many days. |
|
||||
| `minRSAKeySize` | uint | `2048` | Minimum acceptable RSA modulus size, in bits. |
|
||||
| `requireSEP` | bool | `true` | Require at least one DNSKEY with the SEP bit (KSK). |
|
||||
| `dnskeyTTLMin` | uint | `3600` | Minimum DNSKEY TTL, in seconds; shorter TTLs hurt cacheability. |
|
||||
|
||||
## Rules
|
||||
|
||||
Each rule emits a finding code. Severity may be affected by the options above.
|
||||
|
||||
| Code | Default severity | Condition |
|
||||
|------|-----------------|-----------|
|
||||
| `dnssec_zone_signed` | critical | Parent DS is published but the apex serves no DNSKEY (broken chain of trust). |
|
||||
| `dnssec_dnskey_consistent` | critical | Authoritative servers disagree on the apex DNSKEY RRset. |
|
||||
| `dnssec_dnskey_query_ok` | warning | At least one authoritative server failed to answer the DNSKEY query. |
|
||||
| `dnssec_algorithm_allowed` | critical (forbidden) / warning (not in allowlist) | A DNSKEY uses a forbidden algorithm or an algorithm not in `allowedAlgorithms`. |
|
||||
| `dnssec_algorithm_modern` | warning | The zone still uses RSA-family DNSKEYs; ECDSAP256SHA256 (13) or Ed25519 (15) recommended. |
|
||||
| `dnssec_rsa_keysize` | critical (<1024) / warning (<`minRSAKeySize`) | An RSA DNSKEY has a modulus below the policy threshold. |
|
||||
| `dnssec_ksk_present` | critical | No DNSKEY carries the SEP (KSK) flag while `requireSEP` is enabled. |
|
||||
| `dnssec_dnskey_count` | warning | Eight or more DNSKEYs are published, bloating responses and amplification factor. |
|
||||
| `dnssec_rrsig_present_dnskey` | critical | The apex DNSKEY RRset is unsigned. |
|
||||
| `dnssec_rrsig_present_soa` | critical | The apex SOA RRset is unsigned. |
|
||||
| `dnssec_rrsig_validity_window` | critical | An observed RRSIG is outside its `[Inception, Expiration]` window. |
|
||||
| `dnssec_rrsig_freshness` | warning / critical | The closest RRSIG expires in fewer than `signatureFreshness` / `signatureFreshnessCrit` days. |
|
||||
| `dnssec_denial_uses_nsec3` | warning | The zone uses NSEC for denial of existence, exposing it to trivial walking (RFC 5155 / RFC 7129). |
|
||||
| `dnssec_nsec3_iterations` | warning / critical (per `nsec3IterationsSeverity`) | `NSEC3PARAM.Iterations` exceeds `nsec3IterationsMax` (RFC 9276 §3.1). |
|
||||
| `dnssec_nsec3_salt_empty` | warning | `NSEC3PARAM.SaltLength` is non-zero (RFC 9276 §3.1: a salt buys no measurable protection). |
|
||||
| `dnssec_nsec3_optout_only_when_signed_delegations` | info | The OPT-OUT flag is set in a leaf zone, where it serves no purpose. |
|
||||
| `dnssec_denial_consistent` | critical | Authoritative servers disagree on the denial-of-existence scheme (NSEC vs NSEC3, or differing parameters). |
|
||||
| `dnssec_dnskey_ttl_min` | warning | The DNSKEY TTL is below `dnskeyTTLMin`, hurting cache efficiency. |
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the **MIT License** (see `LICENSE`).
|
||||
Loading…
Add table
Add a link
Reference in a new issue