From cd5a116ca6ac8d2fe6b7645d7189f549ed3d5c9d Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Thu, 7 Jul 2016 09:29:14 -0300 Subject: [PATCH] Simplifies the multi thread sample Now using multi process not multi threads. To be renamed. --- examples/multithread_c/basic_rules.conf | 238 +----------------------- examples/multithread_c/multi.c | 85 ++++----- 2 files changed, 48 insertions(+), 275 deletions(-) diff --git a/examples/multithread_c/basic_rules.conf b/examples/multithread_c/basic_rules.conf index be7a3373..7d1b6dab 100644 --- a/examples/multithread_c/basic_rules.conf +++ b/examples/multithread_c/basic_rules.conf @@ -1,234 +1,14 @@ -# -- Rule engine initialization ---------------------------------------------- - -# Enable ModSecurity, attaching it to every transaction. Use detection -# only to start with, because that minimises the chances of post-installation -# disruption. -# -SecRuleEngine DetectionOnly - - -# -- Request body handling --------------------------------------------------- - -# Allow ModSecurity to access request bodies. If you don't, ModSecurity -# won't be able to see any POST parameters, which opens a large security -# hole for attackers to exploit. -# -SecRequestBodyAccess On - - -# Enable XML request body parser. -# Initiate XML Processor in case of xml content-type -# -SecRule REQUEST_HEADERS:Content-Type "text/xml" \ - "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" - -# Enable JSON request body parser. -# Initiate JSON Processor in case of JSON content-type; change accordingly -# if your application does not use 'application/json' -# -SecRule REQUEST_HEADERS:Content-Type "application/json" \ - "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" - -# Maximum request body size we will accept for buffering. If you support -# file uploads then the value given on the first line has to be as large -# as the largest file you are willing to accept. The second value refers -# to the size of data, with files excluded. You want to keep that value as -# low as practical. -# -SecRequestBodyLimit 13107200 -SecRequestBodyNoFilesLimit 131072 - -# Store up to 128 KB of request body data in memory. When the multipart -# parser reachers this limit, it will start using your hard disk for -# storage. That is slow, but unavoidable. -# -SecRequestBodyInMemoryLimit 131072 - -# What do do if the request body size is above our configured limit. -# Keep in mind that this setting will automatically be set to ProcessPartial -# when SecRuleEngine is set to DetectionOnly mode in order to minimize -# disruptions when initially deploying ModSecurity. -# -SecRequestBodyLimitAction Reject - -# Verify that we've correctly processed the request body. -# As a rule of thumb, when failing to process a request body -# you should reject the request (when deployed in blocking mode) -# or log a high-severity alert (when deployed in detection-only mode). -# -SecRule REQBODY_ERROR "!@eq 0" \ -"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2" - -# By default be strict with what we accept in the multipart/form-data -# request body. If the rule below proves to be too strict for your -# environment consider changing it to detection-only. You are encouraged -# _not_ to remove it altogether. -# -SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ -"id:'200003',phase:2,t:none,log,deny,status:400, \ -msg:'Multipart request body failed strict validation: \ -PE %{REQBODY_PROCESSOR_ERROR}, \ -BQ %{MULTIPART_BOUNDARY_QUOTED}, \ -BW %{MULTIPART_BOUNDARY_WHITESPACE}, \ -DB %{MULTIPART_DATA_BEFORE}, \ -DA %{MULTIPART_DATA_AFTER}, \ -HF %{MULTIPART_HEADER_FOLDING}, \ -LF %{MULTIPART_LF_LINE}, \ -SM %{MULTIPART_MISSING_SEMICOLON}, \ -IQ %{MULTIPART_INVALID_QUOTING}, \ -IP %{MULTIPART_INVALID_PART}, \ -IH %{MULTIPART_INVALID_HEADER_FOLDING}, \ -FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'" - -# Did we see anything that might be a boundary? -# -SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \ -"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'" - -# PCRE Tuning -# We want to avoid a potential RegEx DoS condition -# -SecPcreMatchLimit 1000 -SecPcreMatchLimitRecursion 1000 - -# Some internal errors will set flags in TX and we will need to look for these. -# All of these are prefixed with "MSC_". The following flags currently exist: -# -# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded. -# -SecRule TX:/^MSC_/ "!@streq 0" \ - "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" - - -# -- Response body handling -------------------------------------------------- - -# Allow ModSecurity to access response bodies. -# You should have this directive enabled in order to identify errors -# and data leakage issues. -# -# Do keep in mind that enabling this directive does increases both -# memory consumption and response latency. -# -SecResponseBodyAccess On - -# Which response MIME types do you want to inspect? You should adjust the -# configuration below to catch documents but avoid static files -# (e.g., images and archives). -# -SecResponseBodyMimeType text/plain text/html text/xml - -# Buffer response bodies of up to 512 KB in length. -SecResponseBodyLimit 524288 - -# What happens when we encounter a response body larger than the configured -# limit? By default, we process what we have and let the rest through. -# That's somewhat less secure, but does not break any legitimate pages. -# -SecResponseBodyLimitAction ProcessPartial - - -# -- Filesystem configuration ------------------------------------------------ - -# The location where ModSecurity stores temporary files (for example, when -# it needs to handle a file upload that is larger than the configured limit). -# -# This default setting is chosen due to all systems have /tmp available however, -# this is less than ideal. It is recommended that you specify a location that's private. -# -SecTmpDir /tmp/ - -# The location where ModSecurity will keep its persistent data. This default setting -# is chosen due to all systems have /tmp available however, it -# too should be updated to a place that other users can't access. -# -SecDataDir /tmp/ - - -# -- File uploads handling configuration ------------------------------------- - -# The location where ModSecurity stores intercepted uploaded files. This -# location must be private to ModSecurity. You don't want other users on -# the server to access the files, do you? -# -#SecUploadDir /opt/modsecurity/var/upload/ - -# By default, only keep the files that were determined to be unusual -# in some way (by an external inspection script). For this to work you -# will also need at least one file inspection rule. -# -#SecUploadKeepFiles RelevantOnly - -# Uploaded files are by default created with permissions that do not allow -# any other user to access them. You may need to relax that if you want to -# interface ModSecurity to an external program (e.g., an anti-virus). -# -#SecUploadFileMode 0600 - - -# -- Debug log configuration ------------------------------------------------- - -# The default debug log configuration is to duplicate the error, warning -# and notice messages from the error log. -# -#SecDebugLog /opt/modsecurity/var/log/debug.log -#SecDebugLogLevel 3 - - -# -- Audit log configuration ------------------------------------------------- - -# Log the transactions that are marked by a rule, as well as those that -# trigger a server error (determined by a 5xx or 4xx, excluding 404, -# level response status codes). -# -SecAuditEngine RelevantOnly -SecAuditLogRelevantStatus "^(?:5|4(?!04))" - -# Log everything we know about a transaction. -SecAuditLogParts ABIJDEFHZ - -# Use a single file for logging. This is much easier to look at, but -# assumes that you will use the audit log only ocassionally. -# -SecAuditLogType Serial -SecAuditLog /var/log/modsec_audit.log - -# Specify the path for concurrent audit logging. -#SecAuditLogStorageDir /opt/modsecurity/var/audit/ - - -# -- Miscellaneous ----------------------------------------------------------- - -# Use the most commonly used application/x-www-form-urlencoded parameter -# separator. There's probably only one application somewhere that uses -# something else so don't expect to change this value. -# -SecArgumentSeparator & - -# Settle on version 0 (zero) cookies, as that is what most applications -# use. Using an incorrect cookie version may open your installation to -# evasion attacks (against the rules that examine named cookies). -# -SecCookieFormat 0 - -# Specify your Unicode Code Point. -# This mapping is used by the t:urlDecodeUni transformation function -# to properly map encoded data to your language. Properly setting -# these directives helps to reduce false positives and negatives. -# -SecUnicodeMapFile unicode.mapping 20127 - -# Improve the quality of ModSecurity by sharing information about your -# current ModSecurity version and dependencies versions. -# The following information will be shared: ModSecurity version, -# Web Server version, APR version, PCRE version, Lua version, Libxml2 -# version, Anonymous unique id for host. -SecStatusEngine On - SecDebugLog /dev/stdout SecDebugLogLevel 9 -SecRule REQUEST_HEADERS:User-Agent "^(.*)$" "id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{matched_var},nolog,pass" -SecRule &TX:REAL_IP "@eq 0" "id:'900021',phase:1,t:none,initcol:global=global,initcol:ip=%{remote_addr}_%{tx.ua_hash},setvar:tx.real_ip=%{remote_addr},nolog,pass" -SecRule REQUEST_HEADERS:User-Agent "^(.*)$" "id:'900019',phase:2,t:none,setvar:ip.auth_attempt=+1,nolog,pass" +SecRule REQUEST_HEADERS:User-Agent ".*" "id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}" + +SecAction "phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}" + +SecRule REQUEST_HEADERS:User-Agent ".*" "id:2,phase:2,setvar:ip.auth_attempt=+1" + +SecRule ARGS:foo "herewego" "id:3,phase:2,setvar:ip.foo=bar" +SecRule IP "bar" "id:4,phase:2" +SecRule IP:auth_attempt "bar" "id:5,phase:2" diff --git a/examples/multithread_c/multi.c b/examples/multithread_c/multi.c index a2823b16..c30e7be0 100644 --- a/examples/multithread_c/multi.c +++ b/examples/multithread_c/multi.c @@ -15,45 +15,48 @@ #include #include -#include -#include -#include - #include #include #include #include -#include -#include -#include -#include -#define SHM_SIZE 1024 -#define FORKS 10 -#define TRHREADS 10 + +#define FORKS 5 +#define REQUESTS_PER_PROCESS 100 char main_rule_uri[] = "basic_rules.conf"; Rules *rules = NULL; ModSecurity *modsec = NULL; -key_t key; +void process_special_request (int j) { + Transaction *transaction = NULL; + transaction = msc_new_transaction(modsec, rules, NULL); -void process_request (void *ptr) -{ - int i; - for (i = 0; i < TRHREADS; i++) { + msc_process_connection(transaction, "127.0.0.1", 12345, "127.0.0.1", 80); + msc_process_uri(transaction, + "http://www.modsecurity.org/test?foo=herewego", + "GET", "1.1"); + msc_add_request_header(transaction, "User-Agent", + "Basic ModSecurity example"); + msc_process_request_headers(transaction); + msc_process_request_body(transaction); + msc_add_response_header(transaction, "Content-type", "text/html"); + msc_process_response_headers(transaction, 200, "HTTP 1.0"); + msc_process_response_body(transaction); + msc_process_logging(transaction); + msc_transaction_cleanup(transaction); +} + +void process_request (int j) { + for (int i = 0; i < REQUESTS_PER_PROCESS; i++) { + if (i == 1 && j == 1) { + process_special_request(j); + continue; + } struct timeval tv; - int shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT); - char *data; - int *j; - data = shmat(shmid, (void *)0, 0); - j = (int *)data; - (*j)++; - - Transaction *transaction = NULL; transaction = msc_new_transaction(modsec, rules, NULL); @@ -70,8 +73,9 @@ void process_request (void *ptr) msc_process_response_body(transaction); msc_process_logging(transaction); msc_transaction_cleanup(transaction); - tv.tv_sec = 0; - tv.tv_usec = 1000; + + tv.tv_sec = 1; + tv.tv_usec = 500; select(0, NULL, NULL, NULL, &tv); } } @@ -81,22 +85,12 @@ int main (int argc, char **argv) { int ret = 1; const char *error = NULL; - pthread_t thread[TRHREADS*FORKS]; int i = 0; pid_t pid; - int shmid; - int h; - + int f; + modsec = msc_init(); - key = ftok("shmdemo.c", 'R'); - - shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT); - char *data = shmat(shmid, (void *)0, 0); - memset(data, '\0', SHM_SIZE); - int *z = (int *) data; - z = 0; - msc_set_connector_info(modsec, "ModSecurity-test v0.0.1-alpha (Simple " \ "example on how to use ModSecurity API"); @@ -111,22 +105,21 @@ int main (int argc, char **argv) msc_rules_dump(rules); - for (h = 0; h < FORKS; h++) { + for (f = 0; f < FORKS; f++) { pid = fork(); if (pid == 0) { - pthread_create (&thread[h*TRHREADS], NULL, (void *) &process_request, (void *) NULL); - pthread_join(thread[h*TRHREADS], NULL); + process_request(f); goto child; } + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 500; + select(0, NULL, NULL, NULL, &tv); } wait(NULL); - int *j; - data = shmat(shmid, (void *)0, 0); - j = (int *) data; - fprintf(stderr, "The final count is: %d\n", *j); - child: if (pid == 0) {