first version
This commit is contained in:
67
cmd/kf2-antiddos/args.go
Normal file
67
cmd/kf2-antiddos/args.go
Normal file
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/juju/gnuflag"
|
||||
|
||||
"kf2-antiddos/internal/config"
|
||||
"kf2-antiddos/internal/output"
|
||||
)
|
||||
|
||||
func printHelp() {
|
||||
output.Println("Anti DDoS tool for kf2 servers")
|
||||
output.Println("")
|
||||
output.Printf("Usage: <kf2_logs_output> | %s [option]... <shell> <deny_script> <allow_script>", AppName)
|
||||
output.Println("kf2_logs_output KF2 logs to redirect to stdin")
|
||||
output.Println("shell shell to run deny_script and allow_script")
|
||||
output.Println("deny_script firewall deny script (takes IP as argument)")
|
||||
output.Println("allow_script firewall allow script (takes IPs as arguments)")
|
||||
output.Println("")
|
||||
output.Println("Options:")
|
||||
output.Println(" -j, --jobs N allow N jobs at once")
|
||||
output.Println(" -o, --output MODE self|proxy|all|quiet")
|
||||
output.Println(" -dt, --deny-time TIME minimum ip deny TIME (seconds)")
|
||||
output.Println(" -mc, --max-connections N Skip N connections before run deny script")
|
||||
output.Println(" -v, --version Show version")
|
||||
output.Println(" -h, --help Show help")
|
||||
}
|
||||
|
||||
func printVersion() {
|
||||
output.Printf("%s %s", AppName, AppVersion)
|
||||
}
|
||||
|
||||
func parseArgs() config.Config {
|
||||
rawCfg := config.Config{}
|
||||
|
||||
gnuflag.UintVar(&rawCfg.Jobs, "j", 0, "")
|
||||
gnuflag.UintVar(&rawCfg.Jobs, "jobs", 0, "")
|
||||
|
||||
gnuflag.StringVar(&rawCfg.OutputMode, "o", "", "")
|
||||
gnuflag.StringVar(&rawCfg.OutputMode, "output", "", "")
|
||||
|
||||
gnuflag.UintVar(&rawCfg.DenyTime, "dt", 0, "")
|
||||
gnuflag.UintVar(&rawCfg.DenyTime, "deny-time", 0, "")
|
||||
|
||||
gnuflag.UintVar(&rawCfg.MaxConn, "mc", 0, "")
|
||||
gnuflag.UintVar(&rawCfg.MaxConn, "max-connections", 0, "")
|
||||
|
||||
gnuflag.BoolVar(&rawCfg.ShowVersion, "v", false, "")
|
||||
gnuflag.BoolVar(&rawCfg.ShowVersion, "version", false, "")
|
||||
|
||||
gnuflag.BoolVar(&rawCfg.ShowHelp, "h", false, "")
|
||||
gnuflag.BoolVar(&rawCfg.ShowHelp, "help", false, "")
|
||||
|
||||
gnuflag.Parse(true)
|
||||
|
||||
for i := 0; i < 3 && i < gnuflag.NArg(); i++ {
|
||||
switch i {
|
||||
case 0:
|
||||
rawCfg.Shell = gnuflag.Arg(i)
|
||||
case 1:
|
||||
rawCfg.DenyAction = gnuflag.Arg(i)
|
||||
case 2:
|
||||
rawCfg.AllowAction = gnuflag.Arg(i)
|
||||
}
|
||||
}
|
||||
|
||||
return rawCfg
|
||||
}
|
140
cmd/kf2-antiddos/main.go
Normal file
140
cmd/kf2-antiddos/main.go
Normal file
@ -0,0 +1,140 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"kf2-antiddos/internal/action"
|
||||
"kf2-antiddos/internal/common"
|
||||
"kf2-antiddos/internal/config"
|
||||
"kf2-antiddos/internal/history"
|
||||
"kf2-antiddos/internal/output"
|
||||
"kf2-antiddos/internal/parser"
|
||||
"kf2-antiddos/internal/reader"
|
||||
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
ExitSuccess int = 0
|
||||
ExitArgError int = 1
|
||||
)
|
||||
|
||||
const (
|
||||
AppName = "kf2-antiddos"
|
||||
)
|
||||
|
||||
var (
|
||||
AppVersion string = "dev"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := parseArgs()
|
||||
|
||||
switch {
|
||||
case cfg.ShowHelp:
|
||||
printHelp()
|
||||
os.Exit(ExitSuccess)
|
||||
case cfg.ShowVersion:
|
||||
printVersion()
|
||||
os.Exit(ExitSuccess)
|
||||
}
|
||||
|
||||
if cfg.IsValid() {
|
||||
cfg.SetEmptyArgs()
|
||||
} else {
|
||||
os.Exit(ExitArgError)
|
||||
}
|
||||
|
||||
switch cfg.OutputMode {
|
||||
case config.OT_All:
|
||||
output.AllMode()
|
||||
case config.OT_Proxy:
|
||||
output.ProxyMode()
|
||||
case config.OT_Quiet:
|
||||
output.QuietMode()
|
||||
case config.OT_Self:
|
||||
output.SelfMode()
|
||||
}
|
||||
|
||||
runtime.GOMAXPROCS(int(cfg.Jobs))
|
||||
|
||||
Workers := make([]common.Worker, 0, cfg.Jobs+3)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
// Data flow:
|
||||
banChan := make(chan string, cfg.Jobs)
|
||||
inputChan := make(chan common.RawEvent, cfg.Jobs)
|
||||
eventChan := make(chan common.Event, cfg.Jobs)
|
||||
resetChan := make(chan string, cfg.Jobs)
|
||||
|
||||
// Reader worker
|
||||
Workers = append(Workers,
|
||||
reader.New(
|
||||
uint(len(Workers)),
|
||||
&inputChan,
|
||||
))
|
||||
|
||||
// parser workers
|
||||
for i := uint(0); i < cfg.Jobs; i++ {
|
||||
Workers = append(Workers,
|
||||
parser.New(
|
||||
uint(len(Workers)),
|
||||
&inputChan,
|
||||
&eventChan,
|
||||
))
|
||||
}
|
||||
|
||||
// History worker
|
||||
Workers = append(Workers,
|
||||
history.New(
|
||||
uint(len(Workers)),
|
||||
&eventChan,
|
||||
&banChan,
|
||||
&resetChan,
|
||||
cfg.MaxConn,
|
||||
))
|
||||
|
||||
// Action worker
|
||||
Workers = append(Workers,
|
||||
action.New(
|
||||
uint(len(Workers)),
|
||||
cfg.DenyTime,
|
||||
cfg.Shell,
|
||||
cfg.AllowAction,
|
||||
cfg.DenyAction,
|
||||
&banChan,
|
||||
&resetChan,
|
||||
))
|
||||
|
||||
wg.Add(len(Workers))
|
||||
|
||||
closeHandler(Workers, &wg)
|
||||
|
||||
for i := range Workers {
|
||||
Workers[i].Do()
|
||||
}
|
||||
|
||||
output.Println("started")
|
||||
|
||||
wg.Wait()
|
||||
|
||||
output.Println("exit")
|
||||
|
||||
os.Exit(ExitSuccess)
|
||||
}
|
||||
|
||||
func closeHandler(Workers []common.Worker, wg *sync.WaitGroup) {
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||
go func() {
|
||||
<-interrupt
|
||||
output.Println("interrupt")
|
||||
for _, worker := range Workers {
|
||||
worker.Stop()
|
||||
wg.Done()
|
||||
}
|
||||
}()
|
||||
}
|
Reference in New Issue
Block a user