问题描述
是否可以将libmodsecurity用作库并自行处理请求?我搞砸了仓库ModSecurity examples中的示例,但无法弄清楚如何使它接受我的请求。我尝试了simple_example_using_c.c,但没有成功。有人知道这是否可能吗?
#include <stdio.h>
#include <stdlib.h>
#include <modsecurity/modsecurity.h>
#include <modsecurity/rules_set.h>
char rulez[] ="basic_rules.conf";
const char *request = "" \
"GET /?test=test HTTP/\n" \
"Host: localhost:9999\n" \
"Content-Length: 27\n" \
"Content-Type: application/x-www-form-urlencoded\n";
int main(){
ModSecurity *modsec;
RulesSet *setRulez;
Transaction *transakcyja;
const char *error;
modsec = msc_init();
printf(msc_who_am_i(modsec));
msc_set_connector_info(modsec,"ModSecurity simple API");
setRulez = msc_create_rules_set();
int rulz = msc_rules_add_file(setRulez,rulez,&error);
if(rulz == -1){
fprintf(stderr,"huston rulez problem \n");
fprintf(stderr,"%s\n",error);
return -1;
}
msc_rules_dump(setRulez);
transakcyja = msc_new_transaction(modsec,setRulez,NULL);
if(transakcyja == NULL){
fprintf(stderr,"Init bad");
return -1;
}
msc_process_connection(transakcyja,"127.0.0.1",9998,9999);
msc_process_uri(transakcyja,"http://127.0.0.1:9999/?k=test&test=test","GET","1.1");
msc_process_request_body(transakcyja);
msc_process_response_headers(transakcyja,200,"HTTP 1.3");
msc_process_response_body(transakcyja);
msc_process_logging(transakcyja);
msc_rules_cleanup(setRulez);
msc_cleanup(modsec);
return 0;
}
编辑:我现在知道更多了,但是,有人知道如何将请求传递到事务吗?我知道有addRequestHeader(),但当时只需要一个标头,我真的无法弄清楚。
解决方法
我认为您必须了解ModSecurity的工作原理。
所有交易分为五个阶段:
- 解析请求标头
- 解析请求正文
- 解析响应头
- 解析响应正文
- 创建日志(并检查交易变量,例如异常评分(对于CRS))
(还有阶段0:处理连接本身。)
在示例中,您可以看到每个阶段的几个功能。
这是一个常见的HTTP请求:
POST /set.php HTTP/1.1
Host: foobar.com
User-Agent: something
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
a=1&b=2
现在,如果您已经创建了交易对象,则必须向其中添加阶段数据。
首先请查看状态行,并添加必要的部分-考虑您的应用程序已经具有该信息,例如客户端IP(std::string cip
),端口(int cport
)和服务器IP({{1 }}),端口(std::string dip
)。您还具有URI(int dport
),方法(std::string uri
)和协议版本(std::string method
)。您还需要一个类型为std::string vers
的对象。
modsecurity::ModSecurityIntervention *it
现在,您必须检查 // phase 0
trans->processConnection(cip.c_str(),cport,dip.c_str(),dport);
trans->processURI(uri.c_str(),method.c_str(),vers.c_str());
trans->intervention(it);
变量,例如。 it
。有关更多信息,请检查source。
现在考虑您有一个包含已解析标头的变量(列表)。现在,您必须将这些标头一一添加到事务中:
it.status
现在,您可以处理标题并检查结果。请注意,如果您处理阶段,则引擎会评估所有与 for(your_iterator it=headerType.begin(); it != headerType.end(); ++it) {
const std::string key = it->first.as<std::string>(); // key
const std::string val = it->second.as<std::string>(); // val
trans->addRequestHeader(key,val);
}
值相关的规则:1、2、3、4或5。
phase
在接下来的步骤中,您必须添加并处理请求主体,然后(从上游)获取响应头和主体,并重复上述步骤...
希望现在您可以看到它是如何工作的。
我制作了一个实用程序,它在使用CRS test cases的同时在libmodecurity3上运行CRS rules。此处提供了该工具:ftwrunner。
希望这会有所帮助。