We are using this syntax in our nginx configuration:
set $logging 1;
if ( $bot_in_log = 0 ) {
set $logging 0;
}
if ( $ip_in_log = 0 ) {
set $logging 0;
}
access_log /var/log/nginx/access.log combined if=$logging;
error_log /var/log/nginx/error.log warn;
However, we receive these messages in our error.log from bad bot requests:
24946#24946: *26106 using uninitialized "logging" variable while logging request, client: 122.34.124.134, server: domain.com, request: "GET /index.html/bwd0GoD HTTP/1.1"
Do we need to set if=$logging; for the error_log as well to avoid these kind of errors from showing up?
Related
I am using nginx lua docker image firesh/nginx-lua:alpine-3.4. And i tried to use environment variable in nginx.config file. Below is the configuration in /etc/nginx/nginx.conf.
user nginx;
env ES_USERNAME;
env ES_PWD;
worker_processes 1;
events {
worker_connections 10240;
}
http {
server {
listen 8080;
server_name localhost;
set_by_lua $es_username os.getenv("ES_USERNAME");
set_by_lua $es_pwd os.getenv("ES_PWD");
location /health {
proxy_pass http://$es_username:$es_pwd#elk-es-http:9200/_cluster/health;
}
...
After launching the container, I see this error in the log:
2021/11/18 01:07:14 [error] 6#6: *6 failed to load inlined Lua code: set_by_lua:1: unexpected symbol near '"http://"', client: 10.0.4.122, server: localhost, request: "GET /health HTTP/1.1", host: "10.0.2.170:8080"
The problem is that the url after proxy_pass is not reading the variable from lua. It treats the ${es_username} as a string rather than read its value. What is the correct way to use that?
That sounds strange. I rather expect both $es_username and $es_pwd variables will have an empty value. set_by_lua expects a function that should return a value, and your returns nothing. The correct usage is
set_by_lua $es_username 'return os.getenv("ES_USERNAME")';
set_by_lua $es_pwd 'return os.getenv("ES_PWD")';
I have the following structure I am working with for NGINX
/etc/nginx
- nginx.conf
- conf.d
- a.conf-disabled (I appended 'disabled' so it wont be used)
- b.conf-disabled (I appended 'disabled' so it wont be used)
- sites-available
- a
- b
- sites-enabled
- a (sym link to sites-available/a)
- b (sym link to sites-available/b)
The nginx.conf file looks like the following:
worker_processes 4;
events {
worker_connections 1024;
}
http {
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
The a file in sites-available looks like the following:
server {
listen 80;
server_name a;
location /a/ {
proxy_pass http://172.17.0.20:5678/;
}
}
and the b file in sites-available looks like the following:
server {
listen 80;
server_name b;
location /b/ {
proxy_pass http://172.17.0.20:5678/;
}
}
I am aware these pointing at the same address, I am just using it because I want to be able to test /a and /b separately.
The problem I am having is that only /a will work and /b fails. If I remove a, then /b works fine.
For example:
curl -X GET http://container-ip/a/ -> WORKS FINE
curl -X GET http://container-ip/b/ -> DOESN'T WORK
I ran logs and its not complaining about anything, but does fail with this when I try to hit /b.
2015/07/13 04:51:59 [error] 235#235: *58 "/etc/nginx/html/b/index.html" is not found (2: No such file or directory), client: 10.0.2.2, server: , request: "GET /b/ HTTP/1.1", host: "localhost:8181"
I am trying to setup a global limit to a certain uri using nginx via openresty
with the following config, if I curl this box I get a 204 no matter how many times I request it per minute.
worker_processes 1;
error_log logs/error.log;
events {
}
http {
log_format spec_format '$request_uri $const $status';
access_log logs/access.log spec_format;#off;
resolver 10.0.0.2;
limit_req_log_level error;
limit_req_zone $const zone=one:100k rate=1r/m;
server {
set $const 1;
listen 80;
location / {
return 200 "invalid url";
}
location ~* /request/? {
limit_req zone=one burst=1 nodelay;
return 204;
}
location /health/ {
return 200 "healthy";
}
}
}
From the docs I can't find anything obvious (Ive tried switching things around a lot).
In case it helps, the box is running on AWS behind an EIP and Ubuntu 13.10. I'm using openresty-1.5.8.1 from openresty.org.
Also, the actual limit I want to work is for around 24000r/s and there are other settings I thought might be conflicting, but even stripped down it doesn't behave like I thought it should.
The problem may be that $const is not yet set when limit_req_zone processes it. Are you seeing the correct $cost value in the log?
The limit_req_module will ignore empty values, from the docs:
The key is any non-empty value of the specified variable (empty values
are not accounted).
I'm trying to figure out how to do the following:
Request is coming in.
HttpLuaModule performs some action against the request. If request is valid than Lua will finish processing with ngx.exit(202). But there are some conditions that may (and will) occur during the processing and nginx might return 403 , 404, 503 Errors.
What I want to do is to write to access logs only requests that have 200 Status code.
Basically I would like to do something like this:
location /foo {
content_by_lua_file "/opt/nginx/lua/process.lua";
if (status == 200) {
access_log "/path/to/the/access_log"
}
I'm very new to both nginx and lua so for me it's a bit of a challenge to figure out where to place and if statement (ether after content_by_lua_file or in side lua file) and what this if statement should look like.
nginx 1.7.0+ allows using an if condition in access_log directive itself.
access_log path [format [buffer=size [flush=time]] [if=condition]];
The if parameter (1.7.0) enables conditional logging.
A request will not be logged if the condition evaluates to “0” or an empty string
Combined with map directive its possible to send log events to different logs based on various conditions.
http {
map $status $normal {
~^2 1;
default 0;
}
map $status $abnormal {
~^2 0;
default 1;
}
map $remote_addr $islocal {
~^127 1;
default 0;
}
server {
access_log logs/access.log combined if=$normal;
access_log logs/access_abnormal.log combined if=$abnormal;
access_log logs/access_local.log combined if=$islocal;
}
}
http://nginx.org/en/docs/http/ngx_http_log_module.html
http://nginx.org/en/docs/http/ngx_http_map_module.html
you can do it by using ngx.log and log_by_lua directives.
location /conditional_log{
log_by_lua 'if ngx.status == 200 then ngx.log(ngx.ERR, "It is 200") end';
content_by_lua 'ngx.say("I am ok") ngx.exit(200)';
}
In the above code, we use log_by_lua which is called while running in log phase. In that if ngx.status == 200, we use ngx.log to trigger the logging using ngx.log.
This will write to error_log. Not sure how to write it to access_log.
For reference
http://wiki.nginx.org/HttpLuaModule#ngx.log
http://wiki.nginx.org/HttpLuaModule#log_by_lua
In every question is a part of answer. You were very close:
if ($status != "200") {
access_log off;
}
Check info for version availability here.
http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
Also, almost all access log format vars are available in "modern" versions:
http://nginx.org/en/docs/http/ngx_http_log_module.html
This is the solution I came up with:
auth.lua
-- Some logic goes here
-- ....
-- ....
ngx.var.return_status = 200
nginx.conf
http {
lua_package_path .....;
lua_package_cpath ....;
rewrite_by_lua_no_postpone on;
server {
set $return_status 1;
location /foo {
rewrite_by_lua_file "<apth_to_aut.lua";
if ($return_status = 200) {
access_log <path_to_access_log> format;
return 200;
}
}
}
}
How can I completely disable logging from HttpLimitConnModule and HttpLimitReqModule?
At least limit the damage done from extensive logging in case of a DOS-attack. I still want some error-logging but not when the request is denied.
Such messages:
2013/07/12 20:20:10 [error] 31544#0: *78 limiting requests, excess: 0.519 by zone "limit", client: *.*.*.*, server: example.com, request: "GET /static.html HTTP/1.1", host: "example.com", referrer: ""
One solution is to enable error_log just where it is needed.
server {
error_log /dev/null crit;
location ~\.php$ {
error_log /var/log/nginx_error.log;
}
}