Skip to content

Commit f7f3ff3

Browse files
committed
implement host query protection
1 parent 028adbf commit f7f3ff3

File tree

10 files changed

+1266
-93
lines changed

10 files changed

+1266
-93
lines changed

examples/config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ lighthouse:
7171
# for relaying to function.
7272
#incoming_handshake_filtering: false
7373

74+
# This setting on a lighthouse determines whether to enforce the host query protection
75+
# whitelist received from a node. On a node, this setting controls whether the node
76+
# sends its handshake filtering whitelist to the lighthouses at all, not reloadable.
77+
#enable_host_query_protection: false
78+
7479
# remote_allow_list allows you to control ip ranges that this node will
7580
# consider when handshaking to another node. By default, any remote IPs are
7681
# allowed. You can provide CIDRs here with `true` to allow and `false` to

firewall.go

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strconv"
1212
"strings"
1313
"sync"
14+
"sync/atomic"
1415
"time"
1516

1617
"github.com/gaissmai/bart"
@@ -89,6 +90,9 @@ type HandshakeFilter struct {
8990
AllowedCidrs []netip.Prefix
9091
AllowedCANames map[string]struct{}
9192
AllowedCAShas map[string]struct{}
93+
94+
IsEmtpy atomic.Bool
95+
IsModifiedSinceLastMashalling atomic.Bool
9296
}
9397

9498
// FirewallTable is the entry point for a rule, the evaluation order is:
@@ -1039,19 +1043,26 @@ func parsePort(s string) (startPort, endPort int32, err error) {
10391043
}
10401044

10411045
func NewHandshakeFilter() *HandshakeFilter {
1042-
return &HandshakeFilter{
1046+
hf := &HandshakeFilter{
10431047
AllowedHosts: make(map[string]struct{}),
10441048
AllowedGroups: make(map[string]struct{}),
10451049
AllowedGroupsCombos: make([]map[string]struct{}, 0),
10461050
AllowedCidrs: make([]netip.Prefix, 0),
10471051
AllowedCANames: make(map[string]struct{}),
10481052
AllowedCAShas: make(map[string]struct{}),
10491053
}
1054+
1055+
hf.IsModifiedSinceLastMashalling.Store(false)
1056+
hf.IsEmtpy.Store(true)
1057+
1058+
return hf
10501059
}
10511060

10521061
func (hfws *HandshakeFilter) AddRule(groups []string, host string, localIp netip.Prefix, CAName string, CASha string) {
1062+
ruleAdded := false
10531063
if host != "" {
10541064
hfws.AllowedHosts[host] = struct{}{}
1065+
ruleAdded = true
10551066
}
10561067

10571068
if len(groups) > 1 {
@@ -1066,23 +1077,34 @@ func (hfws *HandshakeFilter) AddRule(groups []string, host string, localIp netip
10661077
gs,
10671078
)
10681079
}
1080+
ruleAdded = true
10691081
} else if len(groups) == 1 {
10701082
hfws.AllowedGroups[groups[0]] = struct{}{}
1083+
ruleAdded = true
10711084
}
10721085

10731086
if localIp.IsValid() {
10741087
hfws.AllowedCidrs = append(
10751088
hfws.AllowedCidrs,
10761089
localIp,
10771090
)
1091+
ruleAdded = true
10781092
}
10791093

10801094
if CAName != "" {
10811095
hfws.AllowedCANames[CAName] = struct{}{}
1096+
ruleAdded = true
10821097
}
10831098

10841099
if CASha != "" {
10851100
hfws.AllowedCAShas[CASha] = struct{}{}
1101+
ruleAdded = true
1102+
}
1103+
1104+
hfws.IsModifiedSinceLastMashalling.Store(ruleAdded)
1105+
1106+
if ruleAdded {
1107+
hfws.IsEmtpy.Store(false)
10861108
}
10871109
}
10881110

