Skip to content

Instantly share code, notes, and snippets.

@furusiyya
Created December 9, 2016 21:21
Show Gist options
  • Save furusiyya/36b54ca22352bf3a74304085888b61e2 to your computer and use it in GitHub Desktop.
Save furusiyya/36b54ca22352bf3a74304085888b61e2 to your computer and use it in GitHub Desktop.
I only track for NEW TCP events and log their (src ip, src port, dst port) in a non-blocking channel (FIFO queue). When tcp server receive packet, it compare its src ip and src port with channel entries and get destination port of matching one. Same I do udp server.
package glutton
import (
"bufio"
"bytes"
"os/exec"
"regexp"
)
const tcpRegExp = `\[\w+]\s+\w+\s+.+?src=(\d+\.\d+\.\d+\.\d+)\s+dst=(\d+\.\d+\.\d+\.\d+)\s+sport=(\d+)\s+dport=(\d+)\s+`
const udpRegExp = `\[(\w+)]\s+\w+\s+.+?src=(\d+\.\d+\.\d+\.\d+)\s+dst=(\d+\.\d+\.\d+\.\d+)\s+sport=(\d+)\s+dport=(\d+)\s+`
// MonitorTCPConnections monitors conntrack for TCP connections
func MonitorTCPConnections(channel *NonBlockingChan) {
args := []string{
"--buffer-size", "30000000",
"-E",
"-p", "tcp",
"-e", "NEW",
}
cmd := exec.Command("conntrack", args...)
stderrPipe, err := cmd.StderrPipe()
CheckError("", err)
go func() {
stderr := bufio.NewReader(stderrPipe)
for {
line, _, readErr := stderr.ReadLine()
println("[*]", string(line))
CheckError("", readErr)
}
}()
stdoutPipe, err := cmd.StdoutPipe()
CheckError("", err)
stdout := bufio.NewReader(stdoutPipe)
cmd.Start()
var buffer bytes.Buffer
for {
frag, isPrefix, err := stdout.ReadLine()
CheckError("", err)
buffer.Write(frag)
if !isPrefix {
line := buffer.String()
go func() {
re := regexp.MustCompile(tcpRegExp)
str := re.FindStringSubmatch(line)
channel.Send <- str
}()
buffer.Reset()
}
}
}
// MonitorUDPConnections monitors conntrack for UDP connections
func MonitorUDPConnections(channel *NonBlockingChan) {
args := []string{
"--buffer-size", "30000000",
"-E",
"-p", "udp",
"-e", "ALL",
}
cmd := exec.Command("conntrack", args...)
stderrPipe, err := cmd.StderrPipe()
CheckError("", err)
go func() {
stderr := bufio.NewReader(stderrPipe)
for {
line, _, readErr := stderr.ReadLine()
println("[*]", string(line))
CheckError("", readErr)
}
}()
stdoutPipe, err := cmd.StdoutPipe()
CheckError("", err)
stdout := bufio.NewReader(stdoutPipe)
cmd.Start()
var buffer bytes.Buffer
for {
frag, isPrefix, err := stdout.ReadLine()
CheckError("", err)
buffer.Write(frag)
if !isPrefix {
line := buffer.String()
go func() {
re := regexp.MustCompile(udpRegExp)
str := re.FindStringSubmatch(line)
channel.Send <- str
}()
buffer.Reset()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment