前言你有没有想过在用户请求到达你的Web服务器之前是怎么被检查的SQL注入、XSS攻击是怎么被拦截的Web应用防火墙WAF 是Web安全的第一道防线专门分析HTTP请求拦截恶意流量。今天我们从零实现一个WAF的核心功能· HTTP请求解析· 规则引擎SQL注入/XSS检测· 正向/反向代理模式· 频率限制· IP黑白名单· 日志与告警---一、WAF核心原理1. WAF部署模式┌─────────────────────────────────────────────────────────────┐│ 用户请求 │└─────────────────────────────────────────────────────────────┘│┌───────┴───────┐▼ ▼┌─────────────┐ ┌─────────────┐│ 透明代理 │ │ 反向代理 ││ (网桥模式) │ │ (网关模式) │└─────────────┘ └─────────────┘│ │└───────┬───────┘▼┌─────────────┐│ WAF引擎 ││ 规则匹配 │└─────────────┘│▼┌─────────────┐│ Web服务器 │└─────────────┘2. 核心检测规则攻击类型 检测特征 示例SQL注入 OR 11, UNION SELECT, sleep( ?id1 OR 11XSS script, onerror, alert( ?namescriptalert(1)/script路径遍历 ../, .., /etc/passwd ?file../../etc/passwd命令注入 ; ls, whoami, $(cat)SSRF http://169.254.169.254, localhost ?urlhttp://localhost/admin---二、完整代码实现1. 基础数据结构c#include stdio.h#include stdlib.h#include string.h#include unistd.h#include pthread.h#include time.h#include errno.h#include arpa/inet.h#include sys/socket.h#include netinet/in.h#include netdb.h#define MAX_HEADERS 64#define MAX_HEADER_LEN 512#define MAX_BODY_LEN 65536#define MAX_RULES 1000#define MAX_REQUEST_LEN 65536// HTTP请求结构typedef struct http_request {char method[16];char uri[1024];char version[16];char headers[MAX_HEADERS][MAX_HEADER_LEN];int header_count;char body[MAX_BODY_LEN];int body_len;char client_ip[32];int port;char host[256];} http_request_t;// 检测结果typedef enum {WAF_ALLOW 0,WAF_BLOCK 1,WAF_LOG 2,WAF_CHALLENGE 3} waf_action_t;// 规则类型typedef enum {RULE_SQL_INJECTION 0,RULE_XSS,RULE_PATH_TRAVERSAL,RULE_CMD_INJECTION,RULE_SSRF,RULE_RATE_LIMIT,RULE_IP_BLACKLIST,RULE_IP_WHITELIST,RULE_USER_AGENT,RULE_HEADER} rule_type_t;// WAF规则typedef struct waf_rule {int id;rule_type_t type;char pattern[512];char target[64]; // uri, body, header, user-agent, ipwaf_action_t action;char severity[16];char message[256];int enabled;struct waf_rule *next;} waf_rule_t;// 频率限制条目typedef struct rate_limit_entry {char key[128]; // ipuriint count;time_t first_request;time_t last_request;int blocked;time_t block_until;struct rate_limit_entry *next;} rate_limit_entry_t;// WAF结构typedef struct waf_engine {waf_rule_t *rules;rate_limit_entry_t *rate_limits;int rule_count;int block_count;int log_count;int mode; // 0: 学习, 1: 检测, 2: 拦截char log_dir[256];pthread_mutex_t mutex;pthread_t cleanup_thread;int running;} waf_engine_t;2. HTTP请求解析c// 创建WAF引擎waf_engine_t *waf_create(const char *log_dir) {waf_engine_t *waf malloc(sizeof(waf_engine_t));memset(waf, 0, sizeof(waf_engine_t));waf-mode 1;waf-running 1;strcpy(waf-log_dir, log_dir);pthread_mutex_init(waf-mutex, NULL);printf([WAF] 引擎初始化完成\n);return waf;}// 解析HTTP请求int parse_http_request(const char *raw, http_request_t *req) {memset(req, 0, sizeof(http_request_t));char *ptr (char*)raw;// 解析请求行if (sscanf(ptr, %s %s %s, req-method, req-uri, req-version) ! 3) {return -1;}// 解析Headerschar *line_start strstr(ptr, \r\n);if (!line_start) return -1;ptr line_start 2;while (*ptr) {char *line_end strstr(ptr, \r\n);if (!line_end) break;char *colon strchr(ptr, :);if (colon) {char *key ptr;int key_len colon - ptr;char *value colon 1;while (*value ) value;int value_len line_end - value;if (req-header_count MAX_HEADERS) {snprintf(req-headers[req-header_count], MAX_HEADER_LEN,%.*s: %.*s, key_len, key, value_len, value);req-header_count;}}ptr line_end 2;// 空行表示body开始if (ptr[0] \r ptr[1] \n) {ptr 2;break;}}// Bodyif (*ptr) {req-body_len strlen(ptr);if (req-body_len MAX_BODY_LEN) {memcpy(req-body, ptr, req-body_len);req-body[req-body_len] \0;}}return 0;}3. 规则引擎c// 添加规则void waf_add_rule(waf_engine_t *waf, int id, rule_type_t type, const char *pattern,const char *target, waf_action_t action, const char *severity,const char *message) {pthread_mutex_lock(waf-mutex);waf_rule_t *rule malloc(sizeof(waf_rule_t));rule-id id;rule-type type;strcpy(rule-pattern, pattern);strcpy(rule-target, target);rule-action action;strcpy(rule-severity, severity);strcpy(rule-message, message);rule-enabled 1;rule-next waf-rules;waf-rules rule;waf-rule_count;pthread_mutex_unlock(waf-mutex);printf([规则] 添加规则 #%d: %s\n, id, message);}// 模式匹配支持正则简化int pattern_match(const char *pattern, const char *text, int nocase) {if (!pattern || !text) return 0;// 纯字符串匹配if (nocase) {char p[512], t[512];strcpy(p, pattern);for (int i 0; p[i]; i) p[i] tolower(p[i]);strcpy(t, text);for (int i 0; t[i]; i) t[i] tolower(t[i]);return strstr(t, p) ! NULL;}return strstr(text, pattern) ! NULL;}// 检查SQL注入模式int detect_sql_injection(const char *text) {const char *patterns[] {select, union, insert, update, delete, drop,from, where, order by, group by, --, ;, or 11, or aa, \ or \1\\1,sleep(, benchmark(, waitfor delay,information_schema, table_name, column_name,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 1)) {return 1;}}return 0;}// 检查XSS模式int detect_xss(const char *text) {const char *patterns[] {script, /script, javascript:, onerror,onload, onmouseover, onclick, onfocus,alert(, prompt(, confirm(, document.cookie,window.location, eval(, innerHTML, document.write,lt;script, #60;script, #x3c;script,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 1)) {return 1;}}return 0;}// 检查路径遍历int detect_path_traversal(const char *text) {const char *patterns[] {../, ..\\, /etc/passwd, /etc/shadow,/proc/, /var/log/, boot.ini, win.ini,%2e%2e%2f, %2e%2e\\, ..%5c,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 0)) {return 1;}}return 0;}// 检查命令注入int detect_cmd_injection(const char *text) {const char *patterns[] {; ls, ; whoami, ; cat, ; echo,| whoami, | ls, whoami, ls,$(cat, $(whoami, cat, whoami,; net user, net user, | net user,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 0)) {return 1;}}return 0;}// 检查SSRFint detect_ssrf(const char *text) {const char *patterns[] {http://127.0.0.1, http://localhost, http://0.0.0.0,http://169.254.169.254, http://metadata, http://[::1],http://192.168., http://10., http://172.16.,file:///etc/, gopher://, dict://, ftp://,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 0)) {return 1;}}return 0;}4. 频率限制c// 频率限制检查int waf_check_rate_limit(waf_engine_t *waf, const char *ip, const char *uri,int limit, int window_seconds) {char key[128];snprintf(key, sizeof(key), %s:%s, ip, uri);time_t now time(NULL);pthread_mutex_lock(waf-mutex);rate_limit_entry_t *entry waf-rate_limits;while (entry) {if (strcmp(entry-key, key) 0) {// 检查是否被阻塞if (entry-blocked now entry-block_until) {pthread_mutex_unlock(waf-mutex);return 1; // 被阻塞}if (entry-blocked now entry-block_until) {entry-blocked 0;entry-count 0;}// 滑动窗口if (now - entry-first_request window_seconds) {entry-first_request now;entry-count 1;pthread_mutex_unlock(waf-mutex);return 0;}entry-count;entry-last_request now;if (entry-count limit) {entry-blocked 1;entry-block_until now 300; // 阻塞5分钟pthread_mutex_unlock(waf-mutex);return 1;}pthread_mutex_unlock(waf-mutex);return 0;}entry entry-next;}// 创建新条目entry malloc(sizeof(rate_limit_entry_t));strcpy(entry-key, key);entry-count 1;entry-first_request now;entry-last_request now;entry-blocked 0;entry-block_until 0;entry-next waf-rate_limits;waf-rate_limits entry;pthread_mutex_unlock(waf-mutex);return 0;}5. 主检测流程c// WAF检测waf_action_t waf_inspect(waf_engine_t *waf, http_request_t *req) {// 1. IP检查// 2. URI检查// 3. Body检查// 4. Headers检查// 5. 频率限制waf_rule_t *rule waf-rules;while (rule) {if (!rule-enabled) {rule rule-next;continue;}const char *text NULL;if (strcmp(rule-target, uri) 0) {text req-uri;} else if (strcmp(rule-target, body) 0) {text req-body;} else if (strcmp(rule-target, ip) 0) {text req-client_ip;} else if (strcmp(rule-target, user-agent) 0) {// 从headers提取User-Agentfor (int i 0; i req-header_count; i) {if (strncasecmp(req-headers[i], User-Agent:, 11) 0) {text req-headers[i] 12;while (*text ) text;break;}}}if (text) {int matched 0;switch (rule-type) {case RULE_SQL_INJECTION:matched detect_sql_injection(text);break;case RULE_XSS:matched detect_xss(text);break;case RULE_PATH_TRAVERSAL:matched detect_path_traversal(text);break;case RULE_CMD_INJECTION:matched detect_cmd_injection(text);break;case RULE_SSRF:matched detect_ssrf(text);break;default:matched pattern_match(rule-pattern, text, 0);break;}if (matched) {printf([WAF] 拦截: %s (规则 #%d) %s - %s\n,rule-severity, rule-id, req-client_ip, rule-message);return rule-action;}}rule rule-next;}return WAF_ALLOW;}6. 测试代码cvoid test_waf() {printf( Web应用防火墙测试 \n\n);waf_engine_t *waf waf_create(./logs);// 添加规则waf_add_rule(waf, 1, RULE_SQL_INJECTION, , uri,WAF_BLOCK, CRITICAL, SQL注入检测);waf_add_rule(waf, 2, RULE_XSS, , body,WAF_BLOCK, HIGH, XSS攻击检测);waf_add_rule(waf, 3, RULE_PATH_TRAVERSAL, , uri,WAF_BLOCK, HIGH, 路径遍历检测);waf_add_rule(waf, 4, RULE_CMD_INJECTION, , uri,WAF_BLOCK, CRITICAL, 命令注入检测);// 测试正常请求http_request_t req1;parse_http_request(GET /index.html HTTP/1.1\r\nHost: example.com\r\nUser-Agent: Mozilla/5.0\r\n\r\n,req1);strcpy(req1.client_ip, 192.168.1.100);printf(正常请求:\n);waf_action_t result waf_inspect(waf, req1);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 测试SQL注入http_request_t req2;parse_http_request(GET /search?q OR 11 HTTP/1.1\r\nHost: example.com\r\n\r\n,req2);strcpy(req2.client_ip, 192.168.1.101);printf(\nSQL注入请求:\n);result waf_inspect(waf, req2);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 测试XSShttp_request_t req3;parse_http_request(POST /comment HTTP/1.1\r\nHost: example.com\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\ntextscriptalert(1)/script,req3);strcpy(req3.client_ip, 192.168.1.102);printf(\nXSS请求:\n);result waf_inspect(waf, req3);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 测试路径遍历http_request_t req4;parse_http_request(GET /download?file../../etc/passwd HTTP/1.1\r\nHost: example.com\r\n\r\n,req4);strcpy(req4.client_ip, 192.168.1.103);printf(\n路径遍历请求:\n);result waf_inspect(waf, req4);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 频率限制测试printf(\n频率限制测试 (10次请求):\n);int blocked_count 0;for (int i 0; i 10; i) {int blocked waf_check_rate_limit(waf, 192.168.1.100, /api/test, 5, 60);if (blocked) blocked_count;printf( 请求%d: %s\n, i1, blocked ? 拦截 : 允许);}printf( 总拦截: %d 次\n, blocked_count);printf(\n规则统计: %d 条\n, waf-rule_count);free(waf);}int main() {test_waf();return 0;}---三、编译和运行bashgcc -o waf waf.c -lpthread./waf---四、WAF vs 其他安全方案特性 WAF 防火墙 IDS 杀毒软件检测层 应用层 网络层 网络层 文件层检测方式 规则签名 规则 规则异常 签名行为实时拦截 ✅ ✅ ❌ ✅Web攻击检测 ✅ ❌ ❌ ❌部署位置 Web服务器前 网络边界 旁路 主机---五、总结通过这篇文章你学会了· WAF的核心功能规则检测、频率限制、黑白名单· HTTP请求解析· 攻击检测规则SQL注入、XSS、路径遍历、命令注入、SSRF· 频率限制实现· 检测引擎设计Web应用防火墙是应用安全的关键组件。掌握它你就理解了AWS WAF、Cloudflare WAF的底层设计。下一篇预告《从零实现一个容器运行时Docker的核心设计》---评论区分享一下你遇到过最复杂的WAF绕过方式
从零实现一个Web应用防火墙:WAF的核心设计
发布时间:2026/7/7 4:59:36
前言你有没有想过在用户请求到达你的Web服务器之前是怎么被检查的SQL注入、XSS攻击是怎么被拦截的Web应用防火墙WAF 是Web安全的第一道防线专门分析HTTP请求拦截恶意流量。今天我们从零实现一个WAF的核心功能· HTTP请求解析· 规则引擎SQL注入/XSS检测· 正向/反向代理模式· 频率限制· IP黑白名单· 日志与告警---一、WAF核心原理1. WAF部署模式┌─────────────────────────────────────────────────────────────┐│ 用户请求 │└─────────────────────────────────────────────────────────────┘│┌───────┴───────┐▼ ▼┌─────────────┐ ┌─────────────┐│ 透明代理 │ │ 反向代理 ││ (网桥模式) │ │ (网关模式) │└─────────────┘ └─────────────┘│ │└───────┬───────┘▼┌─────────────┐│ WAF引擎 ││ 规则匹配 │└─────────────┘│▼┌─────────────┐│ Web服务器 │└─────────────┘2. 核心检测规则攻击类型 检测特征 示例SQL注入 OR 11, UNION SELECT, sleep( ?id1 OR 11XSS script, onerror, alert( ?namescriptalert(1)/script路径遍历 ../, .., /etc/passwd ?file../../etc/passwd命令注入 ; ls, whoami, $(cat)SSRF http://169.254.169.254, localhost ?urlhttp://localhost/admin---二、完整代码实现1. 基础数据结构c#include stdio.h#include stdlib.h#include string.h#include unistd.h#include pthread.h#include time.h#include errno.h#include arpa/inet.h#include sys/socket.h#include netinet/in.h#include netdb.h#define MAX_HEADERS 64#define MAX_HEADER_LEN 512#define MAX_BODY_LEN 65536#define MAX_RULES 1000#define MAX_REQUEST_LEN 65536// HTTP请求结构typedef struct http_request {char method[16];char uri[1024];char version[16];char headers[MAX_HEADERS][MAX_HEADER_LEN];int header_count;char body[MAX_BODY_LEN];int body_len;char client_ip[32];int port;char host[256];} http_request_t;// 检测结果typedef enum {WAF_ALLOW 0,WAF_BLOCK 1,WAF_LOG 2,WAF_CHALLENGE 3} waf_action_t;// 规则类型typedef enum {RULE_SQL_INJECTION 0,RULE_XSS,RULE_PATH_TRAVERSAL,RULE_CMD_INJECTION,RULE_SSRF,RULE_RATE_LIMIT,RULE_IP_BLACKLIST,RULE_IP_WHITELIST,RULE_USER_AGENT,RULE_HEADER} rule_type_t;// WAF规则typedef struct waf_rule {int id;rule_type_t type;char pattern[512];char target[64]; // uri, body, header, user-agent, ipwaf_action_t action;char severity[16];char message[256];int enabled;struct waf_rule *next;} waf_rule_t;// 频率限制条目typedef struct rate_limit_entry {char key[128]; // ipuriint count;time_t first_request;time_t last_request;int blocked;time_t block_until;struct rate_limit_entry *next;} rate_limit_entry_t;// WAF结构typedef struct waf_engine {waf_rule_t *rules;rate_limit_entry_t *rate_limits;int rule_count;int block_count;int log_count;int mode; // 0: 学习, 1: 检测, 2: 拦截char log_dir[256];pthread_mutex_t mutex;pthread_t cleanup_thread;int running;} waf_engine_t;2. HTTP请求解析c// 创建WAF引擎waf_engine_t *waf_create(const char *log_dir) {waf_engine_t *waf malloc(sizeof(waf_engine_t));memset(waf, 0, sizeof(waf_engine_t));waf-mode 1;waf-running 1;strcpy(waf-log_dir, log_dir);pthread_mutex_init(waf-mutex, NULL);printf([WAF] 引擎初始化完成\n);return waf;}// 解析HTTP请求int parse_http_request(const char *raw, http_request_t *req) {memset(req, 0, sizeof(http_request_t));char *ptr (char*)raw;// 解析请求行if (sscanf(ptr, %s %s %s, req-method, req-uri, req-version) ! 3) {return -1;}// 解析Headerschar *line_start strstr(ptr, \r\n);if (!line_start) return -1;ptr line_start 2;while (*ptr) {char *line_end strstr(ptr, \r\n);if (!line_end) break;char *colon strchr(ptr, :);if (colon) {char *key ptr;int key_len colon - ptr;char *value colon 1;while (*value ) value;int value_len line_end - value;if (req-header_count MAX_HEADERS) {snprintf(req-headers[req-header_count], MAX_HEADER_LEN,%.*s: %.*s, key_len, key, value_len, value);req-header_count;}}ptr line_end 2;// 空行表示body开始if (ptr[0] \r ptr[1] \n) {ptr 2;break;}}// Bodyif (*ptr) {req-body_len strlen(ptr);if (req-body_len MAX_BODY_LEN) {memcpy(req-body, ptr, req-body_len);req-body[req-body_len] \0;}}return 0;}3. 规则引擎c// 添加规则void waf_add_rule(waf_engine_t *waf, int id, rule_type_t type, const char *pattern,const char *target, waf_action_t action, const char *severity,const char *message) {pthread_mutex_lock(waf-mutex);waf_rule_t *rule malloc(sizeof(waf_rule_t));rule-id id;rule-type type;strcpy(rule-pattern, pattern);strcpy(rule-target, target);rule-action action;strcpy(rule-severity, severity);strcpy(rule-message, message);rule-enabled 1;rule-next waf-rules;waf-rules rule;waf-rule_count;pthread_mutex_unlock(waf-mutex);printf([规则] 添加规则 #%d: %s\n, id, message);}// 模式匹配支持正则简化int pattern_match(const char *pattern, const char *text, int nocase) {if (!pattern || !text) return 0;// 纯字符串匹配if (nocase) {char p[512], t[512];strcpy(p, pattern);for (int i 0; p[i]; i) p[i] tolower(p[i]);strcpy(t, text);for (int i 0; t[i]; i) t[i] tolower(t[i]);return strstr(t, p) ! NULL;}return strstr(text, pattern) ! NULL;}// 检查SQL注入模式int detect_sql_injection(const char *text) {const char *patterns[] {select, union, insert, update, delete, drop,from, where, order by, group by, --, ;, or 11, or aa, \ or \1\\1,sleep(, benchmark(, waitfor delay,information_schema, table_name, column_name,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 1)) {return 1;}}return 0;}// 检查XSS模式int detect_xss(const char *text) {const char *patterns[] {script, /script, javascript:, onerror,onload, onmouseover, onclick, onfocus,alert(, prompt(, confirm(, document.cookie,window.location, eval(, innerHTML, document.write,lt;script, #60;script, #x3c;script,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 1)) {return 1;}}return 0;}// 检查路径遍历int detect_path_traversal(const char *text) {const char *patterns[] {../, ..\\, /etc/passwd, /etc/shadow,/proc/, /var/log/, boot.ini, win.ini,%2e%2e%2f, %2e%2e\\, ..%5c,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 0)) {return 1;}}return 0;}// 检查命令注入int detect_cmd_injection(const char *text) {const char *patterns[] {; ls, ; whoami, ; cat, ; echo,| whoami, | ls, whoami, ls,$(cat, $(whoami, cat, whoami,; net user, net user, | net user,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 0)) {return 1;}}return 0;}// 检查SSRFint detect_ssrf(const char *text) {const char *patterns[] {http://127.0.0.1, http://localhost, http://0.0.0.0,http://169.254.169.254, http://metadata, http://[::1],http://192.168., http://10., http://172.16.,file:///etc/, gopher://, dict://, ftp://,NULL};for (int i 0; patterns[i]; i) {if (pattern_match(patterns[i], text, 0)) {return 1;}}return 0;}4. 频率限制c// 频率限制检查int waf_check_rate_limit(waf_engine_t *waf, const char *ip, const char *uri,int limit, int window_seconds) {char key[128];snprintf(key, sizeof(key), %s:%s, ip, uri);time_t now time(NULL);pthread_mutex_lock(waf-mutex);rate_limit_entry_t *entry waf-rate_limits;while (entry) {if (strcmp(entry-key, key) 0) {// 检查是否被阻塞if (entry-blocked now entry-block_until) {pthread_mutex_unlock(waf-mutex);return 1; // 被阻塞}if (entry-blocked now entry-block_until) {entry-blocked 0;entry-count 0;}// 滑动窗口if (now - entry-first_request window_seconds) {entry-first_request now;entry-count 1;pthread_mutex_unlock(waf-mutex);return 0;}entry-count;entry-last_request now;if (entry-count limit) {entry-blocked 1;entry-block_until now 300; // 阻塞5分钟pthread_mutex_unlock(waf-mutex);return 1;}pthread_mutex_unlock(waf-mutex);return 0;}entry entry-next;}// 创建新条目entry malloc(sizeof(rate_limit_entry_t));strcpy(entry-key, key);entry-count 1;entry-first_request now;entry-last_request now;entry-blocked 0;entry-block_until 0;entry-next waf-rate_limits;waf-rate_limits entry;pthread_mutex_unlock(waf-mutex);return 0;}5. 主检测流程c// WAF检测waf_action_t waf_inspect(waf_engine_t *waf, http_request_t *req) {// 1. IP检查// 2. URI检查// 3. Body检查// 4. Headers检查// 5. 频率限制waf_rule_t *rule waf-rules;while (rule) {if (!rule-enabled) {rule rule-next;continue;}const char *text NULL;if (strcmp(rule-target, uri) 0) {text req-uri;} else if (strcmp(rule-target, body) 0) {text req-body;} else if (strcmp(rule-target, ip) 0) {text req-client_ip;} else if (strcmp(rule-target, user-agent) 0) {// 从headers提取User-Agentfor (int i 0; i req-header_count; i) {if (strncasecmp(req-headers[i], User-Agent:, 11) 0) {text req-headers[i] 12;while (*text ) text;break;}}}if (text) {int matched 0;switch (rule-type) {case RULE_SQL_INJECTION:matched detect_sql_injection(text);break;case RULE_XSS:matched detect_xss(text);break;case RULE_PATH_TRAVERSAL:matched detect_path_traversal(text);break;case RULE_CMD_INJECTION:matched detect_cmd_injection(text);break;case RULE_SSRF:matched detect_ssrf(text);break;default:matched pattern_match(rule-pattern, text, 0);break;}if (matched) {printf([WAF] 拦截: %s (规则 #%d) %s - %s\n,rule-severity, rule-id, req-client_ip, rule-message);return rule-action;}}rule rule-next;}return WAF_ALLOW;}6. 测试代码cvoid test_waf() {printf( Web应用防火墙测试 \n\n);waf_engine_t *waf waf_create(./logs);// 添加规则waf_add_rule(waf, 1, RULE_SQL_INJECTION, , uri,WAF_BLOCK, CRITICAL, SQL注入检测);waf_add_rule(waf, 2, RULE_XSS, , body,WAF_BLOCK, HIGH, XSS攻击检测);waf_add_rule(waf, 3, RULE_PATH_TRAVERSAL, , uri,WAF_BLOCK, HIGH, 路径遍历检测);waf_add_rule(waf, 4, RULE_CMD_INJECTION, , uri,WAF_BLOCK, CRITICAL, 命令注入检测);// 测试正常请求http_request_t req1;parse_http_request(GET /index.html HTTP/1.1\r\nHost: example.com\r\nUser-Agent: Mozilla/5.0\r\n\r\n,req1);strcpy(req1.client_ip, 192.168.1.100);printf(正常请求:\n);waf_action_t result waf_inspect(waf, req1);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 测试SQL注入http_request_t req2;parse_http_request(GET /search?q OR 11 HTTP/1.1\r\nHost: example.com\r\n\r\n,req2);strcpy(req2.client_ip, 192.168.1.101);printf(\nSQL注入请求:\n);result waf_inspect(waf, req2);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 测试XSShttp_request_t req3;parse_http_request(POST /comment HTTP/1.1\r\nHost: example.com\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\ntextscriptalert(1)/script,req3);strcpy(req3.client_ip, 192.168.1.102);printf(\nXSS请求:\n);result waf_inspect(waf, req3);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 测试路径遍历http_request_t req4;parse_http_request(GET /download?file../../etc/passwd HTTP/1.1\r\nHost: example.com\r\n\r\n,req4);strcpy(req4.client_ip, 192.168.1.103);printf(\n路径遍历请求:\n);result waf_inspect(waf, req4);printf( 结果: %s\n, result WAF_ALLOW ? 允许 : 拦截);// 频率限制测试printf(\n频率限制测试 (10次请求):\n);int blocked_count 0;for (int i 0; i 10; i) {int blocked waf_check_rate_limit(waf, 192.168.1.100, /api/test, 5, 60);if (blocked) blocked_count;printf( 请求%d: %s\n, i1, blocked ? 拦截 : 允许);}printf( 总拦截: %d 次\n, blocked_count);printf(\n规则统计: %d 条\n, waf-rule_count);free(waf);}int main() {test_waf();return 0;}---三、编译和运行bashgcc -o waf waf.c -lpthread./waf---四、WAF vs 其他安全方案特性 WAF 防火墙 IDS 杀毒软件检测层 应用层 网络层 网络层 文件层检测方式 规则签名 规则 规则异常 签名行为实时拦截 ✅ ✅ ❌ ✅Web攻击检测 ✅ ❌ ❌ ❌部署位置 Web服务器前 网络边界 旁路 主机---五、总结通过这篇文章你学会了· WAF的核心功能规则检测、频率限制、黑白名单· HTTP请求解析· 攻击检测规则SQL注入、XSS、路径遍历、命令注入、SSRF· 频率限制实现· 检测引擎设计Web应用防火墙是应用安全的关键组件。掌握它你就理解了AWS WAF、Cloudflare WAF的底层设计。下一篇预告《从零实现一个容器运行时Docker的核心设计》---评论区分享一下你遇到过最复杂的WAF绕过方式