aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tunnel/firewall/rules.go
diff options
context:
space:
mode:
Diffstat (limited to 'tunnel/firewall/rules.go')
-rw-r--r--tunnel/firewall/rules.go98
1 files changed, 78 insertions, 20 deletions
diff --git a/tunnel/firewall/rules.go b/tunnel/firewall/rules.go
index 41632f98..4788b0e2 100644
--- a/tunnel/firewall/rules.go
+++ b/tunnel/firewall/rules.go
@@ -581,6 +581,19 @@ func permitDHCPIPv6(session uintptr, baseObjects *baseObjects, weight uint8) err
return nil
}
+func setFilterConditions(filter *wtFwpmFilter0, conditions []wtFwpmFilterCondition0) {
+ if uint(len(conditions)) > uint(^uint32(0)) {
+ panic("number of filter conditions out of bounds")
+ }
+ if len(conditions) > 0 {
+ filter.numFilterConditions = uint32(len(conditions))
+ filter.filterCondition = (*wtFwpmFilterCondition0)(unsafe.Pointer(&conditions[0]))
+ return
+ }
+ filter.numFilterConditions = 0
+ filter.filterCondition = nil
+}
+
func permitNdp(session uintptr, baseObjects *baseObjects, weight uint8) error {
/* TODO: actually handle the hop limit somehow! The rules should vaguely be:
* - icmpv6 133: must be outgoing, dst must be FF02::2/128, hop limit must be 255
@@ -809,8 +822,7 @@ func permitNdp(session uintptr, baseObjects *baseObjects, weight uint8) error {
for _, definition := range defs {
filter.displayData = *definition.displayData
filter.layerKey = definition.layer
- filter.numFilterConditions = uint32(len(definition.conditions))
- filter.filterCondition = (*wtFwpmFilterCondition0)(unsafe.Pointer(&definition.conditions[0]))
+ setFilterConditions(&filter, definition.conditions)
err := fwpmFilterAdd0(session, &filter, 0, &filterID)
if err != nil {
@@ -895,8 +907,51 @@ func permitHyperV(session uintptr, baseObjects *baseObjects, weight uint8) error
return nil
}
-// Block all traffic except what is explicitly permitted by other rules.
-func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error {
+// Block all traffic on restritced routes except what is explicitly permitted by other rules.
+func blockRoutes(routes []netip.Prefix, session uintptr, baseObjects *baseObjects, weight uint8) error {
+ allOnesV4 := netip.AddrFrom4([4]byte{0xff, 0xff, 0xff, 0xff})
+ storedPointersV4 := make([]*wtFwpV4AddrAndMask, 0, len(routes))
+ denyConditionsV4 := make([]wtFwpmFilterCondition0, 0, len(routes))
+ for _, a := range routes {
+ if !a.Addr().Is4() {
+ continue
+ }
+ address := wtFwpV4AddrAndMask{
+ addr: binary.BigEndian.Uint32(a.Addr().AsSlice()),
+ mask: binary.BigEndian.Uint32(netip.PrefixFrom(allOnesV4, a.Bits()).Masked().Addr().AsSlice()),
+ }
+ denyConditionsV4 = append(denyConditionsV4, wtFwpmFilterCondition0{
+ fieldKey: cFWPM_CONDITION_IP_REMOTE_ADDRESS,
+ matchType: cFWP_MATCH_EQUAL,
+ conditionValue: wtFwpConditionValue0{
+ _type: cFWP_V4_ADDR_MASK,
+ value: uintptr(unsafe.Pointer(&address)),
+ },
+ })
+ storedPointersV4 = append(storedPointersV4, &address)
+ }
+
+ storedPointersV6 := make([]*wtFwpV6AddrAndMask, 0, len(routes))
+ denyConditionsV6 := make([]wtFwpmFilterCondition0, 0, len(routes))
+ for _, a := range routes {
+ if !a.Addr().Is6() {
+ continue
+ }
+ address := wtFwpV6AddrAndMask{
+ addr: a.Addr().As16(),
+ prefixLength: uint8(a.Bits()),
+ }
+ denyConditionsV6 = append(denyConditionsV6, wtFwpmFilterCondition0{
+ fieldKey: cFWPM_CONDITION_IP_REMOTE_ADDRESS,
+ matchType: cFWP_MATCH_EQUAL,
+ conditionValue: wtFwpConditionValue0{
+ _type: cFWP_V6_ADDR_MASK,
+ value: uintptr(unsafe.Pointer(&address)),
+ },
+ })
+ storedPointersV6 = append(storedPointersV6, &address)
+ }
+
filter := wtFwpmFilter0{
providerKey: &baseObjects.provider,
subLayerKey: baseObjects.filters,
@@ -907,12 +962,13 @@ func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error {
}
filterID := uint64(0)
+ setFilterConditions(&filter, denyConditionsV4)
//
// #1 Block outbound traffic on IPv4.
//
{
- displayData, err := createWtFwpmDisplayData0("Block all outbound (IPv4)", "")
+ displayData, err := createWtFwpmDisplayData0("Block restricted routes outbound (IPv4)", "")
if err != nil {
return wrapErr(err)
}
@@ -930,7 +986,7 @@ func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error {
// #2 Block inbound traffic on IPv4.
//
{
- displayData, err := createWtFwpmDisplayData0("Block all inbound (IPv4)", "")
+ displayData, err := createWtFwpmDisplayData0("Block restricted routes inbound (IPv4)", "")
if err != nil {
return wrapErr(err)
}
@@ -944,11 +1000,13 @@ func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error {
}
}
+ setFilterConditions(&filter, denyConditionsV6)
+
//
// #3 Block outbound traffic on IPv6.
//
{
- displayData, err := createWtFwpmDisplayData0("Block all outbound (IPv6)", "")
+ displayData, err := createWtFwpmDisplayData0("Block restricted routes outbound (IPv6)", "")
if err != nil {
return wrapErr(err)
}
@@ -966,7 +1024,7 @@ func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error {
// #4 Block inbound traffic on IPv6.
//
{
- displayData, err := createWtFwpmDisplayData0("Block all inbound (IPv6)", "")
+ displayData, err := createWtFwpmDisplayData0("Block restricted routes inbound (IPv6)", "")
if err != nil {
return wrapErr(err)
}
@@ -980,6 +1038,9 @@ func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error {
}
}
+ runtime.KeepAlive(storedPointersV4)
+ runtime.KeepAlive(storedPointersV6)
+
return nil
}
@@ -1018,15 +1079,14 @@ func blockDNS(except []netip.Addr, session uintptr, baseObjects *baseObjects, we
}
filter := wtFwpmFilter0{
- providerKey: &baseObjects.provider,
- subLayerKey: baseObjects.filters,
- weight: filterWeight(weightDeny),
- numFilterConditions: uint32(len(denyConditions)),
- filterCondition: (*wtFwpmFilterCondition0)(unsafe.Pointer(&denyConditions[0])),
+ providerKey: &baseObjects.provider,
+ subLayerKey: baseObjects.filters,
+ weight: filterWeight(weightDeny),
action: wtFwpmAction0{
_type: cFWP_ACTION_BLOCK,
},
}
+ setFilterConditions(&filter, denyConditions)
filterID := uint64(0)
@@ -1138,15 +1198,14 @@ func blockDNS(except []netip.Addr, session uintptr, baseObjects *baseObjects, we
}
filter = wtFwpmFilter0{
- providerKey: &baseObjects.provider,
- subLayerKey: baseObjects.filters,
- weight: filterWeight(weightAllow),
- numFilterConditions: uint32(len(allowConditionsV4)),
- filterCondition: (*wtFwpmFilterCondition0)(unsafe.Pointer(&allowConditionsV4[0])),
+ providerKey: &baseObjects.provider,
+ subLayerKey: baseObjects.filters,
+ weight: filterWeight(weightAllow),
action: wtFwpmAction0{
_type: cFWP_ACTION_PERMIT,
},
}
+ setFilterConditions(&filter, allowConditionsV4)
filterID = uint64(0)
@@ -1186,8 +1245,7 @@ func blockDNS(except []netip.Addr, session uintptr, baseObjects *baseObjects, we
}
}
- filter.filterCondition = (*wtFwpmFilterCondition0)(unsafe.Pointer(&allowConditionsV6[0]))
- filter.numFilterConditions = uint32(len(allowConditionsV6))
+ setFilterConditions(&filter, allowConditionsV6)
//
// #7 Allow IPv6 outbound DNS.