additional fixes for citadel support + performance

shw-merge
dma 6 years ago
parent 04bd4ec052
commit 20c648026a

@ -68,6 +68,9 @@ func (dc *dnsCache) processDNS(pkt *nfqueue.NFQPacket) {
pinfo := getEmptyPInfo() pinfo := getEmptyPInfo()
if !isNSTrusted(srcip) { if !isNSTrusted(srcip) {
pinfo, _ = findProcessForPacket(pkt, true, procsnitch.MATCH_LOOSEST) pinfo, _ = findProcessForPacket(pkt, true, procsnitch.MATCH_LOOSEST)
if pinfo == nil {
findProcessForPacket(pkt, false, procsnitch.MATCH_LOOSEST)
}
if pinfo == nil { if pinfo == nil {
if !FirewallConfig.LogRedact { if !FirewallConfig.LogRedact {
@ -77,6 +80,8 @@ func (dc *dnsCache) processDNS(pkt *nfqueue.NFQPacket) {
} }
return return
} else {
log.Warningf("%v", pinfo)
} }
} }
//log.Notice("XXX: PROCESS LOOKUP -> ", pinfo) //log.Notice("XXX: PROCESS LOOKUP -> ", pinfo)

@ -18,13 +18,14 @@ const ReceiverSocketPath = "/var/run/fw-daemon/fwoz.sock"
type OzInitProc struct { type OzInitProc struct {
Name string Name string
Pid int Pid int
Address net.IP
SandboxID int SandboxID int
} }
var OzInitPids []OzInitProc = []OzInitProc{} var OzInitPids []OzInitProc = []OzInitProc{}
var OzInitPidsLock = sync.Mutex{} var OzInitPidsLock = sync.Mutex{}
func addInitPid(pid int, name string, sboxid int) { func addInitPid(pid int, name string, sboxid int, address net.IP) {
fmt.Println("::::::::::: init pid added: ", pid, " -> ", name) fmt.Println("::::::::::: init pid added: ", pid, " -> ", name)
OzInitPidsLock.Lock() OzInitPidsLock.Lock()
defer OzInitPidsLock.Unlock() defer OzInitPidsLock.Unlock()
@ -35,7 +36,7 @@ func addInitPid(pid int, name string, sboxid int) {
} }
} }
ozi := OzInitProc{Name: name, Pid: pid, SandboxID: sboxid} ozi := OzInitProc{Name: name, Pid: pid, SandboxID: sboxid, Address:address}
OzInitPids = append(OzInitPids, ozi) OzInitPids = append(OzInitPids, ozi)
} }
@ -160,7 +161,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
if tokens[0] == "register-init" && len(tokens) >= 3 { if tokens[0] == "register-init" && len(tokens) >= 3 {
initp := tokens[1] initp := tokens[1]
initpid, err := strconv.Atoi(initp) //initpid, err := strconv.Atoi(initp)
if err != nil { if err != nil {
log.Notice("IPC received invalid oz-init pid: ", initp) log.Notice("IPC received invalid oz-init pid: ", initp)
@ -168,7 +169,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
return return
} }
sboxid, err := strconv.Atoi(tokens[3]) //sboxid, err := strconv.Atoi(tokens[3])
if err != nil { if err != nil {
log.Notice("IPC received invalid oz sbox number: ", tokens[3]) log.Notice("IPC received invalid oz sbox number: ", tokens[3])
log.Notice("Data: %v", data) log.Notice("Data: %v", data)
@ -178,12 +179,12 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
// ozname := strings.Join(tokens[2:], " ") // ozname := strings.Join(tokens[2:], " ")
log.Notice("IPC message for register-init OK.") log.Notice("IPC message for register-init OK.")
addInitPid(initpid, tokens[2], sboxid) //addInitPid(initpid, tokens[2], sboxid)
c.Write([]byte("OK")) c.Write([]byte("OK"))
return return
} else if tokens[0] == "unregister-init" && len(tokens) == 2 { } else if tokens[0] == "unregister-init" && len(tokens) == 2 {
initp := tokens[1] initp := tokens[1]
initpid, err := strconv.Atoi(initp) //initpid, err := strconv.Atoi(initp)
if err != nil { if err != nil {
log.Notice("IPC received invalid oz-init pid: ", initp) log.Notice("IPC received invalid oz-init pid: ", initp)
@ -191,7 +192,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
return return
} }
removeInitPid(initpid) //removeInitPid(initpid)
c.Write([]byte("OK.\n")) c.Write([]byte("OK.\n"))
} }
@ -283,7 +284,7 @@ func OzReceiver(fw *Firewall) {
log.Warning("Adding existing Oz sandbox init pids...") log.Warning("Adding existing Oz sandbox init pids...")
for s := 0; s < len(sboxes); s++ { for s := 0; s < len(sboxes); s++ {
//profname := fmt.Sprintf("%s (%d)", sboxes[s].Profile, sboxes[s].Id) //profname := fmt.Sprintf("%s (%d)", sboxes[s].Profile, sboxes[s].Id)
addInitPid(sboxes[s].InitPid, sboxes[s].Name, sboxes[s].Id) addInitPid(sboxes[s].InitPid, sboxes[s].Name, sboxes[s].Id, sboxes[s].Address)
} }
} else { } else {
log.Warning("It does not appear there were any Oz sandboxed processes already launched.") log.Warning("It does not appear there were any Oz sandboxed processes already launched.")

@ -9,14 +9,18 @@ import (
const iptablesRule = "OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass" const iptablesRule = "OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass"
const realmsRule = "FORWARD -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass" const realmsRule = "FORWARD -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass"
const dnsRule2 = "FORWARD --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass"
const dnsRule = "INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass" const dnsRule = "INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass"
//const logRule = "OUTPUT --protocol tcp -m mark --mark 1 -j LOG" //const logRule = "OUTPUT --protocol tcp -m mark --mark 1 -j LOG"
const blockRule = "OUTPUT --protocol tcp -m mark --mark 1 -j REJECT" const blockRule = "OUTPUT --protocol tcp -m mark --mark 1 -j REJECT"
const blockRule2 = "FORWARD --protocol tcp -m mark --mark 1 -j REJECT"
func setupIPTables() { func setupIPTables() {
// addIPTRules(iptablesRule, dnsRule, logRule, blockRule) // addIPTRules(iptablesRule, dnsRule, logRule, blockRule)
addIPTRules(iptablesRule, realmsRule, dnsRule, blockRule) // addIPTRules(iptablesRule, realmsRule, dnsRule, dnsRule2, blockRule,blockRule2)
//addIPTRules(iptablesRule, realmsRule, dnsRule, blockRule)
addIPTRules(iptablesRule, realmsRule, dnsRule, dnsRule2, blockRule,blockRule2)
} }
func addIPTRules(rules ...string) { func addIPTRules(rules ...string) {

@ -606,7 +606,7 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket, timestamp time.Time) {
// return // return
} else { } else {
ppath = pinfo.ExePath ppath = pinfo.ExePath
optstring = fmt.Sprintf("Realm: %s", pinfo.Realm); optstring = fmt.Sprintf("Realm: %s", pinfo.Realm)
cf := strings.Fields(pinfo.CmdLine) cf := strings.Fields(pinfo.CmdLine)
if len(cf) > 1 && strings.HasPrefix(cf[1], "/") { if len(cf) > 1 && strings.HasPrefix(cf[1], "/") {
for _, intp := range _interpreters { for _, intp := range _interpreters {
@ -846,53 +846,61 @@ func findProcessForPacket(pkt *nfqueue.NFQPacket, reverse bool, strictness int)
res = procsnitch.LookupICMPSocketProcessAll(srcip, dstip, icode, nil) res = procsnitch.LookupICMPSocketProcessAll(srcip, dstip, icode, nil)
} }
if res != nil {
res.Sandbox = "citadel"
res.Realm = "citadel"
}
if res == nil { if res == nil {
removePids := make([]int, 0) removePids := make([]int, 0)
OzInitPidsLock.Lock() OzInitPidsLock.Lock()
for i := 0; i < len(OzInitPids); i++ { for i := 0; i < len(OzInitPids); i++ {
data := "" if OzInitPids[i].Address.Equal(srcip) {
fname := fmt.Sprintf("/proc/%d/root/proc/1/net/%s", OzInitPids[i].Pid, proto) data := ""
//fmt.Println("XXX: opening: ", fname) fname := fmt.Sprintf("/proc/%d/root/proc/1/net/%s", OzInitPids[i].Pid, proto)
bdata, err := readFileDirect(fname) //fmt.Println("XXX: opening: ", fname)
bdata, err := readFileDirect(fname)
if err != nil { if err != nil {
fmt.Println("Error reading proc data from ", fname, ": ", err) fmt.Println("Error reading proc data from ", fname, ": ", err)
if err == syscall.ENOENT { if err == syscall.ENOENT {
removePids = append(removePids, OzInitPids[i].Pid) removePids = append(removePids, OzInitPids[i].Pid)
} }
continue continue
} else { } else {
data = string(bdata) data = string(bdata)
lines := strings.Split(data, "\n") lines := strings.Split(data, "\n")
rlines := make([]string, 0) rlines := make([]string, 0)
for l := 0; l < len(lines); l++ { for l := 0; l < len(lines); l++ {
lines[l] = strings.TrimSpace(lines[l]) lines[l] = strings.TrimSpace(lines[l])
ssplit := strings.Split(lines[l], ":") ssplit := strings.Split(lines[l], ":")
if len(ssplit) != 6 { if len(ssplit) != 6 {
continue continue
} }
rlines = append(rlines, strings.Join(ssplit, ":")) rlines = append(rlines, strings.Join(ssplit, ":"))
} }
if proto == "tcp" { if proto == "tcp" {
//res = procsnitch.LookupTCPSocketProcessAll(srcip, srcp, dstip, dstp, rlines) //res = procsnitch.LookupTCPSocketProcessAll(srcip, srcp, dstip, dstp, rlines)
res = procsnitch.L2(srcp, dstip, dstp, rlines) res = procsnitch.L2(srcp, dstip, dstp, rlines)
} else if proto == "udp" { } else if proto == "udp" {
res = procsnitch.LookupUDPSocketProcessAll(srcip, srcp, dstip, dstp, rlines, strictness) res = procsnitch.LookupUDPSocketProcessAll(srcip, srcp, dstip, dstp, rlines, strictness)
} else if proto == "icmp" { } else if proto == "icmp" {
res = procsnitch.LookupICMPSocketProcessAll(srcip, dstip, icode, rlines) res = procsnitch.LookupICMPSocketProcessAll(srcip, dstip, icode, rlines)
} }
if res != nil { if res != nil {
optstr = "Realm: " + OzInitPids[i].Name optstr = "Realm: " + OzInitPids[i].Name
res.ExePath = GetRealRoot(res.ExePath, OzInitPids[i].Pid) res.Sandbox = OzInitPids[i].Name
break res.ExePath = GetRealRoot(res.ExePath, OzInitPids[i].Pid)
break
}
} }
} }
@ -912,10 +920,15 @@ func findProcessForPacket(pkt *nfqueue.NFQPacket, reverse bool, strictness int)
func basicAllowPacket(pkt *nfqueue.NFQPacket) bool { func basicAllowPacket(pkt *nfqueue.NFQPacket) bool {
srcip, dstip := getPacketIPAddrs(pkt) srcip, dstip := getPacketIPAddrs(pkt)
if pkt.Packet.Layer(layers.LayerTypeUDP) != nil { if pkt.Packet.Layer(layers.LayerTypeUDP) != nil {
_, dport := getPacketUDPPorts(pkt) sport, dport := getPacketUDPPorts(pkt)
if dport == 53 { if dport == 53 {
// fw.dns.processDNS(pkt) // fw.dns.processDNS(pkt)
return true return true
} else {
if sport == 53 {
// fw.dns.processDNS(pkt)
return true
}
} }
} }
if pkt.Packet.Layer(layers.LayerTypeICMPv4) != nil && srcip.Equal(dstip) { if pkt.Packet.Layer(layers.LayerTypeICMPv4) != nil && srcip.Equal(dstip) {

@ -150,6 +150,7 @@ var PC2FDMapLock = &sync.Mutex{}
func monitorPromptFDs(pc pendingConnection) { func monitorPromptFDs(pc pendingConnection) {
guid := pc.getGUID() guid := pc.getGUID()
pid := pc.procInfo().Pid pid := pc.procInfo().Pid
//leaderpid := pc.procInfo().LeaderPid
inode := pc.procInfo().Inode inode := pc.procInfo().Inode
fd := pc.procInfo().FD fd := pc.procInfo().FD
prompter := pc.getPrompter() prompter := pc.getPrompter()
@ -157,17 +158,21 @@ func monitorPromptFDs(pc pendingConnection) {
//fmt.Printf("ADD TO MONITOR: %v | %v / %v / %v\n", pc.policy().application, guid, pid, fd) //fmt.Printf("ADD TO MONITOR: %v | %v / %v / %v\n", pc.policy().application, guid, pid, fd)
if pid == -1 || fd == -1 || prompter == nil { if pid == -1 || fd == -1 || prompter == nil {
log.Warning("Unexpected error condition occurred while adding socket fd to monitor: %d %d %v",pid, fd, prompter) log.Warningf("Unexpected error condition occurred while adding socket fd to monitor: %d %d %v",pid, fd, prompter)
return return
} else } else {
{
log.Warning("No unexpected errors"); log.Warning("No unexpected errors");
} }
PC2FDMapLock.Lock() PC2FDMapLock.Lock()
defer PC2FDMapLock.Unlock() defer PC2FDMapLock.Unlock()
var fdpath string
fdpath := fmt.Sprintf("/proc/%d/fd/%d", pid, fd) // log.Warning("leaderpid:",pc.procInfo().LeaderPid)
//if pc.procInfo().LeaderPid != "" {
// fdpath = fmt.Sprintf("/proc/%s/root/%d/fd/%d", leaderpid, pid, fd)
// } else {
fdpath = fmt.Sprintf("/proc/%d/fd/%d", pid, fd)
// }
PC2FDMap[guid] = PC2FDMapping{guid: guid, inode: inode, fd: fd, fdpath: fdpath, prompter: prompter} PC2FDMap[guid] = PC2FDMapping{guid: guid, inode: inode, fd: fd, fdpath: fdpath, prompter: prompter}
return return
} }

@ -123,8 +123,9 @@ func (fw *Firewall) runFilter() {
p.Packet = ip6p p.Packet = ip6p
} }
var pkt nfqueue.NFQPacket
fw.filterPacket(p, timestamp) pkt = *p
go fw.filterPacket(&pkt, timestamp)
} else { } else {
p.Accept() p.Accept()
} }

@ -7,6 +7,7 @@ import (
"os" "os"
"bufio" "bufio"
"strconv" "strconv"
"net"
"github.com/godbus/dbus" "github.com/godbus/dbus"
) )
@ -16,7 +17,7 @@ type ListSandboxesMsg struct {
type SandboxInfo struct { type SandboxInfo struct {
Id int Id int
Address string Address net.IP
Name string Name string
Profile string Profile string
Mounts []string Mounts []string
@ -53,8 +54,8 @@ func getSandboxes() ([]SandboxInfo, error) {
s := strings.Split(scanner.Text(), ":") s := strings.Split(scanner.Text(), ":")
obj.Call("com.subgraph.realms.Manager.LeaderPidFromIP", 0, s[1]).Store(&leaderpid) obj.Call("com.subgraph.realms.Manager.LeaderPidFromIP", 0, s[1]).Store(&leaderpid)
p, _ := strconv.Atoi(leaderpid) p, _ := strconv.Atoi(leaderpid)
sboxes = append(sboxes,SandboxInfo{Id: i, Name: s[0], Address: s[1], InitPid: p}) sboxes = append(sboxes,SandboxInfo{Id: i, Name: s[0], Address: net.ParseIP(s[1]), InitPid: p})
fmt.Print(s[0], s[1], leaderpid) log.Warningf("Found realm, name=%v ip=%v leader pid=%v ", s[0], s[1], leaderpid)
i++; i++;
} }

@ -9,7 +9,7 @@ import (
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
"github.com/godbus/dbus" //"github.com/godbus/dbus"
) )
// Info is a struct containing the result of a socket proc query // Info is a struct containing the result of a socket proc query
@ -25,7 +25,8 @@ type Info struct {
ParentCmdLine string ParentCmdLine string
ParentExePath string ParentExePath string
Realm string Realm string
Sandbox string Sandbox string
LeaderPid string
Inode uint64 Inode uint64
FD int FD int
} }
@ -139,13 +140,24 @@ func (pi *Info) loadProcessInfo() bool {
if pi.loaded { if pi.loaded {
return true return true
} }
leaderpid := ""
exePath, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pi.Pid)) realm := "unknown"
//conn, _ := dbus.SystemBus()
//obj := conn.Object("com.subgraph.realms", "/")
//obj.Call("com.subgraph.realms.Manager.RealmFromContainerPid", 0, fmt.Sprintf("%d",pi.Pid)).Store(&realm)
//obj.Call("com.subgraph.realms.Manager.LeaderPidFromRealm", 0, realm).Store(&leaderpid)
pi.LeaderPid = leaderpid
prefix := ""
if leaderpid != "" {
prefix = fmt.Sprintf("/proc/%s/root",leaderpid)
}
prefix = ""
exePath, err := os.Readlink(fmt.Sprintf("%s/proc/%d/exe", prefix, pi.Pid))
if err != nil { if err != nil {
log.Warningf("Error reading exe link for pid %d: %v", pi.Pid, err) log.Warningf("Error reading exe link for pid %d: %v", pi.Pid, err)
return false return false
} }
bcs, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pi.Pid)) bcs, err := ioutil.ReadFile(fmt.Sprintf("%s/proc/%d/cmdline", prefix, pi.Pid))
if err != nil { if err != nil {
log.Warningf("Error reading cmdline for pid %d: %v", pi.Pid, err) log.Warningf("Error reading cmdline for pid %d: %v", pi.Pid, err)
return false return false
@ -156,7 +168,7 @@ func (pi *Info) loadProcessInfo() bool {
} }
} }
bs, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", pi.Pid)) bs, err := ioutil.ReadFile(fmt.Sprintf("%s/proc/%d/stat", prefix, pi.Pid))
if err != nil { if err != nil {
log.Warningf("Error reading cmdline for pid %d: %v", pi.Pid, err) log.Warningf("Error reading cmdline for pid %d: %v", pi.Pid, err)
return false return false
@ -168,12 +180,12 @@ func (pi *Info) loadProcessInfo() bool {
} }
ppid := toPid(fs[3]) ppid := toPid(fs[3])
pexePath, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", ppid)) pexePath, err := os.Readlink(fmt.Sprintf("%s/proc/%d/exe", prefix, ppid))
if err != nil { if err != nil {
log.Warningf("Error reading exe link for parent pid %d: %v", ppid, err) log.Warningf("Error reading exe link for parent pid %d: %v", ppid, err)
return false return false
} }
pbs, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", ppid)) pbs, err := ioutil.ReadFile(fmt.Sprintf("%s/proc/%d/cmdline", prefix, ppid))
if err != nil { if err != nil {
log.Warningf("Error reading cmdline for parent pid %d: %v", ppid, err) log.Warningf("Error reading cmdline for parent pid %d: %v", ppid, err)
return false return false
@ -184,14 +196,9 @@ func (pi *Info) loadProcessInfo() bool {
} }
} }
conn, _ := dbus.SystemBus()
obj := conn.Object("com.subgraph.realms", "/")
realm := "unknown"
//leaderpid := ""
obj.Call("com.subgraph.realms.Manager.RealmFromContainerPid", 0, fmt.Sprintf("%d",pi.Pid)).Store(&realm)
finfo, err := os.Stat(fmt.Sprintf("/proc/%d", pi.Pid))
finfo, err := os.Stat(fmt.Sprintf("%s/proc/%d", prefix, pi.Pid))
if err != nil { if err != nil {
log.Warningf("Could not stat /proc/%d: %v", pi.Pid, err) log.Warningf("Could not stat /proc/%d: %v", pi.Pid, err)
return false return false
@ -205,7 +212,7 @@ func (pi *Info) loadProcessInfo() bool {
pi.ExePath = exePath pi.ExePath = exePath
pi.Realm = realm pi.Realm = realm
pi.Sandbox = realm pi.Sandbox = realm
//pi.Leaderpid = leaderpid pi.LeaderPid = leaderpid
pi.CmdLine = string(bcs) pi.CmdLine = string(bcs)
pi.loaded = true pi.loaded = true
return true return true

@ -254,6 +254,10 @@ func findTCPSocketAll(srcAddr net.IP, srcPort uint16, dstAddr net.IP, dstPort ui
func f2(srcPort uint16, dstAddr net.IP, dstPort uint16, custdata[]string) *socketStatus { func f2(srcPort uint16, dstAddr net.IP, dstPort uint16, custdata[]string) *socketStatus {
proto := "tcp" proto := "tcp"
/* if dstAddr.To4() == nil {
proto += "6"
}
*/
return findSocketCustom(proto, custdata, func(ss socketStatus) bool { return findSocketCustom(proto, custdata, func(ss socketStatus) bool {
return ss.remote.port == dstPort && ss.remote.ip.Equal(dstAddr) && ss.local.port == srcPort return ss.remote.port == dstPort && ss.remote.ip.Equal(dstAddr) && ss.local.port == srcPort
}) })

Loading…
Cancel
Save