nginx: [emerg] unknown "bytes_received" variable - nginx

I try to log the amount of bytes received from a client in Nginx like so:
log_format postdata '$remote_addr sent $bytes_received bytes';
However, I get the following error when attempting to start the service:
nginx: [emerg] unknown "bytes_received" variable
As far as I can see this variable should be present from Nginx 1.11.4. I run 1.13.9:
#:/usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.13.9
Output of nginx -V:
:~# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.13.9
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
built with OpenSSL 1.0.2g 1 Mar 2016
TLS SNI support enabled
configure arguments: --with-http_ssl_module --with-pcre --with-http_realip_module --with-stream --add-module=../nchan
Is there something I am missing here?
Thanks for any help!

PS: Using answers as comments as I need to post large text
Seems like you have it compiled from source and a required module is missing. I have below output on the same
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --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_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads
So make sure you have all the stream modules at least and may be some other module is a pre-requisite for this to work

$request_length may be what you want:
request length (including request line, header, and request body)
This logs the size of the request received from the client without hitting the unknown variable issue, if you're using a build of Nginx which doesn't have ngx_stream_core_module built in.
In other words $request_length (rather than $bytes_received) seems to be the counterpart to $bytes_sent, somewhat confusingly.

Related

NGINX Unknown Directive Stream

I'm trying to setup a UDP Load Balancer using NGINX (1.12.1).
However I'm getting an error...
[ec2-user#ip-172-31-0-184 nginx]$ sudo service nginx start Starting
nginx: nginx: [emerg] unknown directive "stream" in
/etc/nginx/conf.d/load-balancer.conf:1
Here is the config I'm trying to use:
stream {
upstream backend1 {
server 10.0.1.50:450;
}
upstream backend2 {
server 10.0.1.50:500;
}
# This server accepts all traffic to port 80 and passes it to the upstream.
# Notice that the upstream name and the proxy_pass need to match.
server {
listen 500 udp;
proxy_pass backend2;
}
server {
listen 4500 udp;
proxy_pass backend1;
}
}
And here is the output of nginx -V, to verify that stream is installed.
[ec2-user#ip-172-31-0-184 nginx]$
th=/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'
Can anyone please help me?
Install the following package then your issue vanished
yum install nginx-mod-stream.x86_64
The stream { ... } block is a top-level block. The files included from /etc/nginx/conf.d/ are probably included into the http { ... } block. Check your nginx.conf file (probably located in /etc/nginx), and locate the include directives.

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.

How can I prevent nginx from serving http/2?

I am working on implementing http/2 for an ecommerce website my company made. I'm hosting it on debian jessie and found that it's now pretty easy to get nginx from the backports repo which was built against openssl 1.0.2 to support ALPN (which is necessary these days to work with chrome).
So I upgraded my libssl and then my nginx. To my great surprise, nginx now seems to be serving my content through http2 even though I didn't add that keyword to the config. Chrome's dev tools show h2 in the protocol column of the network tab.
Normally I would be happy about that, but I'd like to make some comparison measurements between http1.1 and http2. How can I force it to serve http1.1 again (temporarily) to make my measurements?
Edit: adding output of nginx -V to be specific about my version
$ nginx -V
nginx version: nginx/1.9.10
built with OpenSSL 1.0.2h 3 May 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-fPIE -pie -Wl,-z,relro -Wl,-z,now' --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_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/build/nginx-1.9.10/debian/modules/nginx-auth-pam --add-module=/build/nginx-1.9.10/debian/modules/nginx-dav-ext-module --add-module=/build/nginx-1.9.10/debian/modules/nginx-echo --add-module=/build/nginx-1.9.10/debian/modules/nginx-upstream-fair --add-module=/build/nginx-1.9.10/debian/modules/ngx_http_substitutions_filter_module
According to the documentation:
The http2 parameter (1.9.5) configures the port to accept HTTP/2 connections.
Thus any virtual server configured on this port will accept HTTP/2 connections. If you want to configure some hosts with HTTP/2 but other without, then you have to use different IP or ports.

NGINX + HTTP/2 working partially

I just compiled a custom version of nginx for our new project.
NGINX -V:
nginx version: nginx/1.9.15
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.2g 1 Mar 2016
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_v2_module --with-openssl=/usr/src/openssl-1.0.2g --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --add-module=/usr/local/src/naxsi-master/naxsi_src/ --add-module=/root/custom-nginx/nginx-1.9.15/src/http/modules/ngx_pagespeed-release-1.11.33.0-beta
On the browsers from my work office http2 works fine. When I go home and test on my pc, http2 does not work in any browser. I cannot understand where the problem is.
I have the same windows 7, same browsers, everything the same.
Can somebody point me out the problem I am facing ?
Many Thanks.
Can think of two reasons why this might happen:
You are using anti virus software at home which performs MITM interception to enable it to scan traffic. See here: https://serverfault.com/questions/752767/trying-to-setup-http2-on-apache.
You are using a LoadBalancer or other such infrastructure that sits in front of your nginx server, when accessed externally.

Install modsecurity on 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

Resources