type Action uint32
const (
// ActionBlock blocks a packet or session.
ActionBlock Action = 0x1001
// ActionPermit permits a packet or session.
ActionPermit Action = 0x1002
// ActionCalloutTerminating invokes a callout that must return a
// permit or block verdict.
ActionCalloutTerminating Action = 0x5003
// ActionCalloutInspection invokes a callout that is expected to
// not return a verdict (i.e. a read-only callout).
ActionCalloutInspection Action = 0x6004
// ActionCalloutUnknown invokes a callout that may return a permit
// or block verdict.
ActionCalloutUnknown Action = 0x4005
)
这里定义了一些 过滤引擎 可以执行的动作。
type CalloutID windows.GUID
func (id CalloutID) String() string {
if s := guidNames[windows.GUID(id)]; s != "" {
return s
}
return windows.GUID(id).String()
}
// IsZero reports whether id is nil or the zero GUID.
func (id *CalloutID) IsZero() bool {
return id == nil || *id == CalloutID{}
}
用于标识 WFP 调用函数(Callout)
// ConditionFlag represents special conditions that can be tested.
type ConditionFlag uint32 // do not change type, used in C calls
const (
ConditionFlagIsLoopback ConditionFlag = 0x00000001
ConditionFlagIsIPSecSecured ConditionFlag = 0x00000002
ConditionFlagIsReauthorize ConditionFlag = 0x00000004
ConditionFlagIsWildcardBind ConditionFlag = 0x00000008
ConditionFlagIsRawEndpoint ConditionFlag = 0x00000010
ConditionFlagIsFragmant ConditionFlag = 0x00000020
ConditionFlagIsFragmantGroup ConditionFlag = 0x00000040
ConditionFlagIsIPSecNATTReclassify ConditionFlag = 0x00000080
ConditionFlagIsRequiresALEClassify ConditionFlag = 0x00000100
ConditionFlagIsImplicitBind ConditionFlag = 0x00000200
ConditionFlagIsReassembled ConditionFlag = 0x00000400
ConditionFlagIsNameAppSpecified ConditionFlag = 0x00004000
ConditionFlagIsPromiscuous ConditionFlag = 0x00008000
ConditionFlagIsAuthFW ConditionFlag = 0x00010000
ConditionFlagIsReclassify ConditionFlag = 0x00020000
ConditionFlagIsOutboundPassThru ConditionFlag = 0x00040000
ConditionFlagIsInboundPassThru ConditionFlag = 0x00080000
ConditionFlagIsConnectionRedirected ConditionFlag = 0x00100000
)
是一个代表特定条件的标志位常量。
这些标志位常量在检测网络数据包时用于指示数据包是否满足特定条件,例如是否为回送数据包、是否经过IPSec安全性保护、是否需要进行ALE分类等。这些标志位常量具体的含义可以在该包的文档中查看。
type DropEvent struct {
Timestamp time.Time
IPProtocol uint8
LocalAddr netip.AddrPort
RemoteAddr netip.AddrPort
AppID string
LayerID uint16
FilterID uint64
}
DropEvent 是一个结构体类型,用于表示一个网络包被丢弃的事件。
包当 WF 处理网络数据包时,如果遇到了某些条件(例如与某些规则不符合),会将该数据包丢弃并生成一个 DropEvent 事件。这个事件会记录该数据包的相关信息,例如时间戳、协议类型、源地址、目标地址等,以便后续的分析和处理。
DropEvent 事件是 WF 包中的一个重要的概念,用于在网络安全监控和管理中追踪和记录丢弃的数据包。在 WF 中,管理员可以根据 DropEvent 事件来了解网络中的问题,例如网络流量异常、攻击事件等,从而采取相应的措施来保护网络的安全性。
type Field struct {
// ID is the unique identifier for the field.
ID FieldID
// Type is the type of the field.
Type reflect.Type
}
在wf包中,Field类代表了一个网络数据包中的字段,它用于定义一个数据包中的某个具体字段的ID和类型。Field
类中的ID属性是字段的唯一标识符,可以用于识别和引用该字段。而Type属性则表示该字段的类型,通常是一种基本类型(如整数、浮点数、布尔值等)或结构体类型。
可以被应用于Filter
类中的规则匹配过程,以过滤网络流量并进行相应的处理。
例如:表示UDP数据包的头部的端口字段。
// IPProto represents the protocol being used.
type IPProto uint8 // do not change type, used in C calls
// From: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
const (
IPProtoICMP IPProto = 1
IPProtoICMPV6 IPProto = 58
IPProtoTCP IPProto = 6
IPProtoUDP IPProto = 17
)
IPProto
类型用于表示网络数据包的协议类型。
在 Windows Filtering Platform 中,当需要根据协议类型对网络数据包进行过滤或者匹配时,就会使用 IPProto
类型及其常量。
// Layer is a point in the packet processing path where filter rules
// can be applied.
type Layer struct {
// ID is the unique identifier for this layer.
ID LayerID
// KernelID is the internal kernel ID for this layer.
KernelID uint16
// Name is a short descriptive name.
Name string
// Description is a longer description of the layer's function.
Description string
// DefaultSublayer is the ID for the default sublayer into which
// filter rules are added.
DefaultSublayer SublayerID
// Fields describes the fields that are available in this layer to
// be matched against.
Fields []*Field
}
Layer
类型表示网络包处理路径中的一个阶段,它可以用来添加和管理过滤规则。
- 提供一组可用于过滤规则匹配的字段。
Layer
类型的Fields
字段描述了这些字段。 - 管理默认子层级。
Layer
类型的DefaultSublayer
字段表示默认的子层级 ID。 - 提供一些元数据。
Layer
类型的ID
、Name
和Description
字段提供了该阶段的元数据信息,方便开发人员对其进行识别和管理。
总之,Layer
类型在 wf 包中起到了关键的作用,是开发人员用来添加和管理过滤规则的重要工具之一。
// Match is a matching test that gets run against a layer's field.
type Match struct {
Field FieldID
Op MatchType
Value interface{}
}
func (m Match) String() string {
return fmt.Sprintf("%s %s %v (%T)", m.Field, m.Op, m.Value, m.Value)
}
Match
类用于描述一个过滤规则的匹配条件,包括匹配的字段(FieldID
)、匹配类型(MatchType
)和匹配的值(Value
)。
在过滤器中,可以通过Match
实例定义一条匹配规则,用于匹配数据包中的字段是否满足规则要求。比如,可以通过Match
类创建一个匹配规则,要求数据包的目标端口等于80,从而过滤出目标端口为80的数据包。
// MatchType is the operator to use when testing a field in a Match.
type MatchType uint32 // do not change type, used in C calls
const (
MatchTypeEqual MatchType = iota
MatchTypeGreater
MatchTypeLess
MatchTypeGreaterOrEqual
MatchTypeLessOrEqual
MatchTypeRange // true if the field value is within the Range.
MatchTypeFlagsAllSet
MatchTypeFlagsAnySet
MatchTypeFlagsNoneSet
MatchTypeEqualCaseInsensitive // only valid on strings, no string fields exist
MatchTypeNotEqual
MatchTypePrefix // TODO: not well documented. Is this prefix.Contains(ip) ?
MatchTypeNotPrefix // TODO: see above.
)
var mtStr = map[MatchType]string{
MatchTypeEqual: "==",
MatchTypeGreater: ">",
MatchTypeLess: "<",
MatchTypeGreaterOrEqual: ">=",
MatchTypeLessOrEqual: "<=",
MatchTypeRange: "in",
MatchTypeFlagsAllSet: "F[all]",
MatchTypeFlagsAnySet: "F[any]",
MatchTypeFlagsNoneSet: "F[none]",
MatchTypeEqualCaseInsensitive: "i==",
MatchTypeNotEqual: "!=",
MatchTypePrefix: "pfx",
MatchTypeNotPrefix: "!pfx",
}
func (m MatchType) String() string {
return mtStr[m]
}
MatchType
是 wf
包中用来表示匹配操作符的枚举类型,其中包含了常见的匹配操作符,如等于、大于、小于等,还包括用于匹配二进制位的操作符,以及匹配字符串的操作符等。它被用在 Match 类型中,用于描述如何对数据包中的字段进行匹配。同时,MatchType
类型还实现了 String()
方法,可以将枚举值转化为相应的字符串表示。
// Options configures a Session.
type Options struct {
// Name is a short name for the session, shown in Windows
// administrative tools.
Name string
// Description is a short description for the session, shown in
// Windows administrative tools.
Description string
// Dynamic, if true, indicates that all objects created during the
// session should be removed when the session is closed or the
// current process terminates. Dynamic sessions are meant for
// adding firewall configuration that should not outlast your
// program's execution.
Dynamic bool
// TransactionStartTimeout is how long the session is willing to
// wait to acquire the global transaction lock. If zero, WFP's
// default timeout (15 seconds) is used.
TransactionStartTimeout time.Duration
}
// New connects to the WFP API.
func New(opts *Options) (*Session, error) {
if opts == nil {
opts = &Options{}
}
var a arena
defer a.Dispose()
s0 := toSession0(&a, opts)
var handle windows.Handle
err := fwpmEngineOpen0(nil, authnServiceWinNT, nil, s0, &handle)
if err != nil {
return nil, err
}
ret := &Session{
handle: handle,
layerTypes: layerTypes{},
}
// Populate the layer type cache.
layers, err := ret.Layers()
if err != nil {
ret.Close()
return nil, err
}
for _, layer := range layers {
fields := fieldTypes{}
for _, field := range layer.Fields {
fields[field.ID] = field.Type
}
ret.layerTypes[layer.ID] = fields
}
return ret, nil
}
用于配置一个Session
。Session
是与Windows策略防火墙(WFP)交互的主要对象。Options
类包括以下选项:
Name
:会话的短名称,在Windows管理工具中显示。Description
:会话的短描述,在Windows管理工具中显示。Dynamic
:如果为 true,则表示在会话关闭或当前进程终止时应删除在会话期间创建的所有对象。动态会话适用于添加不应超过程序执行期间的防火墙配置。TransactionStartTimeout
:表示会话愿意等待获取全局事务锁的时间。如果为零,则使用WFP的默认超时(15秒)。
// A Provider is an entity that owns sublayers and filtering rules.
type Provider struct {
// ID is the unique identifier for this provider.
ID ProviderID
// Name is a short descriptive name.
Name string
// Description is a longer description of the provider.
Description string
// Persistent indicates whether the provider is preserved across
// restarts of the filtering engine.
Persistent bool
// Data is optional opaque data that can be held on behalf of the
// Provider.
Data []byte
// ServiceName is an optional Windows service name. If present,
// the rules owned by this Provider are only activated when the
// service is active.
ServiceName string
// Disabled indicates whether the rules owned by this Provider are
// disabled due to its associated service being
// disabled. Read-only, ignored on Provider creation.
Disabled bool
}
Provider
类是一个拥有子层和过滤规则的实体。它用于表示 Windows Filtering Platform (WFP) 中的提供程序(provider),提供程序是一组可用于构建网络策略的 WFP 组件。Provider
类包含提供程序的唯一标识符、名称、描述、持久性等信息,同时还可以包含与提供程序相关的数据和服务名称。该类还提供了一个Disabled
属性,表示由于关联的服务被禁用而禁用该Provider
拥有的规则,该属性只读,不影响Provider
创建。
type Range struct {
From, To interface{}
}
表示一个区间。它由两个字段组成,From
和To
,分别表示区间的起始和结束。这两个字段的数据类型可以是任意类型,只要它们可以比较大小。Range
类通常用于表示匹配规则中的某个值必须在指定的区间范围内才能被匹配成功。在wf包中,Range
类被用于Match
类中的MatchTypeRange
操作符。
// A Rule is an action to take on packets that match a set of
// conditions.
type Rule struct {
// ID is the unique identifier for this rule.
ID RuleID
// KernelID is the kernel ID for this rule.
KernelID uint64
// Name is a short descriptive name.
Name string
// Description is a longer description of the rule.
Description string
// Layer is the ID of the layer in which the rule runs.
Layer LayerID
// Sublayer is the ID of the sublayer in which the rule runs.
Sublayer SublayerID
// Weight is the priority of the rule relative to other rules in
// its sublayer.
Weight uint64
// Conditions are the tests which must pass for this rule to apply
// to a packet.
Conditions []*Match
// Action is the action to take on matching packets.
Action Action
// Callout is the ID of the callout to invoke. Only valid if
// Action is ActionCalloutTerminating, ActionCalloutInspection, or
// ActionCalloutUnknown.
Callout CalloutID
// PermitIfMissing, if set, indicates that a callout action to a
// callout ID that isn't registered should be translated into an
// ActionPermit, rather than an ActionBlock. Only relevant if
// Action is ActionCalloutTerminating or ActionCalloutUnknown.
PermitIfMissing bool
// HardAction, if set, indicates that the action type is hard and cannot
// be overridden except by a Veto.
HardAction bool
// Persistent indicates whether the rule is preserved across
// restarts of the filtering engine.
Persistent bool
// BootTime indicates that this rule applies only during early
// boot, before the filtering engine fully starts and hands off to
// the normal runtime rules.
BootTime bool
// Provider optionally identifies the Provider that manages this
// rule.
Provider ProviderID
// ProviderData is optional opaque data that can be held on behalf
// of the Provider.
ProviderData []byte
// Disabled indicates whether the rule is currently disabled due
// to its provider being associated with an inactive Windows
// service. See Provider.ServiceName for details.
Disabled bool
}
Rule
是 Windows Filtering Platform(WFP)中使用的一种过滤规则类型。过滤规则指定要对匹配一组条件的数据包执行的操作。 Rule
对象包含 ID、名称、描述、层、子层、权重、条件和规则动作等信息。条件是必须满足的测试,才能将规则应用于数据包,规则动作指定匹配规则条件的数据包的操作。 Provider
字段可选择地标识管理此规则的提供程序,ProviderData
字段是可选的不透明数据,可以代表提供程序保存。 Disabled
字段指示规则是否因其提供程序关联的未激活 Windows 服务而当前被禁用。 Persistent
字段指示规则是否在过滤引擎重新启动时保留。 BootTime
字段表示此规则仅在引导过程中适用,即在过滤引擎完全启动并移交给正常运行时规则之前。
type Session struct {
// contains filtered or unexported fields
}
func (s *Session) AddProvider(p *Provider) error {
if p.ID.IsZero() {
return errors.New("Provider.ID cannot be zero")
}
var a arena
defer a.Dispose()
p0 := toProvider0(&a, p)
return fwpmProviderAdd0(s.handle, p0, nil)
}
func (s *Session) AddRule(r *Rule) error {
if r.ID.IsZero() {
return errors.New("Provider.ID cannot be zero")
}
var a arena
defer a.Dispose()
f, err := toFilter0(&a, r, s.layerTypes)
if err != nil {
return err
}
if err := fwpmFilterAdd0(s.handle, f, nil, &f.FilterID); err != nil {
return err
}
return nil
}
func (s *Session) AddSublayer(sl *Sublayer) error {
// the WFP API accepts zero GUIDs and interprets it as "give me a
// random GUID". However, we can't get that GUID back out, so it
// would be pointless to make such a request. Stop it here.
if sl.ID.IsZero() {
return errors.New("Sublayer.ID cannot be zero")
}
var a arena
defer a.Dispose()
sl0 := toSublayer0(&a, sl)
return fwpmSubLayerAdd0(s.handle, sl0, nil) // TODO: security descriptor
}
// Close implements io.Closer.
func (s *Session) Close() error {
if s.handle == 0 {
return nil
}
err := fwpmEngineClose0(s.handle)
s.handle = 0
return err
}
// DeleteProvider deletes the Provider whose GUID is id. A provider
// can only be deleted once all the resources it owns have been
// deleted.
func (s *Session) DeleteProvider(id ProviderID) error {
if id.IsZero() {
return errors.New("GUID cannot be zero")
}
return fwpmProviderDeleteByKey0(s.handle, &id)
}
Session
类是一个Windows过滤平台(Windows Filtering Platform,WFP)的会话,用于与操作系统内核通信以创建、配置和删除网络过滤规则。通过Session
类,用户可以添加、删除和修改网络过滤规则、提供程序和子层,并且可以与内核进行通信以获取有关网络数据包的信息。Session
类的方法包括添加提供程序(AddProvider
)、添加规则(AddRule
)、添加子层(AddSublayer
)、删除提供程序(DeleteProvider
)等。用户可以通过创建Session
类来与Windows过滤平台进行交互,以便在网络数据包进出计算机时进行网络过滤和安全控制。
type Sublayer struct {
// ID is the unique identifier for this sublayer.
ID SublayerID
// Name is a short descriptive name.
Name string
// Description is a longer description of the Sublayer.
Description string
// Persistent indicates whether the sublayer is preserved across
// restarts of the filtering engine.
Persistent bool
// Provider optionally identifies the Provider that manages this
// sublayer.
Provider ProviderID
// ProviderData is optional opaque data that can be held on behalf
// of the Provider.
ProviderData []byte
// Weight specifies the priority of this sublayer relative to
// other sublayers. Higher-weighted sublayers are invoked first.
Weight uint16
}
在wf包中,Sublayer
类代表了Windows过滤平台(WFP)中的子层(Sublayer)。子层是WFP的一种组织结构,用于将不同的过滤条件按照一定的优先级进行排序和组织,以便WFP根据这些条件来决定是否允许网络数据包通过。Sublayer
类中的字段包括子层的唯一标识符ID
、名称Name
、描述Description
、是否持久化存储Persistent
、子层所属的ProviderID
、ProviderData
等。通过创建Sublayer实例,可以向WFP注册一个新的子层,使得该子层的过滤条件可以被WFP进行处理。
在 Windows Filtering Platform (WFP) 中,Sublayer 是在 Filter Engine 启动时注册到内核中的用于组织规则的组件。Sublayer 允许管理者组织规则以便更好的进行过滤和管理。Sublayer 可以根据优先级进行排序,具有更高优先级的 Sublayer 将先于优先级低的 Sublayer 处理规则。Sublayer 可以由 Provider 进行管理,每个 Sublayer 都具有唯一的标识符。Sublayer 类中包含了 Sublayer 的各种属性信息,如名称、描述、优先级、Provider 等。
// TokenAccessInformation represents all the information in a token
// that is necessary to perform an access check.
// This type is only present in Layer fields, and cannot be used
// directly as a value in firewall rules.
type TokenAccessInformation struct{}
在 Windows Filtering Platform (WFP) 中,访问控制是通过访问令牌 (access token) 实现的。TokenAccessInformation
类型表示用于执行访问检查所需的令牌中的所有信息。在 WFP 规则中,TokenAccessInformation
类型仅作为 Layer 字段的一部分出现,不能直接用作防火墙规则的值。TokenAccessInformation
类型提供了一种指定需要的访问令牌信息的方法,从而使网络流量的访问控制更加灵活。
// TokenInformation defines a set of security identifiers.
// This type is only present in Layer fields, and cannot be used
// directly as a value in firewall rules.
type TokenInformation struct{}
在Windows防火墙策略的领域中,TokenInformation类型用于表示一组安全标识符(Security Identifiers,SIDs),这些标识符可以用于检查访问控制列表(Access Control List,ACL)是否允许或拒绝一个访问请求。它通常被用作防火墙规则中的目标以及在访问检查过程中进行匹配。但需要注意的是,TokenInformation
类型仅出现在Layer字段中,不能直接用作防火墙规则中的值。