Install modsecurity on nginx - nginx

Today, I installed mod_security for nginx. I added the following block to /etc/nginx/nginx:
server {
listen 80;
server_name localhost;
location / {
ModSecurityEnabled on;
ModSecurityConfig modsecurity.conf;
}
}
After restarting Nginx, I got the following error:
nginx: [emerg] unknown directive "ModSecurityEnabled" in /etc/nginx/conf.d/nginx.conf:6
nginx: configuration file /etc/nginx/nginx.conf test failed
Output of nginx -V:
nginx version: nginx/1.4.7
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables'
What is going wrong?

According to the official documentation:
The extensibility model of the nginx server does not include dynamically loaded modules, thus ModSecurity must be compiled with the source code of the main server. Since nginx is available on multiple Unix-based platforms (and also on Windows), for now the recommended way of obtaining ModSecurity for nginx is compilation in the designated environment.
Source: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#Installation_for_NGINX
You can not just add some lines in nginx.conf to get it working.
You might also want to consider the following if you want to be helped more efficiently and in the meantime participate in making Stack Overflow a better place:
Read the docs before asking for help (it took me 3 minutes to figure out the way it works).
Choose a more explicit title for your issue.
Try to auto-correct the content to make it easier to read.
Good luck!

I did this on NGinx plus, so not sure if entirely identical but it seems so ...
Yum install nginx-modsecurity (for nginx plus its nginx-plus-module-modsecurity)
Add load_module modules/ngx_http_modsecurity_module.so; to top level of /etc/nginx/nginx.conf - Outside of the server block
Then, within your server block
modsecurity on;
modsecurity_rules_file /some/path/to/rules/modsecurity-recommended.conf
You can get the suggested contents for modsecurirty-recommended from: https://docs.nginx.com/nginx-waf/admin-guide/nginx-plus-modsecurity-waf-owasp-crs/
This is working for me at the moment, hope it helps

Related

Should reloading nginx config only work when changing config file specified on start?

