|
|
@ -9,7 +9,6 @@ import (
|
|
|
|
"path"
|
|
|
|
"path"
|
|
|
|
"strconv"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"strings"
|
|
|
|
"unicode"
|
|
|
|
|
|
|
|
"regexp"
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
|
|
|
|
nfqueue "github.com/subgraph/go-nfnetlink/nfqueue"
|
|
|
|
nfqueue "github.com/subgraph/go-nfnetlink/nfqueue"
|
|
|
@ -18,7 +17,9 @@ import (
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const matchAny = 0
|
|
|
|
const matchAny = 0
|
|
|
|
const noAddress = uint32(0xffffffff)
|
|
|
|
//const noAddress = uint32(0xffffffff)
|
|
|
|
|
|
|
|
var anyAddress net.IP = net.IP{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}
|
|
|
|
|
|
|
|
var noAddress net.IP = net.IP{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}
|
|
|
|
|
|
|
|
|
|
|
|
type Rule struct {
|
|
|
|
type Rule struct {
|
|
|
|
id uint
|
|
|
|
id uint
|
|
|
@ -28,7 +29,7 @@ type Rule struct {
|
|
|
|
proto string
|
|
|
|
proto string
|
|
|
|
hostname string
|
|
|
|
hostname string
|
|
|
|
network *net.IPNet
|
|
|
|
network *net.IPNet
|
|
|
|
addr uint32
|
|
|
|
addr net.IP
|
|
|
|
saddr net.IP
|
|
|
|
saddr net.IP
|
|
|
|
port uint16
|
|
|
|
port uint16
|
|
|
|
uid int
|
|
|
|
uid int
|
|
|
@ -66,10 +67,11 @@ func (r *Rule) AddrString(redact bool) string {
|
|
|
|
addr = r.hostname
|
|
|
|
addr = r.hostname
|
|
|
|
} else if r.network != nil {
|
|
|
|
} else if r.network != nil {
|
|
|
|
addr = r.network.String()
|
|
|
|
addr = r.network.String()
|
|
|
|
} else if r.addr != matchAny && r.addr != noAddress {
|
|
|
|
} else if !addrMatchesAny(r.addr) && !addrMatchesNone(r.addr) {
|
|
|
|
bs := make([]byte, 4)
|
|
|
|
// bs := make([]byte, 4)
|
|
|
|
binary.BigEndian.PutUint32(bs, r.addr)
|
|
|
|
// binary.BigEndian.PutUint32(bs, r.addr)
|
|
|
|
addr = fmt.Sprintf("%d.%d.%d.%d", bs[0], bs[1], bs[2], bs[3])
|
|
|
|
// addr = fmt.Sprintf("%d.%d.%d.%d", bs[0], bs[1], bs[2], bs[3])
|
|
|
|
|
|
|
|
addr = r.addr.String()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if r.port != matchAny || r.proto == "icmp" {
|
|
|
|
if r.port != matchAny || r.proto == "icmp" {
|
|
|
@ -99,13 +101,11 @@ func (r *Rule) match(src net.IP, dst net.IP, dstPort uint16, hostname string, pr
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
xip := make(net.IP, 4)
|
|
|
|
log.Notice("comparison: ", hostname, " / ", dst, " : ", dstPort, " -> ", r.addr, " / ", r.hostname, " : ", r.port)
|
|
|
|
binary.BigEndian.PutUint32(xip, r.addr)
|
|
|
|
|
|
|
|
log.Notice("comparison: ", hostname, " / ", dst, " : ", dstPort, " -> ", xip, " / ", r.hostname, " : ", r.port)
|
|
|
|
|
|
|
|
if r.port != matchAny && r.port != dstPort {
|
|
|
|
if r.port != matchAny && r.port != dstPort {
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r.addr == matchAny {
|
|
|
|
if addrMatchesAny(r.addr) {
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if r.hostname != "" {
|
|
|
|
if r.hostname != "" {
|
|
|
@ -126,15 +126,15 @@ log.Notice("comparison: ", hostname, " / ", dst, " : ", dstPort, " -> ", xip, "
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if proto == "icmp" {
|
|
|
|
if proto == "icmp" {
|
|
|
|
fmt.Printf("network = %v, src = %v, r.addr = %x, src to4 = %x\n", r.network, src, r.addr, binary.BigEndian.Uint32(src.To4()))
|
|
|
|
fmt.Printf("network = %v, src = %v, r.addr = %x, src to4 = %x\n", r.network, src, r.addr, binary.BigEndian.Uint32(src.To4()))
|
|
|
|
if (r.network != nil && r.network.Contains(src)) || (r.addr == binary.BigEndian.Uint32(src.To4())) {
|
|
|
|
if (r.network != nil && r.network.Contains(src)) || (r.addr.Equal(src)) {
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r.addr == binary.BigEndian.Uint32(dst.To4())
|
|
|
|
return r.addr.Equal(dst)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (rl *RuleList) filterPacket(p *nfqueue.NFQPacket, pinfo *procsnitch.Info, srcip net.IP, hostname, optstr string) FilterResult {
|
|
|
|
func (rl *RuleList) filterPacket(p *nfqueue.NFQPacket, pinfo *procsnitch.Info, srcip net.IP, hostname, optstr string) FilterResult {
|
|
|
|
_, dstip := getPacketIP4Addrs(p)
|
|
|
|
_, dstip := getPacketIPAddrs(p)
|
|
|
|
_, dstp := getPacketPorts(p)
|
|
|
|
_, dstp := getPacketPorts(p)
|
|
|
|
return rl.filter(p, srcip, dstip, dstp, hostname, pinfo, optstr)
|
|
|
|
return rl.filter(p, srcip, dstip, dstp, hostname, pinfo, optstr)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -162,7 +162,7 @@ log.Notice("+ MATCH SUCCEEDED")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
srcStr := STR_UNKNOWN
|
|
|
|
srcStr := STR_UNKNOWN
|
|
|
|
if pkt != nil {
|
|
|
|
if pkt != nil {
|
|
|
|
srcip, _ := getPacketIP4Addrs(pkt)
|
|
|
|
srcip, _ := getPacketIPAddrs(pkt)
|
|
|
|
srcp, _ := getPacketPorts(pkt)
|
|
|
|
srcp, _ := getPacketPorts(pkt)
|
|
|
|
srcStr = fmt.Sprintf("%s:%d", srcip, srcp)
|
|
|
|
srcStr = fmt.Sprintf("%s:%d", srcip, srcp)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -272,30 +272,31 @@ func (r *Rule) parseVerb(v string) bool {
|
|
|
|
|
|
|
|
|
|
|
|
func (r *Rule) parseTarget(t string) bool {
|
|
|
|
func (r *Rule) parseTarget(t string) bool {
|
|
|
|
addrPort := strings.Split(t, ":")
|
|
|
|
addrPort := strings.Split(t, ":")
|
|
|
|
if len(addrPort) != 2 && len(addrPort) != 3 {
|
|
|
|
if len(addrPort) < 2 {
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sind := 0
|
|
|
|
sind := 0
|
|
|
|
if len(addrPort) == 3 {
|
|
|
|
lind := len(addrPort)-1
|
|
|
|
if addrPort[0] != "udp" && addrPort[0] != "icmp" && addrPort[0] != "tcp" {
|
|
|
|
if addrPort[0] == "udp" || addrPort[0] == "icmp" || addrPort[0] == "tcp" {
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
r.proto = addrPort[0]
|
|
|
|
r.proto = addrPort[0]
|
|
|
|
sind++
|
|
|
|
sind++
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
r.proto = "tcp"
|
|
|
|
r.proto = "tcp"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return r.parseAddr(addrPort[sind]) && r.parsePort(addrPort[sind+1])
|
|
|
|
newAddr := strings.Join(addrPort[sind:lind], ":")
|
|
|
|
|
|
|
|
return r.parseAddr(newAddr) && r.parsePort(addrPort[lind])
|
|
|
|
|
|
|
|
// return r.parseAddr(addrPort[sind]) && r.parsePort(addrPort[sind+1])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (r *Rule) parseAddr(a string) bool {
|
|
|
|
func (r *Rule) parseAddr(a string) bool {
|
|
|
|
if a == "*" {
|
|
|
|
if a == "*" {
|
|
|
|
r.hostname = ""
|
|
|
|
r.hostname = ""
|
|
|
|
r.addr = matchAny
|
|
|
|
r.addr = anyAddress
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if strings.IndexFunc(a, unicode.IsLetter) != -1 {
|
|
|
|
// if strings.IndexFunc(a, unicode.IsLetter) != -1 {
|
|
|
|
|
|
|
|
if net.ParseIP(a) == nil {
|
|
|
|
r.hostname = a
|
|
|
|
r.hostname = a
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -310,7 +311,7 @@ func (r *Rule) parseAddr(a string) bool {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
r.network = ipnet
|
|
|
|
r.network = ipnet
|
|
|
|
}
|
|
|
|
}
|
|
|
|
r.addr = binary.BigEndian.Uint32(ip.To4())
|
|
|
|
r.addr = ip
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -445,3 +446,23 @@ func processRuleLine(policy *Policy, line string) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func addrMatchesAny(addr net.IP) bool {
|
|
|
|
|
|
|
|
any := anyAddress
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if addr.To4() != nil {
|
|
|
|
|
|
|
|
any = net.IP{0,0,0,0}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return any.Equal(addr)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func addrMatchesNone(addr net.IP) bool {
|
|
|
|
|
|
|
|
none := noAddress
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if addr.To4() != nil {
|
|
|
|
|
|
|
|
none = net.IP{0xff,0xff,0xff,0xff}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return none.Equal(addr)
|
|
|
|
|
|
|
|
}
|
|
|
|