Updated go binary
This commit is contained in:
@@ -4,4 +4,7 @@ go 1.18
|
|||||||
|
|
||||||
require github.com/DomySh/go-netfilter-queue v0.0.0-20220713124014-7261f0df2c15
|
require github.com/DomySh/go-netfilter-queue v0.0.0-20220713124014-7261f0df2c15
|
||||||
|
|
||||||
require github.com/google/gopacket v1.1.19 // indirect
|
require (
|
||||||
|
github.com/Jemmic/go-pcre2 v0.0.0-20190111114109-bd52ad5f7098 // indirect
|
||||||
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
github.com/DomySh/go-netfilter-queue v0.0.0-20220713124014-7261f0df2c15 h1:6v9D8bG3oR0dJFMuEeEAg8Xwn436Ziv+P7QWS04wAG8=
|
github.com/DomySh/go-netfilter-queue v0.0.0-20220713124014-7261f0df2c15 h1:6v9D8bG3oR0dJFMuEeEAg8Xwn436Ziv+P7QWS04wAG8=
|
||||||
github.com/DomySh/go-netfilter-queue v0.0.0-20220713124014-7261f0df2c15/go.mod h1:VdJ6kqHln0XlrhuxQM6eBjRIHCzvAMgcZDAtyD/GU5s=
|
github.com/DomySh/go-netfilter-queue v0.0.0-20220713124014-7261f0df2c15/go.mod h1:VdJ6kqHln0XlrhuxQM6eBjRIHCzvAMgcZDAtyD/GU5s=
|
||||||
|
github.com/Jemmic/go-pcre2 v0.0.0-20190111114109-bd52ad5f7098 h1:ZwFIi+5jGJWVrB2V4NvrEhIUy6uDkfnTtBsgj3HAImI=
|
||||||
|
github.com/Jemmic/go-pcre2 v0.0.0-20190111114109-bd52ad5f7098/go.mod h1:c+8WT1L7lfohb4xMaa3yAV7nlYNepqc2ZV09/CU8R/U=
|
||||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
|||||||
@@ -2,25 +2,98 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/DomySh/go-netfilter-queue"
|
"github.com/DomySh/go-netfilter-queue"
|
||||||
|
"github.com/Jemmic/go-pcre2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const QUEUE_BASE_NUM = 1000
|
const QUEUE_BASE_NUM = 1000
|
||||||
const MAX_PACKET_IN_QUEUE = 100
|
const MAX_PACKET_IN_QUEUE = 100
|
||||||
|
|
||||||
func handle_packets(packets <-chan netfilter.NFPacket) {
|
var FILTER_TABLE *regex_filters = ®ex_filters{}
|
||||||
for true {
|
|
||||||
select {
|
type regex_filters struct {
|
||||||
case p := <-packets:
|
input_whitelist []*pcre2.Matcher
|
||||||
//fmt.Println(p.Packet)
|
input_blacklist []*pcre2.Matcher
|
||||||
p.SetVerdict(netfilter.NF_ACCEPT)
|
output_whitelist []*pcre2.Matcher
|
||||||
|
output_blacklist []*pcre2.Matcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self regex_filters) add(raw_regex string) {
|
||||||
|
filter_type := strings.ToLower(raw_regex[0:2])
|
||||||
|
|
||||||
|
decoded_regex, err := hex.DecodeString(raw_regex[2:])
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[add] Unable to decode regex '%s': %s", raw_regex, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regex, err := pcre2.Compile(string(decoded_regex), 0)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[add] Unable to compile regex '%s': %s", string(decoded_regex), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if filter_type[0] == 'i' {
|
||||||
|
if filter_type[1] == '0' {
|
||||||
|
self.input_whitelist = append(self.input_whitelist, regex.NewMatcher())
|
||||||
|
} else {
|
||||||
|
self.input_blacklist = append(self.input_blacklist, regex.NewMatcher())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if filter_type[1] == '0' {
|
||||||
|
self.output_whitelist = append(self.output_whitelist, regex.NewMatcher())
|
||||||
|
} else {
|
||||||
|
self.output_blacklist = append(self.output_blacklist, regex.NewMatcher())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self regex_filters) check(data []byte, is_input bool) bool {
|
||||||
|
if is_input {
|
||||||
|
for _, matcher := range self.input_blacklist {
|
||||||
|
if matcher.Match(data, 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, matcher := range self.input_whitelist {
|
||||||
|
if !matcher.Match(data, 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, matcher := range self.output_blacklist {
|
||||||
|
if matcher.Match(data, 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, matcher := range self.output_whitelist {
|
||||||
|
if !matcher.Match(data, 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func handle_packets(packets <-chan netfilter.NFPacket, is_input bool) {
|
||||||
|
for true {
|
||||||
|
filter := FILTER_TABLE
|
||||||
|
p := <-packets
|
||||||
|
log.Printf("Packet received: %s input: %t", p.Packet.TransportLayer().LayerPayload(), is_input)
|
||||||
|
if filter.check(p.Packet.TransportLayer().LayerPayload(), is_input) {
|
||||||
|
p.SetVerdict(netfilter.NF_ACCEPT)
|
||||||
|
} else {
|
||||||
|
log.Printf("Refused packet: %s", p.Packet.TransportLayer().LayerPayload())
|
||||||
|
p.SetVerdict(netfilter.NF_DROP)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,21 +105,6 @@ func isRoot() bool {
|
|||||||
return currentUser.Username == "root"
|
return currentUser.Username == "root"
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
starts = QUEUE_BASE_NUM
|
|
||||||
while True:
|
|
||||||
if starts >= 65536:
|
|
||||||
raise Exception("Netfilter queue is full!")
|
|
||||||
queue_ids = list(range(starts,starts+n_threads))
|
|
||||||
try:
|
|
||||||
ictor.start(func_wrap, queue_ids=queue_ids)
|
|
||||||
break
|
|
||||||
except interceptor.UnableToBindException as e:
|
|
||||||
starts = e.queue_id + 1
|
|
||||||
return ictor, (starts, starts+n_threads-1)
|
|
||||||
|
|
||||||
*/
|
|
||||||
func create_queue_seq(num int) ([]*netfilter.NFQueue, int, int) {
|
func create_queue_seq(num int) ([]*netfilter.NFQueue, int, int) {
|
||||||
var queue_list = make([]*netfilter.NFQueue, num)
|
var queue_list = make([]*netfilter.NFQueue, num)
|
||||||
var err error
|
var err error
|
||||||
@@ -54,7 +112,6 @@ func create_queue_seq(num int) ([]*netfilter.NFQueue, int, int) {
|
|||||||
for queue_list[0] == nil {
|
for queue_list[0] == nil {
|
||||||
if starts+num-1 >= 65536 {
|
if starts+num-1 >= 65536 {
|
||||||
log.Fatalf("Netfilter queue is full!")
|
log.Fatalf("Netfilter queue is full!")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
for i := 0; i < len(queue_list); i++ {
|
for i := 0; i < len(queue_list); i++ {
|
||||||
queue_list[i], err = netfilter.NewNFQueue(uint16(starts+num-1-i), MAX_PACKET_IN_QUEUE, netfilter.NF_DEFAULT_PACKET_SIZE)
|
queue_list[i], err = netfilter.NewNFQueue(uint16(starts+num-1-i), MAX_PACKET_IN_QUEUE, netfilter.NF_DEFAULT_PACKET_SIZE)
|
||||||
@@ -73,9 +130,9 @@ func create_queue_seq(num int) ([]*netfilter.NFQueue, int, int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
if !isRoot() {
|
if !isRoot() {
|
||||||
log.Fatalf("[main] You must be root to run this program")
|
log.Fatalf("[main] You must be root to run this program")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
number_of_queues := 1
|
number_of_queues := 1
|
||||||
@@ -85,7 +142,6 @@ func main() {
|
|||||||
number_of_queues, err = strconv.Atoi(os.Args[1])
|
number_of_queues, err = strconv.Atoi(os.Args[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("[main] Invalid number of queues: %s", err)
|
log.Fatalf("[main] Invalid number of queues: %s", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,13 +149,13 @@ func main() {
|
|||||||
queue_list, starts_input, end_input := create_queue_seq(number_of_queues)
|
queue_list, starts_input, end_input := create_queue_seq(number_of_queues)
|
||||||
for _, queue := range queue_list {
|
for _, queue := range queue_list {
|
||||||
defer queue.Close()
|
defer queue.Close()
|
||||||
go handle_packets(queue.GetPackets())
|
go handle_packets(queue.GetPackets(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_list, starts_output, end_output := create_queue_seq(number_of_queues)
|
queue_list, starts_output, end_output := create_queue_seq(number_of_queues)
|
||||||
for _, queue := range queue_list {
|
for _, queue := range queue_list {
|
||||||
defer queue.Close()
|
defer queue.Close()
|
||||||
go handle_packets(queue.GetPackets())
|
go handle_packets(queue.GetPackets(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("QUEUE INPUT", starts_input, end_input, "OUTPUT", starts_output, end_output)
|
fmt.Println("QUEUE INPUT", starts_input, end_input, "OUTPUT", starts_output, end_output)
|
||||||
@@ -108,10 +164,22 @@ func main() {
|
|||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
for true {
|
for true {
|
||||||
text, err := reader.ReadString('\n')
|
text, err := reader.ReadString('\n')
|
||||||
|
log.Printf("[main] Regex rule updating...")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("[main] Unable to read from stdin: %s", err)
|
log.Fatalf("[main] Unable to read from stdin: %s", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
fmt.Print(text)
|
text = strings.Trim(text, "\n")
|
||||||
|
regexes := strings.Split(text, " ")
|
||||||
|
|
||||||
|
new_filters := regex_filters{}
|
||||||
|
for _, regex := range regexes {
|
||||||
|
regex = strings.Trim(regex, " ")
|
||||||
|
if len(regex) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
new_filters.add(regex)
|
||||||
|
}
|
||||||
|
FILTER_TABLE = &new_filters
|
||||||
|
log.Printf("[main] Regex filter rules updated!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user