Skip to content

Instantly share code, notes, and snippets.

@zimmerle
Created June 25, 2018 20:30
Show Gist options
  • Save zimmerle/e90054b7630099e7aceceb8f0431f754 to your computer and use it in GitHub Desktop.
Save zimmerle/e90054b7630099e7aceceb8f0431f754 to your computer and use it in GitHub Desktop.
Testing ModSecurity speed while loading the rules.
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2018 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address [email protected].
*
*
* gcc -std=c++11 load.cc -o load -I /usr/local/modsecurity/include -L/usr/local/modsecurity/lib -lmodsecurity -lstdc++
*
*
*/
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <modsecurity/modsecurity.h>
#include <modsecurity/rules.h>
#include <modsecurity/rule_message.h>
#include <string>
#include <memory>
#include <chrono>
#define NUM_MERGE 800
#define NUM_RULES 1000
// From: https://gist.github.com/thirdwing/da4621eb163a886a03c5
void process_mem_usage(double& vm_usage, double& resident_set)
{
vm_usage = 0.0;
resident_set = 0.0;
// the two fields we want
unsigned long vsize;
long rss;
{
std::string ignore;
std::ifstream ifs("/proc/self/stat", std::ios_base::in);
ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore \
>> ignore >> ignore >> ignore >> ignore >> ignore >> ignore \
>> ignore >> ignore >> ignore >> ignore >> ignore >> ignore \
>> ignore >> ignore >> ignore >> ignore >> vsize >> rss;
}
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
vm_usage = vsize / 1024.0;
resident_set = rss * page_size_kb;
}
inline std::string fn(int i) {
std::string fn("/tmp/modsec-rules-" \
+ std::to_string(::getpid()) + "-" \
+ std::to_string(i) + ".conf");
return fn;
}
int main(int argc, char **argv) {
std::vector<modsecurity::Rules *> rules;
int i;
modsecurity::Rules *first;
double vm, rss;
for (i = 0; i < NUM_MERGE; i++) {
std::fstream fs;
fs.open (fn(i), std::fstream::in | std::fstream::out | std::fstream::app);
for (int j = 1; j <= NUM_RULES; j++) {
fs << "SecRule ARGS \"a\" \"id:" << std::to_string(j+(NUM_RULES*i));
fs << "\"" << std::endl;
}
fs.close();
}
for (int i = 0; i < NUM_MERGE; i++) {
auto start = std::chrono::high_resolution_clock::now();
modsecurity::Rules *a = new modsecurity::Rules();
if (a->loadFromUri(fn(i).c_str()) < 0) {
std::cout << "Problems loading the rules..." << std::endl;
std::cout << a->m_parserError.str() << std::endl;
return -1;
}
rules.push_back(a);
if (!first) {
first = a;
} else {
a->merge(first);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
process_mem_usage(vm, rss);
// i vm - rss - dt - nr
std::cout << i << "," << vm << ",";
std::cout << rss << "," << elapsed.count();
std::cout << "," << i*NUM_RULES << std::endl;
}
}
for (int i = 0; i < NUM_MERGE; i++) {
std::remove(fn(i).c_str());
}
for (auto a : rules) {
delete a;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment