Skip to content

Commit

Permalink
Merge pull request #28 from Esonhugh feat
Browse files Browse the repository at this point in the history
Multi Update!
  • Loading branch information
Esonhugh authored Jan 13, 2025
2 parents 587470e + e8d1cd2 commit fdec346
Show file tree
Hide file tree
Showing 24 changed files with 656 additions and 300 deletions.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ default: build build-static check-size
build:
go build -o $(BUILD_DIR)/$(MAIN_PROGRAM_NAME) main.go

test: build
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) all --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) axfr --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) dns --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) dnssd --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) dnssd ptr --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) dnssd srv --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) metric --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) neighbor --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) neighbor pod --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) neighbor svc --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) whereisdns --help
$(BUILD_DIR)/$(MAIN_PROGRAM_NAME) wild --help

build-static:
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o $(BUILD_DIR)/$(MAIN_PROGRAM_NAME)-linux-static main.go
upx --lzma --brute $(BUILD_DIR)/$(MAIN_PROGRAM_NAME)-linux-static
Expand Down
29 changes: 24 additions & 5 deletions cmd/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package all

import (
"net"
"strings"

command "github.com/esonhugh/k8spider/cmd"
"github.com/esonhugh/k8spider/define"
Expand Down Expand Up @@ -42,38 +43,51 @@ var AllCmd = &cobra.Command{
} else {
log.Errorf("Transfer failed: %v", err)
}

// Service Discovery
ipNets, err := pkg.ParseStringToIPNet(command.Opts.Cidr)
if err != nil {
log.Warnf("ParseStringToIPNet failed: %v", err)
return
}
podNets, err := pkg.ParseStringToIPNet(command.Opts.PodCidr)
if err != nil {
log.Warnf("ParseStringToIPNet failed: %v", err)
return
}

var finalRecord define.Records
if command.Opts.MultiThreadingMode {
finalRecord = RunMultiThread(ipNets, command.Opts.ThreadingNum)
finalRecord = RunMultiThread(ipNets, podNets, command.Opts.ThreadingNum)
} else {
finalRecord = Run(ipNets)
finalRecord = Run(ipNets, podNets)
}
printer.PrintResult(finalRecord, command.Opts.OutputFile)

PostRun(finalRecord)
},
}

