149 lines
5.8 KiB
HTML
149 lines
5.8 KiB
HTML
{{define "content"}}
|
|
{{$s := .Data.Settings}}{{$st := .Data.Stats}}
|
|
|
|
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-4">
|
|
<div>
|
|
<h1 class="page-title">Resolver</h1>
|
|
<p class="text-body-secondary mb-0">
|
|
Recursive resolution is performed by forwarding to the upstream servers below.
|
|
</p>
|
|
</div>
|
|
<a href="/settings/resolver" class="btn btn-primary btn-sm">
|
|
<i class="bi bi-gear me-1"></i>Resolver settings
|
|
</a>
|
|
</div>
|
|
|
|
{{if not $s.DNS.Recursion}}
|
|
<div class="alert alert-secondary d-flex align-items-center gap-2">
|
|
<i class="bi bi-info-circle"></i>
|
|
<div>
|
|
Recursion is turned off. This server answers only for its own authoritative zones;
|
|
every other query is refused.
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<div class="row g-3 mb-4">
|
|
{{template "stat" dict "Label" "Forwarded queries" "Value" (num $st.Queries) "Icon" "bi-globe2"}}
|
|
{{template "stat" dict "Label" "Failures" "Value" (num $st.Failures) "Icon" "bi-exclamation-triangle" "Tone" "danger"}}
|
|
{{template "stat" dict "Label" "Average latency" "Value" (ms $st.AvgLatencyMS) "Icon" "bi-stopwatch"}}
|
|
{{template "stat" dict "Label" "Healthy upstreams" "Value" (printf "%d / %d" $st.Healthy $st.Upstreams) "Icon" "bi-heart-pulse" "Tone" "success"}}
|
|
</div>
|
|
|
|
<div class="row g-3">
|
|
<div class="col-12 col-xl-7">
|
|
<div class="card h-100">
|
|
<div class="card-header">Upstream servers</div>
|
|
{{if .Data.Upstreams}}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th>Server</th><th>Status</th>
|
|
<th class="text-end">Latency</th><th class="text-end">Queries</th>
|
|
<th class="text-end">Failures</th><th>Last used</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Data.Upstreams}}
|
|
<tr>
|
|
<td class="mono fw-semibold">{{.Address}}</td>
|
|
<td>
|
|
{{if .Healthy}}
|
|
<span class="badge text-bg-success">healthy</span>
|
|
{{else}}
|
|
<span class="badge text-bg-danger">resting</span>
|
|
{{end}}
|
|
{{if .LastError}}
|
|
<div class="small text-body-secondary truncate-cell" title="{{.LastError}}">{{truncate 60 .LastError}}</div>
|
|
{{end}}
|
|
</td>
|
|
<td class="text-end">{{ms .LatencyMS}}</td>
|
|
<td class="text-end">{{num .Queries}}</td>
|
|
<td class="text-end">{{num .Failures}}</td>
|
|
<td class="small text-body-secondary">
|
|
{{if .LastUsed}}{{timeAgo .LastUsed}}{{else}}never{{end}}
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="card-body pt-2">
|
|
<p class="form-text mb-0">
|
|
A server that fails three times in a row is rested for twenty seconds and moved
|
|
to the back of the selection order. The current strategy is
|
|
<span class="badge text-bg-light text-dark">{{$s.Resolver.Strategy}}</span>.
|
|
</p>
|
|
</div>
|
|
{{else}}
|
|
<div class="card-body">
|
|
{{template "empty" dict "Icon" "bi-globe2" "Title" "No upstream resolvers configured"
|
|
"Message" "Recursive resolution needs at least one upstream server. Add one in the resolver settings."}}
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 col-xl-5">
|
|
<div class="card mb-3">
|
|
<div class="card-header">Test an upstream</div>
|
|
<div class="card-body">
|
|
<form method="post" action="/resolver/test" class="row g-2">
|
|
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
|
<div class="col-12">
|
|
<label class="form-label" for="testAddress">Server</label>
|
|
<input type="text" class="form-control form-control-sm mono" id="testAddress" name="address"
|
|
placeholder="1.1.1.1:53" required
|
|
value="{{if .Data.Upstreams}}{{(index .Data.Upstreams 0).Address}}{{end}}">
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="testName">Name to resolve</label>
|
|
<input type="text" class="form-control form-control-sm mono" id="testName" name="name"
|
|
placeholder="example.com" value="example.com">
|
|
</div>
|
|
<div class="col-12 d-grid">
|
|
<button type="submit" class="btn btn-outline-primary btn-sm">
|
|
<i class="bi bi-broadcast me-1"></i>Send a test query
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">Recursion access control</div>
|
|
<div class="card-body">
|
|
<p class="form-text">
|
|
Recursion is refused for any client not listed here. This is what keeps the
|
|
server from becoming an open resolver.
|
|
</p>
|
|
<div class="mb-3">
|
|
<div class="fw-semibold small mb-1">Allowed networks</div>
|
|
{{if $s.Resolver.AllowNetworks}}
|
|
<div class="d-flex flex-wrap gap-1">
|
|
{{range $s.Resolver.AllowNetworks}}
|
|
<span class="badge text-bg-success-subtle border border-success-subtle text-success-emphasis mono">{{.}}</span>
|
|
{{end}}
|
|
</div>
|
|
{{else}}
|
|
<div class="text-danger small">None — recursion is denied to every client.</div>
|
|
{{end}}
|
|
</div>
|
|
{{if $s.Resolver.DenyNetworks}}
|
|
<div>
|
|
<div class="fw-semibold small mb-1">Denied networks</div>
|
|
<div class="d-flex flex-wrap gap-1">
|
|
{{range $s.Resolver.DenyNetworks}}
|
|
<span class="badge text-bg-danger-subtle border border-danger-subtle text-danger-emphasis mono">{{.}}</span>
|
|
{{end}}
|
|
</div>
|
|
<div class="form-text">Denies are evaluated before allows.</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|