mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-29 03:23:56 +01:00
ba7a39a4fc
Update the client's engine to apply firewall rules received from the manager (results of ACL policy).
91 lines
1.9 KiB
Go
91 lines
1.9 KiB
Go
package iface
|
|
|
|
import (
|
|
"net"
|
|
"sync"
|
|
|
|
"golang.zx2c4.com/wireguard/tun"
|
|
)
|
|
|
|
// PacketFilter interface for firewall abilities
|
|
type PacketFilter interface {
|
|
// DropOutgoing filter outgoing packets from host to external destinations
|
|
DropOutgoing(packetData []byte) bool
|
|
|
|
// DropIncoming filter incoming packets from external sources to host
|
|
DropIncoming(packetData []byte) bool
|
|
|
|
// SetNetwork of the wireguard interface to which filtering applied
|
|
SetNetwork(*net.IPNet)
|
|
}
|
|
|
|
// DeviceWrapper to override Read or Write of packets
|
|
type DeviceWrapper struct {
|
|
tun.Device
|
|
filter PacketFilter
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// newDeviceWrapper constructor function
|
|
func newDeviceWrapper(device tun.Device) *DeviceWrapper {
|
|
return &DeviceWrapper{
|
|
Device: device,
|
|
}
|
|
}
|
|
|
|
// Read wraps read method with filtering feature
|
|
func (d *DeviceWrapper) Read(bufs [][]byte, sizes []int, offset int) (n int, err error) {
|
|
if n, err = d.Device.Read(bufs, sizes, offset); err != nil {
|
|
return 0, err
|
|
}
|
|
d.mutex.RLock()
|
|
filter := d.filter
|
|
d.mutex.RUnlock()
|
|
|
|
if filter == nil {
|
|
return
|
|
}
|
|
|
|
for i := 0; i < n; i++ {
|
|
if filter.DropOutgoing(bufs[i][offset : offset+sizes[i]]) {
|
|
bufs = append(bufs[:i], bufs[i+1:]...)
|
|
sizes = append(sizes[:i], sizes[i+1:]...)
|
|
n--
|
|
i--
|
|
}
|
|
}
|
|
|
|
return n, nil
|
|
}
|
|
|
|
// Write wraps write method with filtering feature
|
|
func (d *DeviceWrapper) Write(bufs [][]byte, offset int) (int, error) {
|
|
d.mutex.RLock()
|
|
filter := d.filter
|
|
d.mutex.RUnlock()
|
|
|
|
if filter == nil {
|
|
return d.Device.Write(bufs, offset)
|
|
}
|
|
|
|
filteredBufs := make([][]byte, 0, len(bufs))
|
|
dropped := 0
|
|
for _, buf := range bufs {
|
|
if !filter.DropIncoming(buf[offset:]) {
|
|
filteredBufs = append(filteredBufs, buf)
|
|
dropped++
|
|
}
|
|
}
|
|
|
|
n, err := d.Device.Write(filteredBufs, offset)
|
|
n += dropped
|
|
return n, err
|
|
}
|
|
|
|
// SetFiltering sets packet filter to device
|
|
func (d *DeviceWrapper) SetFiltering(filter PacketFilter) {
|
|
d.mutex.Lock()
|
|
d.filter = filter
|
|
d.mutex.Unlock()
|
|
}
|