func Run(net *net.IPNet) (finalRecord define.Records) {
func Run(net, pod *net.IPNet) (finalRecord define.Records) {
var records define.Records = scanner.ScanSubnet(net)
if records == nil || len(records) == 0 {
log.Warnf("ScanSubnet Found Nothing")
return
}
records = scanner.ScanSvcForPorts(records)
for r := range mutli.ScanNeighborSvc(pod, 1) {
finalRecord = append(finalRecord, r...)
}
return records
}

func RunMultiThread(net *net.IPNet, count int) (finalRecord define.Records) {
func RunMultiThread(net, pod *net.IPNet, count int) (finalRecord define.Records) {
scan := mutli.ScanAll(net, count)
for r := range scan {
scan2 := mutli.ScanNeighborSvc(pod, count)
select {
case r := <-scan:
finalRecord = append(finalRecord, r...)
case r := <-scan2:
finalRecord = append(finalRecord, r...)
}
return
Expand All @@ -93,4 +107,9 @@ func PostRun(finalRecord define.Records) {
for _, svc := range list {
log.Infof("Service: %s", svc)
}
log.Info("Possible Pod and service ip maps")
maps := post.PodServiceMap(finalRecord)
for svc, ips := range maps {
log.Infof("service %s has ips %s", svc, strings.Join(ips, ","))
}
}
4 changes: 2 additions & 2 deletions cmd/dnsutils/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
var queryType string

func init() {
DNSCmd.PersistentFlags().StringVarP(&queryType, "type", "t", "A", "query type")
DNSCmd.PersistentFlags().StringVarP(&queryType, "type", "x", "A", "query type")
command.RootCmd.AddCommand(DNSCmd)
}

Expand Down Expand Up @@ -40,7 +40,7 @@ var DNSCmd = &cobra.Command{
log.Warnf("Query %s failed: %v", query, err)
continue
}
log.Infof("Query [%d] %s: %v", queryType, query, res)
log.Infof("Query [%s] %s: %v", queryType, query, res)
}
},
}
102 changes: 52 additions & 50 deletions cmd/metrics/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,75 +8,77 @@ import (
"strings"

cmdx "github.com/esonhugh/k8spider/cmd"
"github.com/esonhugh/k8spider/define"
"github.com/esonhugh/k8spider/pkg/metrics"
"github.com/esonhugh/k8spider/pkg/metrics/coredns"
kube_state_metrics "github.com/esonhugh/k8spider/pkg/metrics/kube-state-metrics"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

var MetricOpt struct {
From string
}

func init() {
cmdx.RootCmd.AddCommand(MetricCmd)
MetricCmd.PersistentFlags().StringVarP(&MetricOpt.From, "metric", "m", "", "metrics from (file / remote url)")

cmdx.RootCmd.AddCommand(MetricsCmd)
}

var MetricCmd = &cobra.Command{
Use: "metric",
Short: "parse kube stat metrics to readable resource",
var MetricsCmd = &cobra.Command{
Use: "metrics",
Short: "parse kube stat metrics to readable resource, use: k8spider metrics <file/url> <file/url> ...",
Run: func(cmd *cobra.Command, args []string) {
if MetricOpt.From == "" {
if len(args) != 1 {
cmd.Help()
return
}
log.Debugf("parse metrics from %v", MetricOpt.From)
rule := metrics.DefaultMatchRules()
if err := rule.Compile(); err != nil {
log.Fatalf("compile rule failed: %v", err)
}
log.Debugf("compiled rules completed, start to get resource \n")

ot := output()

var r io.Reader
if strings.HasPrefix("http://", MetricOpt.From) || strings.HasPrefix("https://", MetricOpt.From) {
resp, err := http.Get(MetricOpt.From)
if err != nil {
log.Fatalf("get metrics from %v failed: %v", MetricOpt.From, err)
}
defer resp.Body.Close()
r = resp.Body
} else {
f, err := os.OpenFile(MetricOpt.From, os.O_RDONLY, 0666)
if err != nil {
log.Fatalf("open file %v failed: %v", MetricOpt.From, err)
for _, From := range args {
log.Debugf("parse metrics from %v", From)
rule := append(kube_state_metrics.DefaultMatchRules(), coredns.CoreDNSMatchRules()...)
if err := rule.Compile(); err != nil {
log.Fatalf("compile rule failed: %v", err)
}
defer f.Close()
r = f
}
log.Debugf("start to parse metrics line by line\n")
log.Debugf("compiled rules completed, start to get resource \n")

var rx []*metrics.MetricMatcher
ot := output()

scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
res, err := rule.Match(line)
if err != nil {
continue
var r io.Reader
if strings.HasPrefix("http://", From) || strings.HasPrefix("https://", From) {
resp, err := http.Get(From)
if err != nil {
log.Fatalf("get metrics from %v failed: %v", From, err)
}
defer resp.Body.Close()
r = resp.Body
} else {
log.Debugf("matched: %s", res.DumpString())
rx = append(rx, res.CopyData())
f, err := os.OpenFile(From, os.O_RDONLY, 0666)
if err != nil {
log.Fatalf("open file %v failed: %v", From, err)
}
defer f.Close()
r = f
}
log.Debugf("start to parse metrics line by line\n")

var rx []*metrics.MetricMatcher

scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
res, err := rule.Match(line)
if err != nil {
continue
} else {
log.Debugf("matched: %s", res.DumpString())
rx = append(rx, res)
}
}
if err := scanner.Err(); err != nil {
log.Warnf("scan metrics failed and break out, reason: %v", err)
}
var res define.ResourceList = metrics.ConvertToResource(rx)
log.Debugf("parse metrics completed, start to print result\n")

res.Print(ot)
}
if err := scanner.Err(); err != nil {
log.Warnf("scan metrics failed and break out, reason: %v", err)
}
var res metrics.ResourceList = metrics.ConvertToResource(rx)
log.Debugf("parse metrics completed, start to print result\n")

res.Print(ot)
},
}

Expand Down
64 changes: 40 additions & 24 deletions cmd/neighbor/neighbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package neighbor

import (
"bufio"
"fmt"
"net"
"os"
"strings"

cmdx "github.com/esonhugh/k8spider/cmd"
"github.com/esonhugh/k8spider/define"
Expand All @@ -19,34 +17,40 @@ import (
var Opts = struct {
NamespaceWordlist string
NamespaceList []string
PodCidr string
}{}

func init() {
NeighborCmd.AddCommand(NeighborSvcCmd, NeighborPodCmd)
cmdx.RootCmd.AddCommand(NeighborCmd)
NeighborCmd.Flags().StringVar(&Opts.NamespaceWordlist, "ns-file", "", "namespace wordlist file")
NeighborCmd.Flags().StringSliceVar(&Opts.NamespaceList, "ns", []string{}, "namespace list")
NeighborCmd.Flags().StringVarP(&Opts.PodCidr, "pod-cidr", "p", defaultPodCidr(), "pod cidr list, watch out for the network interface name, default is eth0")
NeighborPodCmd.Flags().StringVar(&Opts.NamespaceWordlist, "ns-file", "", "namespace wordlist file")
NeighborPodCmd.Flags().StringSliceVar(&Opts.NamespaceList, "ns", []string{}, "namespace list")
}

func defaultPodCidr() string {
interfaces, _ := net.Interfaces()
for _, i := range interfaces {
if i.Name == "eth0" {
addrs, _ := i.Addrs()
if addrs != nil || len(addrs) > 0 {
ip := strings.Split(addrs[0].String(), "/")[0]
return fmt.Sprintf("%v/16", ip)
}
var NeighborCmd = &cobra.Command{
Use: "neighbor",
Short: "neighbor is a tool to discover k8s neighbor pods",
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}

var NeighborSvcCmd = &cobra.Command{
Use: "svc",
Short: "neighbor is a tool to discover k8s neighbor pod with services",
Run: func(cmd *cobra.Command, args []string) {
ipNets, err := pkg.ParseStringToIPNet(cmdx.Opts.PodCidr)
if err != nil {
log.Warnf("ParseStringToIPNet failed: %v", err)
return
}
}
return "10.0.0.1/16"
r := RunSvc(ipNets, cmdx.Opts.ThreadingNum)
printer.PrintResult(r, cmdx.Opts.OutputFile)
},
}

var NeighborCmd = &cobra.Command{
Use: "neighbor",
Short: "neighbor is a tool to discover k8s pod and available ip in subnet (require k8s coredns with pod verified config)",
Aliases: []string{"n", "nei"},
var NeighborPodCmd = &cobra.Command{
Use: "pod",
Short: "neighbor is a tool to discover k8s pod and available ip in subnet (require k8s coredns with pod verified config)",
Run: func(cmd *cobra.Command, args []string) {
if !pkg.CheckPodVerified() {
log.Fatalf("k8s coredns with pod verified config could not be set")
Expand All @@ -64,17 +68,17 @@ var NeighborCmd = &cobra.Command{
}
}
log.Tracef("namespace list: %v", Opts.NamespaceList)
ipNets, err := pkg.ParseStringToIPNet(Opts.PodCidr)
ipNets, err := pkg.ParseStringToIPNet(cmdx.Opts.PodCidr)
if err != nil {
log.Warnf("ParseStringToIPNet failed: %v", err)
return
}
r := RunMultiThread(Opts.NamespaceList, ipNets, cmdx.Opts.ThreadingNum)
r := RunPod(Opts.NamespaceList, ipNets, cmdx.Opts.ThreadingNum)
printer.PrintResult(r, cmdx.Opts.OutputFile)
},
}

func RunMultiThread(ns []string, net *net.IPNet, num int) (finalRecord define.Records) {
func RunPod(ns []string, net *net.IPNet, num int) (finalRecord define.Records) {
scan := mutli.ScanNeighbor(ns, net, num)
for r := range scan {
finalRecord = append(finalRecord, r...)
Expand All @@ -85,3 +89,15 @@ func RunMultiThread(ns []string, net *net.IPNet, num int) (finalRecord define.Re
}
return
}

func RunSvc(net *net.IPNet, num int) (finalRecord define.Records) {
scan := mutli.ScanNeighborSvc(net, num)
for r := range scan {
finalRecord = append(finalRecord, r...)
}
if len(finalRecord) == 0 {
log.Warn("ScanSubnet Found Nothing")
return
}
return
}
Loading

0 comments on commit fdec346

Please sign in to comment.