DNS over TLS and HTTPS set up in one step
jarl encrypted-dns setup (and the Encrypted DNS page) finds or obtains a certificate for the host name, checks that nothing else listens on the DoT and DoH ports at the chosen addresses (offering a free DoH port), and stages named's tls statement and listeners as one change, keeping port 53 where it was when there was no listen-on, plus the host name's records in the private views (local to the view in a linked zone). Status shows what to give Android, Linux, Firefox, Chrome and Windows clients. A tls statement with missing files is refused (tls_file_missing), and a certificate named uses can't be deleted. docs/encrypted-dns.md, e2e with real DoT and DoH queries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ebd3a3dfbe
commit
66dcf53684
21 files changed
+1790
-8
No files matched your search
@@ -172,6 +172,10 @@ func (s *Server) routes() {
|
||||
m.HandleFunc("DELETE "+p+"/certificates/{name}", s.authed(s.certDelete))
|
||||
m.HandleFunc("POST "+p+"/certificates/{name}/issue", s.authed(s.certIssue))
|
||||
m.HandleFunc("POST "+p+"/certificates/{name}/check", s.authed(s.certCheck))
|
||||
m.HandleFunc("GET "+p+"/encrypted-dns", s.authed(s.encryptedDNS))
|
||||
m.HandleFunc("POST "+p+"/encrypted-dns", s.authed(s.encryptedDNSSetup))
|
||||
m.HandleFunc("DELETE "+p+"/encrypted-dns", s.authed(s.encryptedDNSDisable))
|
||||
m.HandleFunc("POST "+p+"/encrypted-dns/check", s.authed(s.encryptedDNSCheck))
|
||||
m.HandleFunc("GET "+p+"/exposure", s.authed(s.exposure))
|
||||
m.HandleFunc("POST "+p+"/exposure/fix", s.authed(s.exposureFix))
|
||||
m.HandleFunc("POST "+p+"/exposure/ack", s.authed(s.exposureAck(true)))
|
||||
@@ -253,6 +257,11 @@ func changesetTarget(r *http.Request) (int64, error) {
|
||||
// mutate applies (or stages, or previews) requests and writes the
|
||||
// response. object, if set, returns the resulting object to include.
|
||||
func (s *Server) mutate(w http.ResponseWriter, r *http.Request, p *auth.Principal, description string, reqs []engine.Request, object func(st *model.State, created int64) any) error {
|
||||
return s.mutateNotes(w, r, p, description, reqs, object, nil)
|
||||
}
|
||||
|
||||
// mutateNotes is mutate with notes for the user, shown as warnings.
|
||||
func (s *Server) mutateNotes(w http.ResponseWriter, r *http.Request, p *auth.Principal, description string, reqs []engine.Request, object func(st *model.State, created int64) any, notes []string) error {
|
||||
csID, err := changesetTarget(r)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -263,7 +272,7 @@ func (s *Server) mutate(w http.ResponseWriter, r *http.Request, p *auth.Principa
|
||||
return err
|
||||
}
|
||||
res.Changeset.Ops = engine.RedactOps(res.Changeset.Ops)
|
||||
writeJSON(w, http.StatusAccepted, api.MutationResponse{Staged: true, ChangesetID: csID, Changeset: raw(res.Changeset), Added: engine.RedactOps(res.Added), Warnings: res.Warnings, Problems: raw(res.Problems)})
|
||||
writeJSON(w, http.StatusAccepted, api.MutationResponse{Staged: true, ChangesetID: csID, Changeset: raw(res.Changeset), Added: engine.RedactOps(res.Added), Warnings: append(notes, res.Warnings...), Problems: raw(res.Problems)})
|
||||
return nil
|
||||
}
|
||||
opts := engine.ApplyOptions{DryRun: queryBool(r, "dry_run"), Force: queryBool(r, "force"), AcceptRisk: queryBool(r, "accept_risk")}
|
||||
@@ -272,7 +281,7 @@ func (s *Server) mutate(w http.ResponseWriter, r *http.Request, p *auth.Principa
|
||||
s.writeErr(w, r, err, res)
|
||||
return nil
|
||||
}
|
||||
out := api.MutationResponse{Applied: res.Applied, DryRun: res.DryRun, ChangesetID: res.ChangesetID, Result: raw(res), Warnings: res.Warnings}
|
||||
out := api.MutationResponse{Applied: res.Applied, DryRun: res.DryRun, ChangesetID: res.ChangesetID, Result: raw(res), Warnings: append(notes, res.Warnings...)}
|
||||
if object != nil && res.Applied {
|
||||
st, err := s.store.LoadState(r.Context())
|
||||
if err == nil {
|
||||
|
||||
Reference in new issue
Block a user