|
|
@ -5,13 +5,14 @@ import (
|
|
|
|
"sync"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/subgraph/fw-daemon/nfqueue"
|
|
|
|
"github.com/subgraph/fw-daemon/nfqueue"
|
|
|
|
|
|
|
|
"github.com/subgraph/fw-daemon/proc"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type pendingPkt struct {
|
|
|
|
type pendingPkt struct {
|
|
|
|
policy *Policy
|
|
|
|
policy *Policy
|
|
|
|
hostname string
|
|
|
|
hostname string
|
|
|
|
pkt *nfqueue.Packet
|
|
|
|
pkt *nfqueue.Packet
|
|
|
|
proc *ProcInfo
|
|
|
|
pinfo *proc.ProcInfo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Policy struct {
|
|
|
|
type Policy struct {
|
|
|
@ -42,12 +43,12 @@ func (fw *Firewall) policyForPath(path string) *Policy {
|
|
|
|
return fw.policyMap[path]
|
|
|
|
return fw.policyMap[path]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (p *Policy) processPacket(pkt *nfqueue.Packet, proc *ProcInfo) {
|
|
|
|
func (p *Policy) processPacket(pkt *nfqueue.Packet, pinfo *proc.ProcInfo) {
|
|
|
|
p.lock.Lock()
|
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
name := p.fw.dns.Lookup(pkt.Dst)
|
|
|
|
name := p.fw.dns.Lookup(pkt.Dst)
|
|
|
|
log.Info("Lookup(%s): %s", pkt.Dst.String(), name)
|
|
|
|
log.Info("Lookup(%s): %s", pkt.Dst.String(), name)
|
|
|
|
result := p.rules.filter(pkt, proc, name)
|
|
|
|
result := p.rules.filter(pkt, pinfo, name)
|
|
|
|
switch result {
|
|
|
|
switch result {
|
|
|
|
case FILTER_DENY:
|
|
|
|
case FILTER_DENY:
|
|
|
|
pkt.Mark = 1
|
|
|
|
pkt.Mark = 1
|
|
|
@ -55,7 +56,7 @@ func (p *Policy) processPacket(pkt *nfqueue.Packet, proc *ProcInfo) {
|
|
|
|
case FILTER_ALLOW:
|
|
|
|
case FILTER_ALLOW:
|
|
|
|
pkt.Accept()
|
|
|
|
pkt.Accept()
|
|
|
|
case FILTER_PROMPT:
|
|
|
|
case FILTER_PROMPT:
|
|
|
|
p.processPromptResult(&pendingPkt{policy: p, hostname: name, pkt: pkt, proc: proc})
|
|
|
|
p.processPromptResult(&pendingPkt{policy: p, hostname: name, pkt: pkt, pinfo: pinfo})
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
log.Warning("Unexpected filter result: %d", result)
|
|
|
|
log.Warning("Unexpected filter result: %d", result)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -162,21 +163,21 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.Packet) {
|
|
|
|
fw.dns.processDNS(pkt)
|
|
|
|
fw.dns.processDNS(pkt)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
proc := findProcessForPacket(pkt)
|
|
|
|
pinfo := proc.FindProcessForPacket(pkt)
|
|
|
|
if proc == nil {
|
|
|
|
if pinfo == nil {
|
|
|
|
log.Warning("No proc found for %s", printPacket(pkt, fw.dns.Lookup(pkt.Dst)))
|
|
|
|
log.Warning("No proc found for %s", printPacket(pkt, fw.dns.Lookup(pkt.Dst)))
|
|
|
|
pkt.Accept()
|
|
|
|
pkt.Accept()
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Debug("filterPacket [%s] %s", proc.exePath, printPacket(pkt, fw.dns.Lookup(pkt.Dst)))
|
|
|
|
log.Debug("filterPacket [%s] %s", pinfo.ExePath, printPacket(pkt, fw.dns.Lookup(pkt.Dst)))
|
|
|
|
if basicAllowPacket(pkt) {
|
|
|
|
if basicAllowPacket(pkt) {
|
|
|
|
pkt.Accept()
|
|
|
|
pkt.Accept()
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fw.lock.Lock()
|
|
|
|
fw.lock.Lock()
|
|
|
|
policy := fw.policyForPath(proc.exePath)
|
|
|
|
policy := fw.policyForPath(pinfo.ExePath)
|
|
|
|
fw.lock.Unlock()
|
|
|
|
fw.lock.Unlock()
|
|
|
|
policy.processPacket(pkt, proc)
|
|
|
|
policy.processPacket(pkt, pinfo)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func basicAllowPacket(pkt *nfqueue.Packet) bool {
|
|
|
|
func basicAllowPacket(pkt *nfqueue.Packet) bool {
|
|
|
|