Files
adamandClaude Opus 5.5 c27a6c10bd Mail reverse DNS check, what Jarl adds to named.conf, lists one per line
jarld checks the reverse DNS of the public zones' MX and SPF addresses as the internet sees it, every 6 hours (Exposure page, jarl exposure mail, jarl_mail_reverse_dns_ok). The Server options page, jarl option generated and GET /options/generated list what Jarl writes into named.conf by itself; stats.rate_limit_log turns off the query-errors logging. Option lists of three or more elements are shown one per line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:02:11 +01:00

75 lines
2.0 KiB
Go

package engine
import (
"context"
"crypto/rand"
"encoding/base64"
"errors"
"jarl/internal/model"
"jarl/internal/nscheck"
"jarl/internal/render"
"jarl/internal/store"
)
// viewKeySeedMeta is where the seed of the view keys is kept.
const viewKeySeedMeta = "view_key_seed"
// ViewKeySeed returns the seed the view keys' secrets are derived from
// (render/viewkeys.go), creating it the first time.
func ViewKeySeed(ctx context.Context, st *store.Store) ([]byte, error) {
v, err := st.GetMeta(ctx, viewKeySeedMeta)
if err == nil {
return base64.StdEncoding.DecodeString(v)
}
if !errors.Is(err, store.ErrNotFound) {
return nil, err
}
seed := make([]byte, 32)
if _, err := rand.Read(seed); err != nil {
return nil, err
}
if err := st.SetMeta(ctx, viewKeySeedMeta, base64.StdEncoding.EncodeToString(seed)); err != nil {
return nil, err
}
return seed, nil
}
// extras returns what jarld's configuration adds to the rendered
// configuration, with the view keys' seed.
func (e *Engine) extras(ctx context.Context) render.Extras {
x := e.cfg.Extras
e.seedMu.Lock()
defer e.seedMu.Unlock()
if e.seed == nil {
seed, err := ViewKeySeed(ctx, e.store)
if err != nil {
e.log.Warn("view keys: reading their seed failed", "err", err)
return x
}
e.seed = seed
}
x.ViewKeySeed = e.seed
return x
}
// ViewKey returns the TSIG key that selects a zone's view on this server
// (nil without views).
func (e *Engine) ViewKey(ctx context.Context, st *model.State, z *model.Zone) *nscheck.Key {
v := st.Views[z.ViewID]
if v == nil {
return nil
}
x := e.extras(ctx)
if len(x.ViewKeySeed) == 0 {
return nil
}
return &nscheck.Key{Name: render.ViewKeyName(v.Name), Algorithm: render.ViewKeyAlgorithm, Secret: render.ViewKeySecret(x.ViewKeySeed, v.ID)}
}
// GeneratedStatements lists what Jarl adds to named.conf by itself
// (render.GeneratedStatements).
func (e *Engine) GeneratedStatements(ctx context.Context, st *model.State) []render.Generated {
return render.GeneratedStatements(st, e.cfg.Paths, e.extras(ctx))
}