@@ -1134,6 +1156,88 @@ func (hfws *HandshakeFilter) IsHandshakeAllowed(groups []string, host string, vp
11341156
return false
11351157
}
11361158

1159+
func (hfws *HandshakeFilter) MarshalToHfw() *HandshakeFilteringWhitelist {
1160+
hfw := &HandshakeFilteringWhitelist{
1161+
AllowedHosts: make([]string, len(hfws.AllowedHosts)),
1162+
AllowedGroups: make([]string, len(hfws.AllowedGroups)),
1163+
AllowedGroupsCombos: make([]*GroupsCombos, len(hfws.AllowedGroupsCombos)),
1164+
AllowedCidrs: make([]string, len(hfws.AllowedCidrs)),
1165+
AllowedCANames: make([]string, len(hfws.AllowedCANames)),
1166+
AllowedCAShas: make([]string, len(hfws.AllowedCAShas)),
1167+
SetEmpty: hfws.IsEmtpy.Load(),
1168+
}
1169+
1170+
for host := range hfws.AllowedHosts {
1171+
hfw.AllowedHosts = append(hfw.AllowedHosts, host)
1172+
}
1173+
1174+
for group := range hfws.AllowedGroups {
1175+
hfw.AllowedGroups = append(hfw.AllowedGroups, group)
1176+
}
1177+
1178+
for i, groupCombo := range hfws.AllowedGroupsCombos {
1179+
gc := &GroupsCombos{
1180+
Group: make([]string, len(groupCombo)),
1181+
}
1182+
j := 0
1183+
for group := range groupCombo {
1184+
gc.Group[j] = group
1185+
j += 1
1186+
}
1187+
hfw.AllowedGroupsCombos[i] = gc
1188+
}
1189+
1190+
for i, cidr := range hfws.AllowedCidrs {
1191+
hfw.AllowedCidrs[i] = cidr.String()
1192+
}
1193+
1194+
for ca := range hfws.AllowedCANames {
1195+
hfw.AllowedCANames = append(hfw.AllowedCANames, ca)
1196+
}
1197+
1198+
for fp := range hfws.AllowedCAShas {
1199+
hfw.AllowedCAShas = append(hfw.AllowedCAShas, fp)
1200+
}
1201+
1202+
hfws.IsModifiedSinceLastMashalling.Store(false)
1203+
1204+
return hfw
1205+
}
1206+
1207+
func (hfws *HandshakeFilter) UnmarshalFromHfw(hfw *HandshakeFilteringWhitelist) {
1208+
if hfw == nil {
1209+
return
1210+
}
1211+
1212+
for _, h := range hfw.AllowedHosts {
1213+
hfws.AddRule(nil, h, netip.Prefix{}, "", "")
1214+
}
1215+
1216+
for _, g := range hfw.AllowedGroups {
1217+
hfws.AddRule([]string{g}, "", netip.Prefix{}, "", "")
1218+
}
1219+
1220+
for _, gc := range hfw.AllowedGroupsCombos {
1221+
hfws.AddRule(gc.Group, "", netip.Prefix{}, "", "")
1222+
}
1223+
1224+
for _, cs := range hfw.AllowedCidrs {
1225+
c, err := netip.ParsePrefix(cs)
1226+
if err != nil {
1227+
continue
1228+
}
1229+
hfws.AddRule(nil, "", c, "", "")
1230+
}
1231+
1232+
for _, ca := range hfw.AllowedCANames {
1233+
hfws.AddRule(nil, "", netip.Prefix{}, ca, "")
1234+
}
1235+
1236+
for _, sha := range hfw.AllowedCAShas {
1237+
hfws.AddRule(nil, "", netip.Prefix{}, "", sha)
1238+
}
1239+
}
1240+
11371241
func isSubset(subset map[string]struct{}, superset []string) bool {
11381242
ls := len(subset)
11391243
s := make(map[string]struct{}, ls)

0 commit comments

Comments
 (0)