Skip to content

Instantly share code, notes, and snippets.

@Splinters-io
Created September 19, 2025 21:42
Show Gist options
  • Select an option

  • Save Splinters-io/268e76eb7cca5fcead0dd9c7d09e638c to your computer and use it in GitHub Desktop.

Select an option

Save Splinters-io/268e76eb7cca5fcead0dd9c7d09e638c to your computer and use it in GitHub Desktop.
MannaWeb.go
package main
import (
"bytes"
"context"
"crypto/tls"
"encoding/hex"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"os/signal"
"regexp"
"strings"
"sync"
"syscall"
"time"
"unicode/utf8"
)
type ConnectionTracker struct {
mu sync.RWMutex
connections map[string]*ConnectionInfo
}
type ConnectionInfo struct {
StartTime time.Time
TLSVersion string
CipherSuite string
ClientCert string
RequestCount int
}
var (
connTracker = &ConnectionTracker{connections: make(map[string]*ConnectionInfo)}
suspiciousPatterns = []*regexp.Regexp{
regexp.MustCompile(`(?i)\.\.[\\/]`),
regexp.MustCompile(`(?i)(union|select|drop|insert|delete)\s+`),
regexp.MustCompile(`(?i)<script[^>]*>`),
regexp.MustCompile(`(?i)eval\s*\(`),
regexp.MustCompile(`(?i)base64_decode`),
}
maxBodySize = int64(1024 * 1024) // 1MB
slackWebhook string
logFile *os.File
)
type SlackPayload struct {
Text string `json:"text"`
}
func sendSlackAlert(message string) {
if slackWebhook == "" {
return
}
payload := SlackPayload{Text: message}
jsonData, _ := json.Marshal(payload)
go func() {
resp, err := http.Post(slackWebhook, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
log.Printf("SLACK_ERROR: %v", err)
return
}
resp.Body.Close()
}()
}
func logToFile(message string) {
if logFile != nil {
logFile.WriteString(fmt.Sprintf("%s %s\n", time.Now().Format(time.RFC3339), message))
logFile.Sync()
}
}
func (ct *ConnectionTracker) addConnection(remoteAddr string, tlsState *tls.ConnectionState) {
ct.mu.Lock()
defer ct.mu.Unlock()
info := &ConnectionInfo{
StartTime: time.Now(),
}
if tlsState != nil {
info.TLSVersion = getTLSVersionString(tlsState.Version)
info.CipherSuite = tls.CipherSuiteName(tlsState.CipherSuite)
if len(tlsState.PeerCertificates) > 0 {
info.ClientCert = fmt.Sprintf("CN=%s", tlsState.PeerCertificates[0].Subject.CommonName)
}
}
ct.connections[remoteAddr] = info
log.Printf("TLS_CONNECT Remote=%s TLS=%s Cipher=%s ClientCert=%s",
remoteAddr, info.TLSVersion, info.CipherSuite, info.ClientCert)
}
func (ct *ConnectionTracker) incrementRequest(remoteAddr string) {
ct.mu.Lock()
defer ct.mu.Unlock()
if info, exists := ct.connections[remoteAddr]; exists {
info.RequestCount++
}
}
func getTLSVersionString(version uint16) string {
switch version {
case tls.VersionTLS10:
return "TLS1.0"
case tls.VersionTLS11:
return "TLS1.1"
case tls.VersionTLS12:
return "TLS1.2"
case tls.VersionTLS13:
return "TLS1.3"
default:
return fmt.Sprintf("Unknown(%d)", version)
}
}
func getRealClientIP(r *http.Request) string {
// Check X-Forwarded-For
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
ips := strings.Split(xff, ",")
return strings.TrimSpace(ips[0])
}
// Check X-Real-IP
if xri := r.Header.Get("X-Real-IP"); xri != "" {
return xri
}
// Fallback to RemoteAddr
host, _, _ := net.SplitHostPort(r.RemoteAddr)
return host
}
func isBinaryContent(data []byte) bool {
if len(data) == 0 {
return false
}
// Check for NULL bytes or non-UTF8 content
for i, b := range data {
if b == 0 {
return true
}
if i > 512 { // Check first 512 bytes
break
}
}
return !utf8.Valid(data)
}
func checkSuspiciousPatterns(data string) []string {
var matches []string
for _, pattern := range suspiciousPatterns {
if pattern.MatchString(data) {
matches = append(matches, pattern.String())
}
}
return matches
}
func logRequest(r *http.Request) {
start := time.Now()
realIP := getRealClientIP(r)
// Track connection
connTracker.incrementRequest(r.RemoteAddr)
// Read body with size limit
limitedBody := http.MaxBytesReader(nil, r.Body, maxBodySize)
body, err := io.ReadAll(limitedBody)
r.Body.Close()
if err != nil {
log.Printf("ERROR_BODY_READ Remote=%s Error=%v", r.RemoteAddr, err)
body = []byte("[ERROR: Body too large or read failed]")
}
// Basic request info
requestInfo := fmt.Sprintf("REQUEST: %s %s from %s (Real IP: %s) UA: %s",
r.Method, r.URL.String(), r.RemoteAddr, realIP, r.UserAgent())
log.Printf("=== REQUEST START ===")
log.Printf("METHOD=%s URL=%s PROTO=%s", r.Method, r.URL.String(), r.Proto)
log.Printf("HOST=%s REMOTE=%s REAL_IP=%s", r.Host, r.RemoteAddr, realIP)
log.Printf("USER_AGENT=%s", r.UserAgent())
log.Printf("REFERER=%s", r.Referer())
log.Printf("CONTENT_LENGTH=%d CONTENT_TYPE=%s", r.ContentLength, r.Header.Get("Content-Type"))
// Log to file
logToFile(requestInfo)
// Log TLS info if available
if r.TLS != nil {
log.Printf("TLS_VERSION=%s CIPHER=%s", getTLSVersionString(r.TLS.Version), tls.CipherSuiteName(r.TLS.CipherSuite))
if len(r.TLS.PeerCertificates) > 0 {
log.Printf("CLIENT_CERT=%s", r.TLS.PeerCertificates[0].Subject.CommonName)
}
}
// Log all headers
log.Printf("--- HEADERS ---")
for name, values := range r.Header {
for _, value := range values {
log.Printf("HEADER: %s=%s", name, value)
}
}
// Log body
var bodyAlert string
if len(body) > 0 {
if isBinaryContent(body) {
log.Printf("BODY_BINARY: %d bytes, hex=%s", len(body), hex.EncodeToString(body[:min(32, len(body))]))
bodyAlert = fmt.Sprintf(" with %d bytes binary data", len(body))
} else {
bodyStr := string(body)
log.Printf("BODY_TEXT: %s", bodyStr)
bodyAlert = fmt.Sprintf(" with body: %.100s", bodyStr)
// Check for suspicious patterns
suspicious := checkSuspiciousPatterns(bodyStr)
if len(suspicious) > 0 {
alertMsg := fmt.Sprintf("🚨 SECURITY ALERT: %s%s - Suspicious body patterns: %v", requestInfo, bodyAlert, suspicious)
log.Printf("SECURITY_ALERT: Suspicious patterns detected: %v", suspicious)
sendSlackAlert(alertMsg)
logToFile(alertMsg)
}
}
}
// Check URL for suspicious patterns
urlSuspicious := checkSuspiciousPatterns(r.URL.String())
if len(urlSuspicious) > 0 {
alertMsg := fmt.Sprintf("🚨 SECURITY ALERT: %s%s - Suspicious URL patterns: %v", requestInfo, bodyAlert, urlSuspicious)
log.Printf("SECURITY_ALERT: Suspicious URL patterns: %v", urlSuspicious)
sendSlackAlert(alertMsg)
logToFile(alertMsg)
}
// Send general alert for interesting requests
if r.Method != "GET" || len(body) > 0 || r.URL.Path != "/" {
alertMsg := fmt.Sprintf("📡 Traffic Alert: %s%s", requestInfo, bodyAlert)
sendSlackAlert(alertMsg)
}
log.Printf("=== REQUEST END === (Duration: %v)", time.Since(start))
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
var serveFile string
func handler(w http.ResponseWriter, r *http.Request) {
logRequest(r)
if serveFile != "" {
http.ServeFile(w, r, serveFile)
} else {
w.WriteHeader(200)
w.Write([]byte("OK"))
}
}
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("HEALTHY"))
}
type ConnStateLogger struct {
listener net.Listener
}
func (c *ConnStateLogger) Accept() (net.Conn, error) {
conn, err := c.listener.Accept()
if err != nil {
return nil, err
}
return &LoggingConn{Conn: conn}, nil
}
func (c *ConnStateLogger) Close() error {
return c.listener.Close()
}
func (c *ConnStateLogger) Addr() net.Addr {
return c.listener.Addr()
}
type LoggingConn struct {
net.Conn
logged bool
}
func (lc *LoggingConn) Read(b []byte) (int, error) {
if !lc.logged {
log.Printf("CONN_ESTABLISHED Remote=%s Local=%s", lc.RemoteAddr(), lc.LocalAddr())
lc.logged = true
}
return lc.Conn.Read(b)
}
func (lc *LoggingConn) Close() error {
log.Printf("CONN_CLOSED Remote=%s", lc.RemoteAddr())
return lc.Conn.Close()
}
func main() {
port := flag.String("port", "443", "Port")
cert := flag.String("cert", "/etc/letsencrypt/live/YOURDOMAIN/fullchain.pem", "Cert file")
key := flag.String("key", "/etc/letsencrypt/live/YOURDOMAIN/privkey.pem", "Key file")
maxBody := flag.Int64("max-body", 1024*1024, "Max request body size in bytes")
file := flag.String("file", "", "File to serve for all requests (optional)")
webhook := flag.String("slack", "", "Slack webhook URL for alerts")
logPath := flag.String("log", "", "Log file path (optional)")
flag.Parse()
maxBodySize = *maxBody
serveFile = *file
slackWebhook = *webhook
// Setup log file
if *logPath != "" {
var err error
logFile, err = os.OpenFile(*logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal("Failed to open log file:", err)
}
defer logFile.Close()
}
if _, err := os.Stat(*cert); os.IsNotExist(err) {
log.Fatal("Cert file not found:", *cert)
}
if _, err := os.Stat(*key); os.IsNotExist(err) {
log.Fatal("Key file not found:", *key)
}
// Setup routes
http.HandleFunc("/", handler)
http.HandleFunc("/health", healthHandler)
// TLS config with connection state callback
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12,
GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
// Log legacy protocol attempts
if len(chi.SupportedVersions) > 0 {
for _, version := range chi.SupportedVersions {
if version < tls.VersionTLS12 {
alertMsg := fmt.Sprintf("🔒 Legacy TLS attempt from %s - versions: %v", "unknown", chi.SupportedVersions)
log.Printf("TLS_LEGACY_ATTEMPT: %s", alertMsg)
sendSlackAlert(alertMsg)
logToFile(alertMsg)
break
}
}
}
cert, err := tls.LoadX509KeyPair(*cert, *key)
if err != nil {
log.Printf("TLS_HANDSHAKE_ERROR Error=%v", err)
return nil, err
}
return &cert, nil
},
}
server := &http.Server{
Addr: ":" + *port,
TLSConfig: tlsConfig,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 120 * time.Second,
ConnState: func(conn net.Conn, state http.ConnState) {
switch state {
case http.StateNew:
log.Printf("HTTP_CONN_NEW Remote=%s", conn.RemoteAddr())
case http.StateActive:
if tlsConn, ok := conn.(*tls.Conn); ok {
state := tlsConn.ConnectionState()
connTracker.addConnection(conn.RemoteAddr().String(), &state)
}
case http.StateClosed:
log.Printf("HTTP_CONN_CLOSED Remote=%s", conn.RemoteAddr())
}
},
}
// Graceful shutdown
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log.Println("SHUTDOWN_INITIATED")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
server.Shutdown(ctx)
log.Println("SHUTDOWN_COMPLETE")
}()
log.Printf("STARTUP port=%s cert=%s key=%s max_body=%d", *port, *cert, *key, *maxBody)
log.Printf("SERVER_LISTENING port=%s", *port)
if err := server.ListenAndServeTLS(*cert, *key); err != nil && err != http.ErrServerClosed {
log.Fatal("SERVER_ERROR:", err)
}
log.Println("SERVER_STOPPED")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment