Projects#
Go projects that fit the language’s sweet spot, static binaries you can drop and run, network tools, and small services.
Static CLI tool#
A subdomain enumerator built on the stdlib resolver and
cobra. Cross-compiles to a single binary drop
onto any target host.
// main.go
package main
import (
"bufio"
"context"
"fmt"
"net"
"os"
"sync"
"time"
"github.com/spf13/cobra"
)
func main() {
var concurrency int
cmd := &cobra.Command{
Use: "resolve <file>",
Short: "Resolve A/AAAA for every line in the file",
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, args []string) error {
f, err := os.Open(args[0])
if err != nil { return err }
defer f.Close()
ctx, cancel := context.WithTimeout(context.Background(),
30*time.Second)
defer cancel()
sem := make(chan struct{}, concurrency)
var wg sync.WaitGroup
s := bufio.NewScanner(f)
for s.Scan() {
host := s.Text()
wg.Add(1)
sem <- struct{}{}
go func(h string) {
defer wg.Done()
defer func() { <-sem }()
addrs, _ := net.DefaultResolver.LookupHost(ctx, h)
fmt.Println(h, addrs)
}(host)
}
wg.Wait()
return s.Err()
},
}
cmd.Flags().IntVarP(&concurrency, "concurrency", "c", 50, "parallel resolutions")
cmd.Execute()
}
HTTP probe#
A concurrent HTTP banner-grabber. net/http plus goroutines
plus a worker pool.
package main
import (
"context"
"fmt"
"net/http"
"sync"
"time"
)
func probe(ctx context.Context, url string, c *http.Client) (int, string) {
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
r, err := c.Do(req)
if err != nil { return 0, err.Error() }
defer r.Body.Close()
return r.StatusCode, r.Header.Get("Server")
}
func main() {
urls := []string{
"https://example.com",
"https://example.org",
}
c := &http.Client{Timeout: 5 * time.Second}
ctx, cancel := context.WithTimeout(context.Background(),
30*time.Second)
defer cancel()
var wg sync.WaitGroup
for _, u := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
status, server := probe(ctx, u, c)
fmt.Println(u, status, server)
}(u)
}
wg.Wait()
}
Microservice#
A small HTTP service run as a collection endpoint
for their other tooling. net/http only, no framework.
package main
import (
"encoding/json"
"log"
"net/http"
)
type Finding struct {
Host string `json:"host"`
Port int `json:"port"`
}
func main() {
http.HandleFunc("/collect", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "POST only", http.StatusMethodNotAllowed)
return
}
var f Finding
if err := json.NewDecoder(r.Body).Decode(&f); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
log.Printf("collected: %+v", f)
w.WriteHeader(http.StatusNoContent)
})
log.Fatal(http.ListenAndServe(":9000", nil))
}
Agent#
A long-running agent drop on hosts to collect metrics and stream them back to a control server over HTTPS. Pattern, ticker → collect → POST.
package main
import (
"bytes"
"encoding/json"
"net/http"
"os"
"runtime"
"time"
)
func main() {
hostname, _ := os.Hostname()
client := &http.Client{Timeout: 10 * time.Second}
t := time.NewTicker(60 * time.Second)
defer t.Stop()
for range t.C {
payload, _ := json.Marshal(map[string]any{
"host": hostname,
"ts": time.Now().UTC(),
"goroutines": runtime.NumGoroutine(),
})
client.Post("https://collector.example.com/agent",
"application/json", bytes.NewReader(payload))
}
}
References#
Setup for the toolchain and cross-compilation.
Frameworks for Gin, Echo, Fiber, Cobra, Viper.
Networking for
net/http,crypto/tls, gRPC.