Based on what I've read, it looks like I should be able to specify a new configuration file path when running nginx reload:
sudo nginx -c ${config_file_path} -s reload
But what I'm finding is that the config argument will only set the config to be loaded when initially starting nginx. So if I started nginx using...
sudo nginx -c /path/to/first/config/nginx.conf
Then later I create a different path /path/to/second/config/nginx.conf and try to run...
sudo nginx -c /path/to/second/config/nginx.conf -s reload
The second configuration is not loaded. In my logs/errors.log I see [notice] PID/PID: signal process started, but what's reloaded are really changes to /path/to/first/config/nginx.conf, even though I specified the second config in the reload call.
Is this expected behavior? Namely that -c argument when starting nginx will set the configuration value to be used until nginx is stopped, and the parameter really has no effect on subsequent reload calls?
For what it's worth, this is my nginx version information:
nginx version: openresty/1.19.9.1
built by gcc 7.3.1 20180712 (Red Hat 7.3.1-13) (GCC)
built with OpenSSL 1.1.1k 25 Mar 2021 (running with OpenSSL 1.1.1l 24 Aug 2021)
TLS SNI support enabled
arguments:
--prefix=/usr/local/openresty/nginx
--with-cc-opt='-O2
-DNGX_LUA_ABORT_AT_PANIC
-I/usr/local/openresty/zlib/include
-I/usr/local/openresty/pcre/include
-I/usr/local/openresty/openssl111/include'
--add-module=../ngx_devel_kit-0.3.1
--add-module=../echo-nginx-module-0.62
--add-module=../xss-nginx-module-0.06
--add-module=../ngx_coolkit-0.2
--add-module=../set-misc-nginx-module-0.32
--add-module=../form-input-nginx-module-0.12
--add-module=../encrypted-session-nginx-module-0.08
--add-module=../srcache-nginx-module-0.32
--add-module=../ngx_lua-0.10.20
--add-module=../ngx_lua_upstream-0.07
--add-module=../headers-more-nginx-module-0.33
--add-module=../array-var-nginx-module-0.05
--add-module=../memc-nginx-module-0.19
--add-module=../redis2-nginx-module-0.15
--add-module=../redis-nginx-module-0.3.7
--add-module=../ngx_stream_lua-0.0.10
--with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib
-L/usr/local/openresty/zlib/lib
-L/usr/local/openresty/pcre/lib
-L/usr/local/openresty/openssl111/lib
-Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl111/lib'
--with-cc='ccache
gcc
-fdiagnostics-color=always'
--with-pcre-jit
--with-stream
--with-stream_ssl_module
--with-stream_ssl_preread_module
--with-http_v2_module
--without-mail_pop3_module
--without-mail_imap_module
--without-mail_smtp_module
--with-http_stub_status_module
--with-http_realip_module
--with-http_addition_module
--with-http_auth_request_module
--with-http_secure_link_module
--with-http_random_index_module
--with-http_gzip_static_module
--with-http_sub_module
--with-http_dav_module
--with-http_flv_module
--with-http_mp4_module
--with-http_gunzip_module
--with-threads
--with-compat
--with-stream
--with-http_ssl_module
The config file path feed into nginx -c is mostly let the ad-hoc nginx process know where to read the pid file(it's pid directive inside config file), not for the daemon nginx process reloading config.

nginx different locations from totally different folder in filesystem

I am currently serving an Application for one domain name using nginx.
I need to serve a completely different Application in a specific location, but that second App is located in a completely different folder in the filesystem.
I understand the differences between root and alias thanks to this very well explained answer so I opted to use alias
The config file looks something like:
server {
server_name myapp.dev;
root /home/apps/myapp/build;
error_log /home/apps/omg-errors.log warn;
index index.htm index.html;
error_page 403 404 /404.html;
location /admin {
alias /home/apps/admin/;
}
}
I already tried using root, removing the /admin part at the end of the path pointing to and also tried adding the trailing / at the end of the location, like:
location /admin/ {
...
# also this:
root /home/apps/;
}
The important and curious part
is that the same configuration works pretty well using nginx in my local machine where the config looks like:
server {
listen 80;
server_name myapp.local;
root /Users/lio/Projects/MyApp/my-app-static/build;
error_log /Users/lio/Projects/MyApp/myapp-error.log warn;
index index.htm index.html;
location /admin {
alias /Users/lio/Desktop/test-admin;
}
}
Logs
Here are the error-logs catched when trying to access the /admin path:
2020/02/26 04:16:57 [error] 5704#0: *7619 open() "/home/apps/myapp/build/admin" failed (2: No such file or directory), client: xxx.xxx.xxx.xxx, server: myapp.dev, request: "GET /admin HTTP/2.0", host: "myapp.dev"
Environment
Don't know if could be the fact of different OS and software versions, however here are the details provided by nginx -V:
Local
nginx version: nginx/1.15.10
built by clang 10.0.1 (clang-1001.0.46.3)
built with OpenSSL 1.0.2r 26 Feb 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.15.10 --sbin-path=/usr/local/Cellar/nginx/1.15.10/bin/nginx --with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl/include' --with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-compat --with-debug --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-ipv6 --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module
Server
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-google_perftools_module --add-module=/builddir/build/BUILD/nginx-1.14.0/passenger-5.3.7/src/nginx_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
On your second snippet, you should also provide the /admin folder, as follow:
location /admin/ {
...
# also this:
root /home/apps/admin;
}
Otherwise, to access the admin area, you'd need to type yourdomain.tld/admin/admin (as the last /admin) is the missing /admin in your root /home/apps declaration.
Would that suffice to work for you?
After lots of try / catch I found the trick, and that is ^~.
location ^~ /admin/ {
alias /home/apps/admin/;
}
Simple but (at least for me) tricky.
Here are two articles/posts that helped me to understand better the location issue.

NginX GeoIP Module Config - load_module not allowed on First Line of Conf

My nginx conf looks like this:
include /usr/share/nginx/modules/mod-http-geoip.conf;
server {
}
server {
}
I had installed mod-http-geoip via sudo yum install nginx-mod-http-geoip
and i have these:
/usr/share/nginx/modules/mod-http-geoip.conf:
load_module "/usr/lib64/nginx/modules/ngx_http_geoip_module.so";
/usr/lib64/nginx/modules/ngx_http_geoip_module.so
The error I get:
2018/07/09 09:37:14 [emerg] 9552#0: "load_module" directive is not allowed here in /usr/share/nginx/modules/mod-http-geoip.conf:1
This is my nginx -V :
[root#ip-172-31-45-46 modules]# nginx -V
nginx version: nginx/1.12.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E'
Note that the above had "--with-http_geoip_module=dynamic" argument
Can someone point what im missing?
I followed Peter Jones' answer on this post: How to enable dynamic module with an existing NGINX installation
I also tried:
- Putting load_module "/usr/lib64/nginx/modules/ngx_http_geoip_module.so";
in the first line of my .conf file.
- putting load_module "/usr/lib64/nginx/modules/ngx_http_geoip_module.so";
inside the server { }
All giving me the same error, "load_module" directive is not allowed here
Do I need to run ./configure command, make or anything?
Based on all the information so far, you have installed nginx from EPEL repository. While there's nothing wrong with that, I would suggest to install it from nginx's own YUM repository as it's:
coming from the software's developer
more recent (as I see now the nginx own repo is with 1.14.0 while epel's is on 1.12.2)
So make sure you install nginx properly.
Every nginx distribution tends to have their own convention for structuring files. But nginx configuration rules are the same across the board. So:
include /usr/share/nginx/modules/mod-http-geoip.conf;
server {
}
server {
}
... isn't really possible, as server block should go within http section.
The load_module should be placed at the top level (beginning of the file) within /etc/nginx/nginx.conf.
If you can't move from / want to stick to EPEL's nginx distribution
The EPEL nginx package convention is to include those load_module directives from each module's .conf file:
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
After a module is installed, it drops a .conf file with load_module to load it.
Make sure that include goes at the top of your nginx configuration and not inside any section.
/usr/share/nginx/modules is really just a symlink to /usr/lib64/nginx/modules and Nginx is expecting to find the actual modules in there, not config directives.
Looking at your config above I would expect the path to your config file for dynamic modules to be /etc/nginx/modules-enabled, or you can include them in the very top section of your nginx.conf, above the events block.

Nginx unknown directive "if"

On my Nginx server, in order to save time, I made etc/nginx/include.conf and put this line in etc/nginx/sites-available/site1.conf:
location / {
include /etc/nginx/include.conf;
try_files $uri $uri/ /index.php?page=$uri;
}
The content of include.conf :
if ($http_referer ~* (badreferers)) {
return 403;
}
When testing the conf file, this error emerges:
[emerg] unknown directive "if" in /etc/nginx/include.conf:1
When I put the if statement directly in etc/nginx/sites-available/site1.conf, it doesn't give an error.
What could be wrong here?
Update:
nginx -V gives:
nginx version: nginx/1.4.6 (Ubuntu) built by gcc 4.8.4 (Ubuntu
4.8.4-2ubuntu1~14.04.3) TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_spdy_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module
You use old nginx version 1.4. On modern 1.10.2 your config works fine.
I've checked the sources of nginx. The "include" directive isn't just replaced with content of included file. It is processed differently depending on context. So there are definitely some restrictions of what you may put in included file. At least in your nginx version.
As nginx documentation says
Included files should consist of syntactically correct directives and
blocks.
if is part of http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if . you will need to add the rewrite module into your nginx.
Or better us the official package from nginx them self
http://nginx.org/en/linux_packages.html#stable
It looks like you have somewhere in nginx config files line like
include /etc/nginx/*.conf;
So your file /etc/nginx/include.conf is included not only in /etc/nginx/sites-available/site1.conf but somewehere else where "if" directive is invalid and you get error.

why does spdy not function here with nginx 1.5.10?

i have compiled nginx 1.5.10 with the spdy module on centos 6.5 and it is operating without a problem, as far as i know except, that spdy is apparently not being used.
i have added the 'spdy' option to the listen directive in nginx.conf and restarted the server, yet the various spdy checking methods, such as the firefox plugin that is available and also the website: https://spdycheck.org/
both show that spdy is not being used on my site.
the line in nginx.conf is:
listen 443 ssl spdy default_server;
i saw this thread: How to set up SPDY Protocol over Nginx?
and looked to see if i needed to change the DAEMON or PATH lines in /etc/init.d/nginx - yet in my versions those lines are not present at all.
the output of nginx -V is:
nginx version: nginx/1.5.10
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g'
any tips welcomed!
SPDY/3.1 isn't supported by Firefox 26. The support was added to Firefox in version 27, see release notes.

Resources