mirror of https://github.com/subgraph/fw-daemon
fw-daemon prompter is now updated with source address of originating packet. Fixed bug in decoding DNS data. Packets are dropped properly (by marking and then calling Accept()).shw_dev
parent
942b0a0c01
commit
cadb859dce
@ -0,0 +1,90 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"flag"
|
||||||
|
"strconv"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ReceiverSocketPath = "/tmp/fwoz.sock"
|
||||||
|
|
||||||
|
func reader(r io.Reader) {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
|
||||||
|
for {
|
||||||
|
n, err := r.Read(buf[:])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(buf[0:n]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
dump := flag.Bool("d", false, "dump current oz-fw rules")
|
||||||
|
whitelist := flag.Bool("w", false, "submit whitelist rule")
|
||||||
|
blacklist := flag.Bool("b", false, "submit blacklist rule")
|
||||||
|
src := flag.String("src", "", "source IP address")
|
||||||
|
dst := flag.String("dst", "", "destination IP address")
|
||||||
|
port := flag.Int("port", 0, "destination port number")
|
||||||
|
rm := flag.Bool("rm", false, "remove entry from rules (default is add)")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if !*dump {
|
||||||
|
|
||||||
|
if *src == "" {
|
||||||
|
log.Fatal("Error: must specify source address with -src")
|
||||||
|
} else if *dst == "" {
|
||||||
|
log.Fatal("Error: must specify destination address with -dst")
|
||||||
|
} else if *port == 0 {
|
||||||
|
log.Fatal("Error: must specify destination port with -port")
|
||||||
|
} else if *port <= 0 || *port > 65535 {
|
||||||
|
log.Fatal("Error: invalid port was specified")
|
||||||
|
} else if !*whitelist && !*blacklist {
|
||||||
|
log.Fatal("Error: -w or -b must be specified to whitelist or blacklist entry")
|
||||||
|
} else if *whitelist && *blacklist {
|
||||||
|
log.Fatal("Error: -w and -b cannot be specified together")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fmt.Println("Attempting to dump active rule list.")
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := net.Dial("unix", ReceiverSocketPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Could not establish connection to listener:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
if *dump {
|
||||||
|
c.Write([]byte("dump\n"))
|
||||||
|
reader(c)
|
||||||
|
fmt.Println("Done.")
|
||||||
|
} else {
|
||||||
|
reqstr := ""
|
||||||
|
|
||||||
|
if *rm {
|
||||||
|
reqstr += "remove "
|
||||||
|
} else {
|
||||||
|
reqstr += "add "
|
||||||
|
}
|
||||||
|
|
||||||
|
if *whitelist {
|
||||||
|
reqstr += "whitelist"
|
||||||
|
} else {
|
||||||
|
reqstr += "blacklist"
|
||||||
|
}
|
||||||
|
|
||||||
|
reqstr += " " + *src + " " + *dst + " " + strconv.Itoa(*port) + "\n"
|
||||||
|
c.Write([]byte(reqstr))
|
||||||
|
reader(c)
|
||||||
|
fmt.Println("Done.")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,187 @@
|
|||||||
|
package sgfw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"bufio"
|
||||||
|
"strings"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ReceiverSocketPath = "/tmp/fwoz.sock"
|
||||||
|
|
||||||
|
|
||||||
|
func canAddRule(rule sandboxRule) bool {
|
||||||
|
|
||||||
|
for i := 0; i < len(sandboxRules); i++ {
|
||||||
|
|
||||||
|
if rule.SrcIf.Equal(sandboxRules[i].SrcIf) && rule.Whitelist != sandboxRules[i].Whitelist {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func ruleExists(rule sandboxRule) int {
|
||||||
|
|
||||||
|
for i := 0; i < len(sandboxRules); i++ {
|
||||||
|
|
||||||
|
if rule.Whitelist == sandboxRules[i].Whitelist && rule.SrcIf.Equal(sandboxRules[i].SrcIf) && rule.DstIP.Equal(sandboxRules[i].DstIP) && rule.DstPort == sandboxRules[i].DstPort {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReceiverLoop(c net.Conn) {
|
||||||
|
defer c.Close()
|
||||||
|
bio := bufio.NewReader(c)
|
||||||
|
|
||||||
|
for {
|
||||||
|
buf, err := bio.ReadBytes('\n')
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Notice("Error reading data from IPC client: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := string(buf)
|
||||||
|
|
||||||
|
if data[len(data)-1] == '\n' {
|
||||||
|
data = data[0:len(data)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if data == "dump" {
|
||||||
|
log.Notice("Dumping oz-firewall rule set to client...")
|
||||||
|
banner := fmt.Sprintf("There are a total of %d rule(s).\n", len(sandboxRules))
|
||||||
|
c.Write([]byte(banner))
|
||||||
|
|
||||||
|
for i := 0; i < len(sandboxRules); i++ {
|
||||||
|
rulestr := ""
|
||||||
|
|
||||||
|
if sandboxRules[i].Whitelist {
|
||||||
|
rulestr += "whitelist"
|
||||||
|
} else {
|
||||||
|
rulestr += "blacklist"
|
||||||
|
}
|
||||||
|
|
||||||
|
rulestr += " " + sandboxRules[i].SrcIf.String() + " -> " + sandboxRules[i].DstIP.String() + " : " + strconv.Itoa(int(sandboxRules[i].DstPort)) + "\n"
|
||||||
|
c.Write([]byte(rulestr))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
tokens := strings.Split(data, " ")
|
||||||
|
|
||||||
|
if len(tokens) != 5 {
|
||||||
|
log.Notice("IPC received invalid command: " + data)
|
||||||
|
c.Write([]byte("Received bad number of parameters.\n"))
|
||||||
|
return
|
||||||
|
} else if tokens[0] != "add" && tokens[0] != "remove" {
|
||||||
|
log.Notice("IPC received invalid command: " + data)
|
||||||
|
c.Write([]byte("Unrecognized command.\n"))
|
||||||
|
return
|
||||||
|
} else if tokens[1] != "whitelist" && tokens[1] != "blacklist" {
|
||||||
|
log.Notice("IPC received invalid command: " + data)
|
||||||
|
c.Write([]byte("Bad command: must specify either whitelist or blacklist.\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
add := true
|
||||||
|
|
||||||
|
if tokens[0] == "remove" {
|
||||||
|
add = false
|
||||||
|
}
|
||||||
|
|
||||||
|
w := true
|
||||||
|
|
||||||
|
if tokens[1] == "blacklist" {
|
||||||
|
w = false
|
||||||
|
}
|
||||||
|
|
||||||
|
srcip := net.ParseIP(tokens[2])
|
||||||
|
|
||||||
|
if srcip == nil {
|
||||||
|
log.Notice("IPC received invalid source host: ", tokens[2])
|
||||||
|
c.Write([]byte("Bad command: source host address was invalid"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dstip := net.ParseIP(tokens[3])
|
||||||
|
|
||||||
|
if dstip == nil {
|
||||||
|
log.Notice("IPC received invalid destination host: ", tokens[3])
|
||||||
|
c.Write([]byte("Bad command: dst host address was invalid"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dstport, err := strconv.Atoi(tokens[4])
|
||||||
|
|
||||||
|
if err != nil || dstport <= 0 || dstport > 65535 {
|
||||||
|
log.Notice("IPC received invalid destination port: ", tokens[4])
|
||||||
|
c.Write([]byte("Bad command: dst port was invalid"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rule := sandboxRule { srcip, dstip, uint16(dstport), w }
|
||||||
|
|
||||||
|
if add && !canAddRule(rule) {
|
||||||
|
log.Notice("Could not add rule of mismatching type: ", rule)
|
||||||
|
c.Write([]byte("Error: cannot add rule that would result in mixed whitelist and blacklist"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
exists := ruleExists(rule)
|
||||||
|
|
||||||
|
if add && exists != -1 {
|
||||||
|
log.Notice("IP received request to add existing rule: ", rule)
|
||||||
|
c.Write([]byte("Error: cannot add already existing rule"))
|
||||||
|
return
|
||||||
|
} else if !add && exists == -1 {
|
||||||
|
log.Notice("IP received request to remove non-existent rule: ", rule)
|
||||||
|
c.Write([]byte("Error: could not remove non-existent rule"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if add {
|
||||||
|
log.Notice("Adding new rule to oz sandbox/fw: ", rule)
|
||||||
|
sandboxRules = append(sandboxRules, rule)
|
||||||
|
} else {
|
||||||
|
log.Notice("Removing new rule from oz sandbox/fw: ", rule)
|
||||||
|
sandboxRules = append(sandboxRules[:exists], sandboxRules[exists+1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log.Notice("IPC received command: " + data)
|
||||||
|
c.Write([]byte("OK.\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func OzReceiver() {
|
||||||
|
log.Notice("XXX: dispatching oz receiver...")
|
||||||
|
os.Remove(ReceiverSocketPath)
|
||||||
|
lfd, err := net.Listen("unix", ReceiverSocketPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Could not open oz receiver socket:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
fd, err := lfd.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Could not accept receiver client:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
go ReceiverLoop(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue