mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-26 08:53:05 +00:00
fix loading policy manager
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
8d5b04f3d3
commit
50b62ddfb3
2 changed files with 65 additions and 61 deletions
|
@ -88,6 +88,7 @@ type Headscale struct {
|
|||
DERPMap *tailcfg.DERPMap
|
||||
DERPServer *derpServer.DERPServer
|
||||
|
||||
polManOnce sync.Once
|
||||
polMan policy.PolicyManager
|
||||
|
||||
mapper *mapper.Mapper
|
||||
|
@ -531,8 +532,7 @@ func (h *Headscale) Serve() error {
|
|||
}
|
||||
|
||||
var err error
|
||||
|
||||
if err = h.loadACLPolicy(); err != nil {
|
||||
if err = h.loadPolicyManager(); err != nil {
|
||||
return fmt.Errorf("failed to load ACL policy: %w", err)
|
||||
}
|
||||
|
||||
|
@ -814,7 +814,7 @@ func (h *Headscale) Serve() error {
|
|||
|
||||
// TODO(kradalby): Reload config on SIGHUP
|
||||
// TODO(kradalby): Only update if we set a new policy
|
||||
if err := h.loadACLPolicy(); err != nil {
|
||||
if err := h.loadPolicyManager(); err != nil {
|
||||
log.Error().Err(err).Msg("failed to reload ACL policy")
|
||||
}
|
||||
|
||||
|
@ -1037,22 +1037,9 @@ func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
|
|||
return &machineKey, nil
|
||||
}
|
||||
|
||||
func (h *Headscale) loadACLPolicy() error {
|
||||
var (
|
||||
pm policy.PolicyManager
|
||||
)
|
||||
|
||||
switch h.cfg.Policy.Mode {
|
||||
case types.PolicyModeFile:
|
||||
path := h.cfg.Policy.Path
|
||||
|
||||
// It is fine to start headscale without a policy file.
|
||||
if len(path) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
absPath := util.AbsolutePathFromConfigPath(path)
|
||||
|
||||
func (h *Headscale) loadPolicyManager() error {
|
||||
var errOut error
|
||||
h.polManOnce.Do(func() {
|
||||
// Validate and reject configuration that would error when applied
|
||||
// when creating a map response. This requires nodes, so there is still
|
||||
// a scenario where they might be allowed if the server has no nodes
|
||||
|
@ -1063,22 +1050,42 @@ func (h *Headscale) loadACLPolicy() error {
|
|||
// allowed to be written to the database.
|
||||
nodes, err := h.db.ListNodes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading nodes from database to validate policy: %w", err)
|
||||
errOut = fmt.Errorf("loading nodes from database to validate policy: %w", err)
|
||||
return
|
||||
}
|
||||
users, err := h.db.ListUsers()
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading users from database to validate policy: %w", err)
|
||||
errOut = fmt.Errorf("loading users from database to validate policy: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
pm, err = policy.NewPolicyManagerFromPath(absPath, users, nodes)
|
||||
switch h.cfg.Policy.Mode {
|
||||
case types.PolicyModeFile:
|
||||
path := h.cfg.Policy.Path
|
||||
|
||||
// It is fine to start headscale without a policy file.
|
||||
if len(path) == 0 {
|
||||
h.polMan, err = policy.NewPolicyManager(nil, users, nodes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading policy from file: %w", err)
|
||||
errOut = fmt.Errorf("policy manager with no policy: %w", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
absPath := util.AbsolutePathFromConfigPath(path)
|
||||
|
||||
h.polMan, err = policy.NewPolicyManagerFromPath(absPath, users, nodes)
|
||||
if err != nil {
|
||||
errOut = fmt.Errorf("loading policy from file (%s): %w", absPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(nodes) > 0 {
|
||||
_, err = pm.SSHPolicy(nodes[0])
|
||||
_, err = h.polMan.SSHPolicy(nodes[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("verifying SSH rules: %w", err)
|
||||
errOut = fmt.Errorf("verifying SSH rules: %w", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1086,31 +1093,24 @@ func (h *Headscale) loadACLPolicy() error {
|
|||
p, err := h.db.GetPolicy()
|
||||
if err != nil {
|
||||
if errors.Is(err, types.ErrPolicyNotFound) {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to get policy from database: %w", err)
|
||||
errOut = fmt.Errorf("failed to get policy from database: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
nodes, err := h.db.ListNodes()
|
||||
h.polMan, err = policy.NewPolicyManager([]byte(p.Data), users, nodes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading nodes from database to validate policy: %w", err)
|
||||
}
|
||||
users, err := h.db.ListUsers()
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading users from database to validate policy: %w", err)
|
||||
}
|
||||
pm, err = policy.NewPolicyManager([]byte(p.Data), users, nodes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading policy from database: %w", err)
|
||||
errOut = fmt.Errorf("loading policy from database: %w", err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
log.Fatal().
|
||||
Str("mode", string(h.cfg.Policy.Mode)).
|
||||
Msg("Unknown ACL policy mode")
|
||||
}
|
||||
})
|
||||
|
||||
h.polMan = pm
|
||||
|
||||
return nil
|
||||
return errOut
|
||||
}
|
||||
|
|
|
@ -40,10 +40,14 @@ func NewPolicyManagerFromPath(path string, users []types.User, nodes types.Nodes
|
|||
}
|
||||
|
||||
func NewPolicyManager(polB []byte, users []types.User, nodes types.Nodes) (PolicyManager, error) {
|
||||
pol, err := LoadACLPolicyFromBytes(polB)
|
||||
var pol *ACLPolicy
|
||||
var err error
|
||||
if polB != nil && len(polB) > 0 {
|
||||
pol, err = LoadACLPolicyFromBytes(polB)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing policy: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
pm := PolicyManagerV1{
|
||||
pol: pol,
|
||||
|
|
Loading…
Reference in a new issue