@@ -251,6 +251,41 @@ ngx_http_modsecurity_cleanup(void *data)
251
251
#endif
252
252
}
253
253
254
+ static int lazy_loading_rules (ngx_http_request_t * r ) {
255
+ int rules ;
256
+ const char * error ;
257
+ ngx_http_modsecurity_conf_t * mcf = ngx_http_get_module_loc_conf (r , ngx_http_modsecurity_module );
258
+ #define show_loaded_rules (message ) \
259
+ if (rules >= 0) { \
260
+ ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, \
261
+ "lazy-load %d rules from %s", rules, message); \
262
+ } else { \
263
+ goto clean; \
264
+ }
265
+
266
+ if (mcf -> rules_loaded != NGX_CONF_UNSET ) {
267
+ return NGX_OK ;
268
+ }
269
+ if (mcf -> rules != NGX_CONF_UNSET_PTR ) {
270
+ rules = msc_rules_add (mcf -> rules_set , mcf -> rules , & error );
271
+ show_loaded_rules (mcf -> rules );
272
+ }
273
+ if (mcf -> rules_set_file != NGX_CONF_UNSET_PTR ) {
274
+ rules = msc_rules_add_file (mcf -> rules_set , mcf -> rules_set_file , & error );
275
+ show_loaded_rules (mcf -> rules_set_file );
276
+ }
277
+ if (mcf -> rules_remote_key != NGX_CONF_UNSET_PTR
278
+ && mcf -> rules_remote_server != NGX_CONF_UNSET_PTR ) {
279
+ rules = msc_rules_add_remote (mcf -> rules_set ,
280
+ mcf -> rules_remote_key , mcf -> rules_remote_server , & error );
281
+ show_loaded_rules (mcf -> rules_remote_server );
282
+ }
283
+ mcf -> rules_loaded = - NGX_CONF_UNSET ;
284
+ return NGX_OK ;
285
+ clean :
286
+ ngx_log_error (NGX_ERROR_ERR , r -> connection -> log , 0 , "cannot load rules: %s" , error );
287
+ return NGX_ERROR ;
288
+ }
254
289
255
290
ngx_inline ngx_http_modsecurity_ctx_t *
256
291
ngx_http_modsecurity_create_ctx (ngx_http_request_t * r )
@@ -273,6 +308,10 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r)
273
308
274
309
dd ("creating transaction with the following rules: '%p' -- ms: '%p'" , mcf -> rules_set , mmcf -> modsec );
275
310
311
+ if (lazy_loading_rules (r ) != NGX_OK ) {
312
+ return NGX_CONF_ERROR ;
313
+ }
314
+
276
315
if (mcf -> transaction_id ) {
277
316
if (ngx_http_complex_value (r , mcf -> transaction_id , & s ) != NGX_OK ) {
278
317
return NGX_CONF_ERROR ;
@@ -325,6 +364,12 @@ ngx_conf_set_rules(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
325
364
return NGX_CONF_ERROR ;
326
365
}
327
366
367
+ if (!ngx_test_config ) {
368
+ mcf -> rules = rules ;
369
+ ngx_log_error (NGX_LOG_NOTICE , cf -> log , 0 , "would lazy-load rules %s" , rules );
370
+ return NGX_CONF_OK ;
371
+ }
372
+
328
373
old_pool = ngx_http_modsecurity_pcre_malloc_init (cf -> pool );
329
374
res = msc_rules_add (mcf -> rules_set , rules , & error );
330
375
ngx_http_modsecurity_pcre_malloc_done (old_pool );
@@ -359,6 +404,12 @@ ngx_conf_set_rules_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
359
404
return NGX_CONF_ERROR ;
360
405
}
361
406
407
+ if (!ngx_test_config ) {
408
+ mcf -> rules_set_file = rules_set ;
409
+ ngx_log_error (NGX_LOG_NOTICE , cf -> log , 0 , "would lazy-load rules file %s" , rules_set );
410
+ return NGX_CONF_OK ;
411
+ }
412
+
362
413
old_pool = ngx_http_modsecurity_pcre_malloc_init (cf -> pool );
363
414
res = msc_rules_add_file (mcf -> rules_set , rules_set , & error );
364
415
ngx_http_modsecurity_pcre_malloc_done (old_pool );
@@ -398,6 +449,13 @@ ngx_conf_set_rules_remote(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
398
449
return NGX_CONF_ERROR ;
399
450
}
400
451
452
+ if (!ngx_test_config ) {
453
+ mcf -> rules_remote_key = rules_remote_key ;
454
+ mcf -> rules_remote_server = rules_remote_server ;
455
+ ngx_log_error (NGX_LOG_NOTICE , cf -> log , 0 , "would lazy-load remote rules %s" , rules_remote_server );
456
+ return NGX_CONF_OK ;
457
+ }
458
+
401
459
old_pool = ngx_http_modsecurity_pcre_malloc_init (cf -> pool );
402
460
res = msc_rules_add_remote (mcf -> rules_set , rules_remote_key , rules_remote_server , & error );
403
461
ngx_http_modsecurity_pcre_malloc_done (old_pool );
@@ -691,6 +749,11 @@ ngx_http_modsecurity_create_conf(ngx_conf_t *cf)
691
749
692
750
conf -> enable = NGX_CONF_UNSET ;
693
751
conf -> rules_set = msc_create_rules_set ();
752
+ conf -> rules = NGX_CONF_UNSET_PTR ;
753
+ conf -> rules_set_file = NGX_CONF_UNSET_PTR ;
754
+ conf -> rules_remote_key = NGX_CONF_UNSET_PTR ;
755
+ conf -> rules_remote_server = NGX_CONF_UNSET_PTR ;
756
+ conf -> rules_loaded = NGX_CONF_UNSET ;
694
757
conf -> pool = cf -> pool ;
695
758
conf -> transaction_id = NGX_CONF_UNSET_PTR ;
696
759
#if defined(MODSECURITY_SANITY_CHECKS ) && (MODSECURITY_SANITY_CHECKS )
@@ -742,6 +805,19 @@ ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child)
742
805
dd ("CHILD RULES" );
743
806
msc_rules_dump (c -> rules_set );
744
807
#endif
808
+
809
+ #define ngx_conf_merge_ptr_value_if_unset (conf , prev , message ) \
810
+ if (conf != NGX_CONF_UNSET_PTR && prev != NGX_CONF_UNSET_PTR) { \
811
+ return "cannot use " message " on both parent and child"; \
812
+ } else { \
813
+ ngx_conf_merge_ptr_value(conf, prev, NGX_CONF_UNSET_PTR); \
814
+ }
815
+
816
+ ngx_conf_merge_ptr_value_if_unset (c -> rules , p -> rules , "modsecurity_rules" );
817
+ ngx_conf_merge_ptr_value_if_unset (c -> rules_set_file , p -> rules_set_file , "modsecurity_rules_file" );
818
+ ngx_conf_merge_ptr_value_if_unset (c -> rules_remote_key , p -> rules_remote_key , "modsecurity_rules_remote" );
819
+ ngx_conf_merge_ptr_value_if_unset (c -> rules_remote_server , p -> rules_remote_server , "modsecurity_rules_remote" );
820
+
745
821
rules = msc_rules_merge (c -> rules_set , p -> rules_set , & error );
746
822
747
823
if (rules < 0 ) {
0 commit comments