mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
commit
bc637c7269
4 changed files with 120 additions and 46 deletions
|
@ -30,51 +30,65 @@ type Connection struct {
|
||||||
|
|
||||||
func Parse(nfp netfilter.Packet) *Connection {
|
func Parse(nfp netfilter.Packet) *Connection {
|
||||||
ipLayer := nfp.Packet.Layer(layers.LayerTypeIPv4)
|
ipLayer := nfp.Packet.Layer(layers.LayerTypeIPv4)
|
||||||
if ipLayer == nil {
|
ipLayer6 := nfp.Packet.Layer(layers.LayerTypeIPv6)
|
||||||
|
if ipLayer == nil && ipLayer6 == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, ok := ipLayer.(*layers.IPv4)
|
if (ipLayer == nil) {
|
||||||
if ok == false || ip == nil {
|
ip, ok := ipLayer6.(*layers.IPv6)
|
||||||
return nil
|
if ok == false || ip == nil {
|
||||||
}
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// we're not interested in connections
|
// we're not interested in connections
|
||||||
// from/to the localhost interface
|
// from/to the localhost interface
|
||||||
if ip.SrcIP.IsLoopback() {
|
if ip.SrcIP.IsLoopback() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip multicast stuff
|
// skip multicast stuff
|
||||||
if ip.SrcIP.IsMulticast() || ip.DstIP.IsMulticast() {
|
if ip.SrcIP.IsMulticast() || ip.DstIP.IsMulticast() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip broadcasted stuff
|
con, err := NewConnection6(&nfp, ip)
|
||||||
// FIXME: this is ugly
|
if err != nil {
|
||||||
if ip.DstIP[3] == 0xff {
|
log.Debug("%s", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
} else if con == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return con
|
||||||
|
} else {
|
||||||
|
ip, ok := ipLayer.(*layers.IPv4)
|
||||||
|
if ok == false || ip == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
con, err := NewConnection(&nfp, ip)
|
// we're not interested in connections
|
||||||
if err != nil {
|
// from/to the localhost interface
|
||||||
log.Debug("%s", err)
|
if ip.SrcIP.IsLoopback() {
|
||||||
return nil
|
return nil
|
||||||
} else if con == nil {
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return con
|
// skip multicast stuff
|
||||||
|
if ip.SrcIP.IsMulticast() || ip.DstIP.IsMulticast() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
con, err := NewConnection(&nfp, ip)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("%s", err)
|
||||||
|
return nil
|
||||||
|
} else if con == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return con
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnection(nfp *netfilter.Packet, ip *layers.IPv4) (c *Connection, err error) {
|
func newConnectionImpl(nfp *netfilter.Packet, c *Connection) (cr *Connection, err error) {
|
||||||
c = &Connection{
|
|
||||||
SrcIP: ip.SrcIP,
|
|
||||||
DstIP: ip.DstIP,
|
|
||||||
DstHost: dns.HostOr(ip.DstIP, ip.DstIP.String()),
|
|
||||||
pkt: nfp,
|
|
||||||
}
|
|
||||||
|
|
||||||
// no errors but not enough info neither
|
// no errors but not enough info neither
|
||||||
if c.parseDirection() == false {
|
if c.parseDirection() == false {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -94,28 +108,57 @@ func NewConnection(nfp *netfilter.Packet, ip *layers.IPv4) (c *Connection, err e
|
||||||
return nil, fmt.Errorf("Could not find process by its pid %d for: %s", pid, c)
|
return nil, fmt.Errorf("Could not find process by its pid %d for: %s", pid, c)
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConnection(nfp *netfilter.Packet, ip *layers.IPv4) (c *Connection, err error) {
|
||||||
|
c = &Connection{
|
||||||
|
SrcIP: ip.SrcIP,
|
||||||
|
DstIP: ip.DstIP,
|
||||||
|
DstHost: dns.HostOr(ip.DstIP, ip.DstIP.String()),
|
||||||
|
pkt: nfp,
|
||||||
|
}
|
||||||
|
return newConnectionImpl(nfp, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConnection6(nfp *netfilter.Packet, ip *layers.IPv6) (c *Connection, err error) {
|
||||||
|
c = &Connection{
|
||||||
|
SrcIP: ip.SrcIP,
|
||||||
|
DstIP: ip.DstIP,
|
||||||
|
DstHost: dns.HostOr(ip.DstIP, ip.DstIP.String()),
|
||||||
|
pkt: nfp,
|
||||||
|
}
|
||||||
|
return newConnectionImpl(nfp, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Connection) parseDirection() bool {
|
func (c *Connection) parseDirection() bool {
|
||||||
|
ret := false
|
||||||
for _, layer := range c.pkt.Packet.Layers() {
|
for _, layer := range c.pkt.Packet.Layers() {
|
||||||
if layer.LayerType() == layers.LayerTypeTCP {
|
if layer.LayerType() == layers.LayerTypeTCP {
|
||||||
if tcp, ok := layer.(*layers.TCP); ok == true && tcp != nil {
|
if tcp, ok := layer.(*layers.TCP); ok == true && tcp != nil {
|
||||||
c.Protocol = "tcp"
|
c.Protocol = "tcp"
|
||||||
c.DstPort = int(tcp.DstPort)
|
c.DstPort = int(tcp.DstPort)
|
||||||
c.SrcPort = int(tcp.SrcPort)
|
c.SrcPort = int(tcp.SrcPort)
|
||||||
return true
|
ret = true
|
||||||
}
|
}
|
||||||
} else if layer.LayerType() == layers.LayerTypeUDP {
|
} else if layer.LayerType() == layers.LayerTypeUDP {
|
||||||
if udp, ok := layer.(*layers.UDP); ok == true && udp != nil {
|
if udp, ok := layer.(*layers.UDP); ok == true && udp != nil {
|
||||||
c.Protocol = "udp"
|
c.Protocol = "udp"
|
||||||
c.DstPort = int(udp.DstPort)
|
c.DstPort = int(udp.DstPort)
|
||||||
c.SrcPort = int(udp.SrcPort)
|
c.SrcPort = int(udp.SrcPort)
|
||||||
return true
|
ret = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
for _, layer := range c.pkt.Packet.Layers() {
|
||||||
|
if layer.LayerType() == layers.LayerTypeIPv6 {
|
||||||
|
if tcp, ok := layer.(*layers.IPv6); ok == true && tcp != nil {
|
||||||
|
c.Protocol += "6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Connection) To() string {
|
func (c *Connection) To() string {
|
||||||
|
|
|
@ -27,6 +27,8 @@ func RunRule(enable bool, rule []string) (err error) {
|
||||||
// fmt.Printf("iptables %s\n", rule)
|
// fmt.Printf("iptables %s\n", rule)
|
||||||
|
|
||||||
_, err = core.Exec("iptables", rule)
|
_, err = core.Exec("iptables", rule)
|
||||||
|
_, err = core.Exec("ip6tables", rule)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,6 @@ const (
|
||||||
|
|
||||||
NF_DEFAULT_QUEUE_SIZE uint32 = 4096
|
NF_DEFAULT_QUEUE_SIZE uint32 = 4096
|
||||||
NF_DEFAULT_PACKET_SIZE uint32 = 4096
|
NF_DEFAULT_PACKET_SIZE uint32 = 4096
|
||||||
|
|
||||||
ipv4version = 0x40
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -167,7 +165,7 @@ func go_callback(queueId C.int, data *C.uchar, length C.int, mark C.uint, idx ui
|
||||||
xdata := C.GoBytes(unsafe.Pointer(data), length)
|
xdata := C.GoBytes(unsafe.Pointer(data), length)
|
||||||
|
|
||||||
var packet gopacket.Packet
|
var packet gopacket.Packet
|
||||||
if xdata[0]&0xf0 == ipv4version {
|
if (xdata[0] >> 4) == 4 { // first 4 bits is the version
|
||||||
packet = gopacket.NewPacket(xdata, layers.LayerTypeIPv4, gopacketDecodeOptions)
|
packet = gopacket.NewPacket(xdata, layers.LayerTypeIPv4, gopacketDecodeOptions)
|
||||||
} else {
|
} else {
|
||||||
packet = gopacket.NewPacket(xdata, layers.LayerTypeIPv6, gopacketDecodeOptions)
|
packet = gopacket.NewPacket(xdata, layers.LayerTypeIPv6, gopacketDecodeOptions)
|
||||||
|
|
|
@ -16,8 +16,8 @@ import (
|
||||||
var (
|
var (
|
||||||
parser = regexp.MustCompile(`(?i)` +
|
parser = regexp.MustCompile(`(?i)` +
|
||||||
`\d+:\s+` + // sl
|
`\d+:\s+` + // sl
|
||||||
`([a-f0-9]{8}):([a-f0-9]{4})\s+` + // local_address
|
`([a-f0-9]{8,32}):([a-f0-9]{4})\s+` + // local_address
|
||||||
`([a-f0-9]{8}):([a-f0-9]{4})\s+` + // rem_address
|
`([a-f0-9]{8,32}):([a-f0-9]{4})\s+` + // rem_address
|
||||||
`[a-f0-9]{2}\s+` + // st
|
`[a-f0-9]{2}\s+` + // st
|
||||||
`[a-f0-9]{8}:[a-f0-9]{8}\s+` + // tx_queue rx_queue
|
`[a-f0-9]{8}:[a-f0-9]{8}\s+` + // tx_queue rx_queue
|
||||||
`[a-f0-9]{2}:[a-f0-9]{8}\s+` + // tr tm->when
|
`[a-f0-9]{2}:[a-f0-9]{8}\s+` + // tr tm->when
|
||||||
|
@ -44,10 +44,41 @@ func hexToInt(h string) int {
|
||||||
return int(d)
|
return int(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func hexToInt2(h string) (int, int) {
|
||||||
|
if len(h) > 16 {
|
||||||
|
d, err := strconv.ParseInt(h[:16], 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error while parsing %s to int: %s", h[16:], err)
|
||||||
|
}
|
||||||
|
d2, err := strconv.ParseInt(h[16:], 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error while parsing %s to int: %s", h[16:], err)
|
||||||
|
}
|
||||||
|
return int(d), int(d2)
|
||||||
|
} else {
|
||||||
|
d, err := strconv.ParseInt(h, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error while parsing %s to int: %s", h[16:], err)
|
||||||
|
}
|
||||||
|
return int(d), 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func hexToIP(h string) net.IP {
|
func hexToIP(h string) net.IP {
|
||||||
n := hexToInt(h)
|
n, m := hexToInt2(h)
|
||||||
ip := make(net.IP, 4)
|
var ip net.IP
|
||||||
binary.LittleEndian.PutUint32(ip, uint32(n))
|
if m != 0 {
|
||||||
|
ip = make(net.IP, 16)
|
||||||
|
// TODO: Check if this depends on machine endianness?
|
||||||
|
binary.LittleEndian.PutUint32(ip, uint32(n >> 32))
|
||||||
|
binary.LittleEndian.PutUint32(ip[4:], uint32(n))
|
||||||
|
binary.LittleEndian.PutUint32(ip[8:], uint32(m >> 32))
|
||||||
|
binary.LittleEndian.PutUint32(ip[12:], uint32(m))
|
||||||
|
} else {
|
||||||
|
ip = make(net.IP, 4)
|
||||||
|
binary.LittleEndian.PutUint32(ip, uint32(n))
|
||||||
|
}
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue