Sets from Jarl: sets holding the addresses of names in Jarl
A set can take its addresses from Jarl: every A and AAAA record of its
names (NAME@VIEW), CNAMEs followed within Jarl's zones in the same view.
housecarld reads them every jarl.refresh and after each change, keeps
only the addresses within the zones and networks the set allows, and
keeps what it last read (saved in the database and the boot ruleset)
while Jarl can't be reached. A change of the addresses applies the
ruleset again without a history entry and is audited (set.jarl).
hc set add --jarl --within, hc set jarl; the kind "from Jarl" and
Addresses… on the Sets page; GET /sets/{name}/jarl and /jarl/refresh;
validation codes set_jarl_*, status warnings jarl_*; docs/jarl.md.
e2e phase with scripts/fakejarl.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
50dce02746
commit
68ba2d06c5
37 files changed
+2315
-59
No files matched your search
@@ -1,6 +1,9 @@
|
||||
package model
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Chains rules are placed in.
|
||||
const (
|
||||
@@ -71,11 +74,49 @@ type AddressSet struct {
|
||||
Dynamic bool `json:"dynamic,omitempty"`
|
||||
// Timeout is a dynamic set's default entry lifetime in seconds (0:
|
||||
// entries stay until removed).
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
// Jarl makes the set's entries the addresses of names in Jarl, which
|
||||
// housecarld reads and keeps up to date (docs/jarl.md).
|
||||
Jarl *JarlSource `json:"jarl,omitempty"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
func (s *AddressSet) GetID() int64 { return s.ID }
|
||||
func (s *AddressSet) GetID() int64 { return s.ID }
|
||||
|
||||
// Runtime reports whether the set's entries come at run time (a dynamic
|
||||
// set's, a Jarl set's) rather than from the configuration.
|
||||
func (s *AddressSet) Runtime() bool { return s.Dynamic || s.Jarl != nil }
|
||||
|
||||
// JarlSource is where a set's addresses come from in Jarl: the A and AAAA
|
||||
// records of names (CNAMEs followed), each in a view, kept only where
|
||||
// Within allows.
|
||||
type JarlSource struct {
|
||||
Names []JarlName `json:"names"`
|
||||
// Within are zone names and addresses (prefixes, ranges): an address
|
||||
// is used only if it lies in a zone's connected networks or in one of
|
||||
// the addresses.
|
||||
Within []string `json:"within"`
|
||||
}
|
||||
|
||||
// JarlName is a name in Jarl, in a view ("": the only view that has it).
|
||||
type JarlName struct {
|
||||
Name string `json:"name"` // "nas.example.com", without the final dot
|
||||
View string `json:"view,omitempty"`
|
||||
}
|
||||
|
||||
// String is "name" or "name@view".
|
||||
func (n JarlName) String() string {
|
||||
if n.View == "" {
|
||||
return n.Name
|
||||
}
|
||||
return n.Name + "@" + n.View
|
||||
}
|
||||
|
||||
// ParseJarlName reads "name" or "name@view".
|
||||
func ParseJarlName(s string) JarlName {
|
||||
name, view, _ := strings.Cut(strings.TrimSpace(s), "@")
|
||||
return JarlName{Name: strings.TrimSuffix(strings.ToLower(strings.TrimSpace(name)), "."), View: strings.TrimSpace(view)}
|
||||
}
|
||||
func (s *AddressSet) Label() string { return s.Name }
|
||||
|
||||
// Service is a named list of ports ("tcp/22", "udp/60000-61000") and ICMP
|
||||
|
||||
Reference in new issue
Block a user