From bd6ed80936d950a1e650af43125928fea74301f3 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 16 May 2025 17:30:47 +0200 Subject: [PATCH] policy/v2: error on missing or zero port (#2606) * policy/v2: error on missing or zero port Fixes #2605 Signed-off-by: Kristoffer Dalby * changelog: add entry Signed-off-by: Kristoffer Dalby --------- Signed-off-by: Kristoffer Dalby --- CHANGELOG.md | 5 ++++ hscontrol/policy/v2/types.go | 3 +++ hscontrol/policy/v2/types_test.go | 38 +++++++++++++++++++++++++++++++ hscontrol/policy/v2/utils.go | 4 ++++ 4 files changed, 50 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bca556d..e6645ec5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Next +### BREAKING + +- Policy: Zero or empty destination port is no longer allowed + [#2606](https://github.com/juanfont/headscale/pull/2606) + ## 0.26.0 (2025-05-14) ### BREAKING diff --git a/hscontrol/policy/v2/types.go b/hscontrol/policy/v2/types.go index a49f55de..d10136a0 100644 --- a/hscontrol/policy/v2/types.go +++ b/hscontrol/policy/v2/types.go @@ -3,6 +3,7 @@ package v2 import ( "bytes" "encoding/json" + "errors" "fmt" "net/netip" "strings" @@ -467,6 +468,8 @@ func (ve *AliasWithPorts) UnmarshalJSON(b []byte) error { return err } ve.Ports = ports + } else { + return errors.New(`hostport must contain a colon (":")`) } ve.Alias, err = parseAlias(vs) diff --git a/hscontrol/policy/v2/types_test.go b/hscontrol/policy/v2/types_test.go index 3808b547..e9fa6263 100644 --- a/hscontrol/policy/v2/types_test.go +++ b/hscontrol/policy/v2/types_test.go @@ -706,6 +706,44 @@ func TestUnmarshalPolicy(t *testing.T) { `, wantErr: `Tag "tag:notdefined" is not defined in the Policy, please define or remove the reference to it`, }, + { + name: "missing-dst-port-is-err", + input: ` + { + "acls": [ + { + "action": "accept", + "src": [ + "*" + ], + "dst": [ + "100.64.0.1" + ] + } + ] +} +`, + wantErr: `hostport must contain a colon (":")`, + }, + { + name: "dst-port-zero-is-err", + input: ` + { + "acls": [ + { + "action": "accept", + "src": [ + "*" + ], + "dst": [ + "100.64.0.1:0" + ] + } + ] +} +`, + wantErr: `first port must be >0, or use '*' for wildcard`, + }, } cmps := append(util.Comparers, cmp.Comparer(func(x, y Prefix) bool { diff --git a/hscontrol/policy/v2/utils.go b/hscontrol/policy/v2/utils.go index 9c962af8..2c551eda 100644 --- a/hscontrol/policy/v2/utils.go +++ b/hscontrol/policy/v2/utils.go @@ -73,6 +73,10 @@ func parsePortRange(portDef string) ([]tailcfg.PortRange, error) { return nil, err } + if port < 1 { + return nil, errors.New("first port must be >0, or use '*' for wildcard") + } + portRanges = append(portRanges, tailcfg.PortRange{First: port, Last: port}) } }