2024-11-26 15:16:06 +01:00
|
|
|
package policy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/netip"
|
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
policyv1 "github.com/juanfont/headscale/hscontrol/policy/v1"
|
|
|
|
policyv2 "github.com/juanfont/headscale/hscontrol/policy/v2"
|
2024-11-26 15:16:06 +01:00
|
|
|
"github.com/juanfont/headscale/hscontrol/types"
|
2025-03-10 16:20:29 +01:00
|
|
|
"tailscale.com/envknob"
|
2024-11-26 15:16:06 +01:00
|
|
|
"tailscale.com/tailcfg"
|
2025-03-10 16:20:29 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
polv2 = envknob.Bool("HEADSCALE_EXPERIMENTAL_POLICY_V2")
|
2024-11-26 15:16:06 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type PolicyManager interface {
|
|
|
|
Filter() []tailcfg.FilterRule
|
|
|
|
SSHPolicy(*types.Node) (*tailcfg.SSHPolicy, error)
|
|
|
|
SetPolicy([]byte) (bool, error)
|
|
|
|
SetUsers(users []types.User) (bool, error)
|
|
|
|
SetNodes(nodes types.Nodes) (bool, error)
|
2025-03-10 16:20:29 +01:00
|
|
|
// NodeCanHaveTag reports whether the given node can have the given tag.
|
|
|
|
NodeCanHaveTag(*types.Node, string) bool
|
2025-02-26 07:22:55 -08:00
|
|
|
|
|
|
|
// NodeCanApproveRoute reports whether the given node can approve the given route.
|
|
|
|
NodeCanApproveRoute(*types.Node, netip.Prefix) bool
|
2024-11-26 15:16:06 +01:00
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
Version() int
|
|
|
|
DebugString() string
|
2024-11-26 15:16:06 +01:00
|
|
|
}
|
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
// NewPolicyManager returns a new policy manager, the version is determined by
|
|
|
|
// the environment flag "HEADSCALE_EXPERIMENTAL_POLICY_V2".
|
|
|
|
func NewPolicyManager(pol []byte, users []types.User, nodes types.Nodes) (PolicyManager, error) {
|
|
|
|
var polMan PolicyManager
|
2024-11-26 15:16:06 +01:00
|
|
|
var err error
|
2025-03-10 16:20:29 +01:00
|
|
|
if polv2 {
|
|
|
|
polMan, err = policyv2.NewPolicyManager(pol, users, nodes)
|
2024-11-26 15:16:06 +01:00
|
|
|
if err != nil {
|
2025-03-10 16:20:29 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
polMan, err = policyv1.NewPolicyManager(pol, users, nodes)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2024-11-26 15:16:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
return polMan, err
|
2024-11-26 15:16:06 +01:00
|
|
|
}
|
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
// PolicyManagersForTest returns all available PostureManagers to be used
|
|
|
|
// in tests to validate them in tests that try to determine that they
|
|
|
|
// behave the same.
|
|
|
|
func PolicyManagersForTest(pol []byte, users []types.User, nodes types.Nodes) ([]PolicyManager, error) {
|
|
|
|
var polMans []PolicyManager
|
2024-11-26 15:16:06 +01:00
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
for _, pmf := range PolicyManagerFuncsForTest(pol) {
|
|
|
|
pm, err := pmf(users, nodes)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
polMans = append(polMans, pm)
|
2024-11-26 15:16:06 +01:00
|
|
|
}
|
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
return polMans, nil
|
2024-11-26 15:16:06 +01:00
|
|
|
}
|
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
func PolicyManagerFuncsForTest(pol []byte) []func([]types.User, types.Nodes) (PolicyManager, error) {
|
|
|
|
var polmanFuncs []func([]types.User, types.Nodes) (PolicyManager, error)
|
2025-02-26 07:22:55 -08:00
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
polmanFuncs = append(polmanFuncs, func(u []types.User, n types.Nodes) (PolicyManager, error) {
|
|
|
|
return policyv1.NewPolicyManager(pol, u, n)
|
|
|
|
})
|
|
|
|
polmanFuncs = append(polmanFuncs, func(u []types.User, n types.Nodes) (PolicyManager, error) {
|
|
|
|
return policyv2.NewPolicyManager(pol, u, n)
|
|
|
|
})
|
2025-02-26 07:22:55 -08:00
|
|
|
|
2025-03-10 16:20:29 +01:00
|
|
|
return polmanFuncs
|
2025-02-26 07:22:55 -08:00
|
|
|
}
|