go实现自带webui支持限流人机验证爬虫防护sql注入xss攻击的waf web防火墙应用管理系统代码
代码语言:golang
所属分类:其他
代码描述:go实现自带webui支持限流人机验证爬虫防护sql注入xss攻击的waf web防火墙应用管理系统代码
代码标签: go 自带 webui 支持 限流 人机 验证 爬虫 防护 sql注入 xss 攻击 waf web
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
package main
import (
"crypto/md5"
"encoding/json"
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"io/ioutil"
"log"
"math"
"math/rand"
"net/http"
"net/http/httputil"
"net/url"
"os"
"regexp"
"strconv"
"strings"
"sync"
"time"
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
)
// ============ 数据结构定义 ============
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"` // 每秒请求数
RateLimitBurst int `json:"rate_limit_burst"` // 峰值
EnableHumanVerification bool `json:"enable_human_verification"` // 启用人机验证
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)
whitelistedIPs = make(map[string]time.Time) // 人机验证白名单
mu sync.RWMutex
sessionMu sync.RWMutex
limiterMu sync.RWMutex
whitelistMu 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-requests", "java/", "ruby", "perl", "scrapy",
}
userAgentLower := strings.ToLower(userAgent)
for _, pattern := range botPatterns {
if strings.Contains(userAgentLower, pattern) {
return false
}
}
// 检查是否没有User-Agent
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(rand.Intn(100)), uint8(rand.Intn(100)), uint8(rand.Intn(100)), 255}}
// 字符位置
x := 10 + i*charSpacing + rand.Intn(5)
y := 25 + rand.Intn(10) // 随机垂直偏移
d := &font.Drawer{
Dst: img,
Src: charColor,
Face: basicfont.Face7x13,
Dot: fixed.Point26_6{X: fixed.I(x), Y: fixed.I(y)},
}
d.DrawString(string(c))
}
return string(code), img
}
// ============ 工具函数 ============
func md5Hash(text string) string {
hash := md5.Sum([]byte(text))
return fmt.Sprintf("%x", hash)
}
func randomString(n int) string {
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func saveConfig() error {
mu.Lock()
defer mu.Unlock()
data, err := json.MarshalIndent(config, "", .........完整代码请登录后点击上方下载按钮下载查看















网友评论0