go实现自带webui的waf web防火墙应用管理系统代码

代码语言:golang

所属分类:其他

代码描述:go实现自带webui的waf web防火墙应用管理系统代码,单体实现,一个go代码内置了html,实现了可代理任何网站的防火墙。1. 运行程序 Bash go run waf.go 2. 访问管理后台 地址:http://localhost:8000/admin/login 默认账号:admin 默认密码:admin123 3. 功能说明 仪表板: 查看总请求数、拦截数、代理站点数 查看各类攻击类型统计 查看代理站点运行状态 代理管理: 添加新的代理站点(域名 -> 目标地址) 启用/停用代理 删

代码标签: go 自带 webui waf web 防火墙 应用 管理 系统 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

package main

import (
	"crypto/md5"
		"math"

	"golang.org/x/image/font"
	"golang.org/x/image/font/basicfont"
	"golang.org/x/image/math/fixed"
	"encoding/json"
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"regexp"
	"strings"
	"sync"
	"time"
)

// ============ 数据结构定义 ============

type Admin struct {
	Username string `json:"username"`
	Password string `json:"password"` // MD5存储
}

type ProxyTarget struct {
	ID          string    `json:"id"`
	Domain      string    `json:"domain"`      // 监听域名
	Target      string    `json:"target"`      // 目标地址
	Enabled     bool      `json:"enabled"`     // 是否启用
	CreatedAt   time.Time `json:"created_at"`
	RequestCount int64    `json:"request_count"`
	BlockCount   int64    `json:"block_count"`
}

type SessionData struct {
	Username  string
	LoginTime time.Time
}

type Statistics struct {
	TotalRequests int64            `json:"total_requests"`
	BlockedCount  int64            `json:"blocked_count"`
	AttackTypes   map[string]int64 `json:"attack_types"`
}

type Config struct {
	Admin          Admin                  `json:"admin"`
	ProxyTargets   map[string]ProxyTarget `json:"proxy_targets"`
	EnableWAF      bool                   `json:"enable_waf"`
	EnableBot      bool                   `json:"enable_bot"`
	RateLimit      int                    `json:"rate_limit"` // 每秒请求数
	Statistics     Statistics             `json:"statistics"`
}

// ============ 全局变量 ============

var (
	config      Config
	sessions    = make(map[string]SessionData)
	configFile  = "waf_config.json"
	rateLimiter = make(map[string]*TokenBucket)
	captchaStore = make(map[string]string)
	mu          sync.RWMutex
	sessionMu   sync.RWMutex
	limiterMu   sync.RWMutex
)

// ============ 令牌桶限流器 ============

type TokenBucket struct {
	tokens    float64
	capacity  float64
	rate      float64
	lastTime  time.Time
	mu        sync.Mutex
}

func NewTokenBucket(rate, capacity float64) *TokenBucket {
	return &TokenBucket{
		tokens:   capacity,
		capacity: capacity,
		rate:     rate,
		lastTime: time.Now(),
	}
}

func (tb *TokenBucket) Allow() bool {
	tb.mu.Lock()
	defer tb.mu.Unlock()
	
	now := time.Now()
	elapsed := now.Sub(tb.lastTime).Seconds()
	tb.tokens += elapsed * tb.rate
	
	if tb.tokens > tb.capacity {
		tb.tokens = tb.capacity
	}
	
	tb.lastTime = now
	
	if tb.tokens >= 1.0 {
		tb.tokens -= 1.0
		return true
	}
	
	return false
}

// ============ WAF规则引擎 ============

