Proper logging of all connections denied by firewall.

fw-daemon now also forces logging to syslog if launched from a terminal.
shw_dev
shw 8 years ago
parent e895f204a7
commit 0708f9127c

@ -4,6 +4,7 @@ import (
"os" "os"
"syscall" "syscall"
"unsafe" "unsafe"
"fmt"
"github.com/op/go-logging" "github.com/op/go-logging"
) )
@ -43,14 +44,25 @@ func isTerminal(fd int) bool {
return err == 0 return err == 0
} }
func setupLoggerBackend(lvl logging.Level) logging.LeveledBackend { func setupLoggerBackend(lvl logging.Level) (logging.LeveledBackend, logging.LeveledBackend) {
format := logFormat format := logFormat
sleveler := logging.LeveledBackend(nil)
if isTerminal(int(os.Stderr.Fd())) { if isTerminal(int(os.Stderr.Fd())) {
format = ttyFormat format = ttyFormat
fmt.Fprintf(os.Stderr, "Program was launched from a terminal; forcing output to syslog.\n")
sbackend, err := logging.NewSyslogBackend("sgfw")
if err != nil {
log.Error("Could not open syslog backend for logging: %v", err)
} else {
sformatter := logging.NewBackendFormatter(sbackend, logFormat)
sleveler = logging.AddModuleLevel(sformatter)
sleveler.SetLevel(lvl, "sgfw")
}
} }
backend := logging.NewLogBackend(os.Stderr, "", 0) backend := logging.NewLogBackend(os.Stderr, "", 0)
formatter := logging.NewBackendFormatter(backend, format) formatter := logging.NewBackendFormatter(backend, format)
leveler := logging.AddModuleLevel(formatter) leveler := logging.AddModuleLevel(formatter)
leveler.SetLevel(lvl, "sgfw") leveler.SetLevel(lvl, "sgfw")
return leveler return leveler, sleveler
} }

@ -3,6 +3,7 @@ package sgfw
import ( import (
"fmt" "fmt"
"strings" "strings"
"strconv"
"sync" "sync"
// "encoding/binary" // "encoding/binary"
@ -41,6 +42,7 @@ type pendingConnection interface {
hostname() string hostname() string
getOptString() string getOptString() string
src() net.IP src() net.IP
srcPort() uint16
dst() net.IP dst() net.IP
dstPort() uint16 dstPort() uint16
accept() accept()
@ -105,6 +107,11 @@ func (pp *pendingPkt) dst() net.IP {
// pp.pkt.NetworkLayer().Layer // pp.pkt.NetworkLayer().Layer
} }
func (pp *pendingPkt) srcPort() uint16 {
srcp, _ := getPacketTCPPorts(pp.pkt)
return srcp
}
func (pp *pendingPkt) dstPort() uint16 { func (pp *pendingPkt) dstPort() uint16 {
/* dst := pp.pkt.Packet.TransportLayer().TransportFlow().Dst() /* dst := pp.pkt.Packet.TransportLayer().TransportFlow().Dst()
@ -293,6 +300,9 @@ func (p *Policy) filterPending(rule *Rule) {
if rule.rtype == RULE_ACTION_ALLOW { if rule.rtype == RULE_ACTION_ALLOW {
pc.accept() pc.accept()
} else { } else {
srcs := pc.src().String() + ":" + strconv.Itoa(int(pc.srcPort()))
log.Warningf("DENIED outgoing connection attempt by %s from %s %s -> %s:%d (user prompt)",
pc.procInfo().ExePath, "TCP", srcs, pc.dst(), pc.dstPort)
pc.drop() pc.drop()
} }
} else { } else {

@ -127,6 +127,10 @@ log.Notice("+ MATCH SUCCEEDED")
srcStr, srcStr,
dstStr, dstPort) dstStr, dstPort)
if r.rtype == RULE_ACTION_DENY { if r.rtype == RULE_ACTION_DENY {
log.Warningf("DENIED outgoing connection attempt by %s from %s %s -> %s:%d",
pinfo.ExePath, "TCP",
srcStr,
dstStr, dstPort)
return FILTER_DENY return FILTER_DENY
} else if r.rtype == RULE_ACTION_ALLOW { } else if r.rtype == RULE_ACTION_ALLOW {
result = FILTER_ALLOW result = FILTER_ALLOW

@ -173,8 +173,14 @@ func getSocksChainConfig(config *SocksJsonConfig) *socksChainConfig {
func Main() { func Main() {
readConfig() readConfig()
logBackend := setupLoggerBackend(FirewallConfig.LoggingLevel) logBackend, logBackend2 := setupLoggerBackend(FirewallConfig.LoggingLevel)
log.SetBackend(logBackend)
if logBackend2 == nil {
logging.SetBackend(logBackend)
} else {
logging.SetBackend(logBackend, logBackend2)
}
procsnitch.SetLogger(log) procsnitch.SetLogger(log)
if os.Geteuid() != 0 { if os.Geteuid() != 0 {

@ -7,6 +7,7 @@ import (
"sync" "sync"
"github.com/subgraph/go-procsnitch" "github.com/subgraph/go-procsnitch"
"strings"
"strconv" "strconv"
) )
@ -46,6 +47,7 @@ type pendingSocksConnection struct {
hname string hname string
srcIP net.IP srcIP net.IP
destIP net.IP destIP net.IP
sourcePort uint16
destPort uint16 destPort uint16
pinfo *procsnitch.Info pinfo *procsnitch.Info
verdict chan int verdict chan int
@ -70,6 +72,9 @@ func (sc *pendingSocksConnection) hostname() string {
func (sc *pendingSocksConnection) dst() net.IP { func (sc *pendingSocksConnection) dst() net.IP {
return sc.destIP return sc.destIP
} }
func (sc *pendingSocksConnection) srcPort() uint16 {
return sc.sourcePort
}
func (sc *pendingSocksConnection) dstPort() uint16 { func (sc *pendingSocksConnection) dstPort() uint16 {
return sc.destPort return sc.destPort
} }
@ -204,11 +209,38 @@ func (c *socksChainSession) filterConnect() bool {
case FILTER_ALLOW: case FILTER_ALLOW:
return true return true
case FILTER_PROMPT: case FILTER_PROMPT:
caddr := c.clientConn.RemoteAddr().String()
caddrt := strings.Split(caddr, ":")
caddrIP := net.IP{0,0,0,0}
caddrPort := uint16(0)
if len(caddrt) != 2 {
log.Errorf("Error reading peer information from SOCKS client connection")
} else {
srcp, err := strconv.Atoi(caddrt[1])
if err != nil || srcp <= 0 || srcp > 65535 {
log.Errorf("Error getting port of SOCKS client connection")
} else {
caddrPort = uint16(srcp)
ip := net.ParseIP(caddrt[0])
if ip == nil {
log.Errorf("Error getting host IP of SOCKS5 client connection: %v", err)
} else {
caddrIP = ip
}
}
}
pending := &pendingSocksConnection{ pending := &pendingSocksConnection{
pol: policy, pol: policy,
hname: hostname, hname: hostname,
destIP: ip, destIP: ip,
srcIP: net.IP{0,0,0,0}, srcIP: caddrIP,
sourcePort: caddrPort,
destPort: port, destPort: port,
pinfo: pinfo, pinfo: pinfo,
verdict: make(chan int), verdict: make(chan int),

Loading…
Cancel
Save