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

@ -18,13 +18,14 @@ const ReceiverSocketPath = "/var/run/fw-daemon/fwoz.sock"
type OzInitProc struct {
Name string
Pid int
Address net.IP
SandboxID int
}
var OzInitPids []OzInitProc = []OzInitProc{}
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)
OzInitPidsLock.Lock()
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)
}
@ -160,7 +161,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
if tokens[0] == "register-init" && len(tokens) >= 3 {
initp := tokens[1]
initpid, err := strconv.Atoi(initp)
//initpid, err := strconv.Atoi(initp)
if err != nil {
log.Notice("IPC received invalid oz-init pid: ", initp)
@ -168,7 +169,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
return
}
sboxid, err := strconv.Atoi(tokens[3])
//sboxid, err := strconv.Atoi(tokens[3])
if err != nil {
log.Notice("IPC received invalid oz sbox number: ", tokens[3])
log.Notice("Data: %v", data)
@ -178,12 +179,12 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
// ozname := strings.Join(tokens[2:], " ")
log.Notice("IPC message for register-init OK.")
addInitPid(initpid, tokens[2], sboxid)
//addInitPid(initpid, tokens[2], sboxid)
c.Write([]byte("OK"))
return
} else if tokens[0] == "unregister-init" && len(tokens) == 2 {
initp := tokens[1]
initpid, err := strconv.Atoi(initp)
//initpid, err := strconv.Atoi(initp)
if err != nil {
log.Notice("IPC received invalid oz-init pid: ", initp)
@ -191,7 +192,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
return
}
removeInitPid(initpid)
//removeInitPid(initpid)
c.Write([]byte("OK.\n"))
}
@ -283,7 +284,7 @@ func OzReceiver(fw *Firewall) {
log.Warning("Adding existing Oz sandbox init pids...")
for s := 0; s < len(sboxes); s++ {
//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 {
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 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 logRule = "OUTPUT --protocol tcp -m mark --mark 1 -j LOG"
const blockRule = "OUTPUT --protocol tcp -m mark --mark 1 -j REJECT"
const blockRule2 = "FORWARD --protocol tcp -m mark --mark 1 -j REJECT"
func setupIPTables() {
// 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) {

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

@ -150,6 +150,7 @@ var PC2FDMapLock = &sync.Mutex{}
func monitorPromptFDs(pc pendingConnection) {
guid := pc.getGUID()
pid := pc.procInfo().Pid
//leaderpid := pc.procInfo().LeaderPid
inode := pc.procInfo().Inode
fd := pc.procInfo().FD
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)
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
} else
{
} else {
log.Warning("No unexpected errors");
}
PC2FDMapLock.Lock()
defer PC2FDMapLock.Unlock()
fdpath := fmt.Sprintf("/proc/%d/fd/%d", pid, fd)
var fdpath string
// 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}
return
}

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

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

@ -9,7 +9,7 @@ import (
"strings"
"sync"
"syscall"
"github.com/godbus/dbus"
//"github.com/godbus/dbus"
)
// Info is a struct containing the result of a socket proc query
@ -25,7 +25,8 @@ type Info struct {
ParentCmdLine string
ParentExePath string
Realm string
Sandbox string
Sandbox string
LeaderPid string
Inode uint64
FD int
}
@ -139,13 +140,24 @@ func (pi *Info) loadProcessInfo() bool {
if pi.loaded {
return true
}
exePath, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pi.Pid))
leaderpid := ""
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 {
log.Warningf("Error reading exe link for pid %d: %v", pi.Pid, err)
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 {
log.Warningf("Error reading cmdline for pid %d: %v", pi.Pid, err)
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 {
log.Warningf("Error reading cmdline for pid %d: %v", pi.Pid, err)
return false
@ -168,12 +180,12 @@ func (pi *Info) loadProcessInfo() bool {
}
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 {
log.Warningf("Error reading exe link for parent pid %d: %v", ppid, err)
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 {
log.Warningf("Error reading cmdline for parent pid %d: %v", ppid, err)
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 {
log.Warningf("Could not stat /proc/%d: %v", pi.Pid, err)
return false
@ -205,7 +212,7 @@ func (pi *Info) loadProcessInfo() bool {
pi.ExePath = exePath
pi.Realm = realm
pi.Sandbox = realm
//pi.Leaderpid = leaderpid
pi.LeaderPid = leaderpid
pi.CmdLine = string(bcs)
pi.loaded = 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 {
proto := "tcp"
/* if dstAddr.To4() == nil {
proto += "6"
}
*/
return findSocketCustom(proto, custdata, func(ss socketStatus) bool {
return ss.remote.port == dstPort && ss.remote.ip.Equal(dstAddr) && ss.local.port == srcPort
})

Loading…
Cancel
Save