var wafRules = []struct {
	Name    string
	Pattern *regexp.Regexp
}{
	{"SQL_Injection", regexp.MustCompile(`(?i)(union.*select|select.*from|insert.*into|delete.*from|drop.*table|exec.*\(|script.*>)`)},
	{"XSS", regexp.MustCompile(`(?i)(<script|javascript:|onerror=|onload=|<iframe|eval\()`)},
	{"Path_Traversal", regexp.MustCompile(`(\.\./|\.\.\\|/etc/passwd|/windows/win\.ini)`)},
	{"Command_Injection", regexp.MustCompile(`(?i)(;|\||&|`+"`"+`)(\s)*(ls|cat|wget|curl|chmod|bash|sh|cmd|powershell)`)},
	{"XXE", regexp.MustCompile(`(?i)(<!entity|<!doctype.*\[)`)},
}

func checkWAF(r *http.Request) (bool, string) {
	if !config.EnableWAF {
		return true, ""
	}
	
	// 检查URL
	for _, rule := range wafRules {
		if rule.Pattern.MatchString(r.URL.String()) {
			return false, rule.Name
		}
	}
	
	// 检查POST数据
	if r.Method == "POST" {
		body, _ := ioutil.ReadAll(r.Body)
		r.Body = ioutil.NopCloser(strings.NewReader(string(body)))
		
		for _, rule := range wafRules {
			if rule.Pattern.MatchString(string(body)) {
				return false, rule.Name
			}
		}
	}
	
	// 检查Headers
	for _, values := range r.Header {
		for _, value := range values {
			for _, rule := range wafRules {
				if rule.Pattern.MatchString(value) {
					return false, rule.Name
				}
			}
		}
	}
	
	return true, ""
}

// ============ 爬虫检测 ============

func checkBot(r *http.Request) bool {
	if !config.EnableBot {
		return true
	}
	
	userAgent := r.Header.Get("User-Agent")
	
	// 检查常见爬虫特征
	botPatterns := []string{
		"bot", "crawler", "spider", "scraper", "curl", "wget",
		"python", "java", "ruby", "perl", "scrapy",
	}
	
	userAgentLower := strings.ToLower(userAgent)
	for _, pattern := range botPatterns {
		if strings.Contains(userAgentLower, pattern) {
			return false
		}
	}
	
	// 检查是否有referer(简单检测)
	if userAgent == "" {
		return false
	}
	
	return true
}

// ============ 验证码生成 ============

// 使用Bresenham算法画线
func drawLine(img *image.RGBA, x1, y1, x2, y2 int, col color.Color) {
	dx := math.Abs(float64(x2 - x1))
	dy := math.Abs(float64(y2 - y1))
	sx := 1
	if x1 > x2 {
		sx = -1
	}
	sy := 1
	if y1 > y2 {
		sy = -1
	}
	err := dx - dy

	for {
		img.Set(x1, y1, col)
		if x1 == x2 && y1 == y2 {
			break
		}
		e2 := 2 * err
		if e2 > -dy {
			err -= dy
			x1 += sx
		}
		if e2 < dx {
			err += dx
			y1 += sy
		}
	}
}

func generateCaptcha() (string, image.Image) {
	const (
		width  = 120
		height = 40
		chars  = "0123456789"
		length = 4
	)
	
	code := make([]byte, length)
	for i := range code {
		code[i] = chars[rand.Intn(len(chars))]
	}

	img := image.NewRGBA(image.Rect(0, 0, width, height))
	// 使用浅灰色背景
	draw.Draw(img, img.Bounds(), &image.Uniform{color.RGBA{245, 245, 245, 255}}, image.Point{}, draw.Src)

	// 绘制干扰线
	for i := 0; i < 5; i++ {
		x1 := rand.Intn(width)
		y1 := rand.Intn(height)
		x2 := rand.Intn(width)
		y2 := rand.Intn(height)
		c := color.RGBA{uint8(180 + rand.Intn(60)), uint8(180 + rand.Intn(60)), uint8(180 + rand.Intn(60)), 255}
		drawLine(img, x1, y1, x2, y2, c)
	}

	// 绘制字符
	charSpacing := (width - 20) / length
	for i, c := range code {
		// 随机深色
		charColor := &image.Uniform{color.RGBA{uint8(.........完整代码请登录后点击上方下载按钮下载查看

网友评论0