Configure nginx and luameter not working - nginx

I am just beginner.I am trying to configure nginx and luameter for monitoring nginx.
Here are the step I follow :
1). Compile openresty
2). And configure luameter and nginx using this guide : luameter
I put this code to my nginx configuration :
http {
...
lua_shared_dict luameter 1m;
lua_package_path "{CHANGE_ME}?.luac";
init_by_lua "luameter = require 'luameter'";
log_by_lua "luameter.mark_by_host(); luameter.mark_by_path(1)";
...
}
server {
listen 127.0.0.1:8001;
location / {
root /opt/luameter;
}
location /stats {
content_by_lua "luameter.get_stats('/stats');";
expires -1;
}
}
I change {CHANGE_ME} to /opt/luameterbut it's not working.

I'm in the process of setting this up too, and according to some examples I found the text {CHANGE_ME}? should be replaced with /opt/luameter/luac/luameter. So the lua_package_path line becomes:
lua_package_path "/opt/luameter/luac/luameter.luac";

Related

How to drop path in rewrite and proxy pass the args in nginx

Example request - http://localhost/iframe?ip=192.168.0.237
I want to proxy pass the request to the value of IP and remove the path and args after localhost/ .
Ideally the proxy_pass should point to 192.168.0.237 and the URL should be http://localhost/.
localhost /iframe {
rewrite ^/(iframe/.*)$ http://localhost/ permanent;
proxy_pass $arg_ip;
}
I'm not sure whether rewrite is the proper way to address this problem.
I would use the argument ip and a rewrite to remove the iframe location
server {
listen 8085;
location /iframe {
rewrite ^/iframe(.*)$ /$1 break;
proxy_pass http://$arg_ip;
}
}
server {
listen 8080;
location / { return 200 "$host$uri"; }
}
Security Notice
I just have a feeling you should whilelist the upstream servers accepted as arguments. If not this will be a wildcard proxy to every single http-server reachable in the network. This is a easy to use SSRF attack vector. So please add some extra layer of security.
SSRF Explained:
Let's say we use this configuration without any further security. Given the folowing NGINX config:
server {
listen 8085;
location /iframe {
rewrite ^/iframe(.*)$ /$1 break;
proxy_pass http://$arg_ip;
}
}
# Server for iframe service
server {
listen 8080;
root /usr/share/nginx/;
location / { return 200 "$host$uri\n"; }
}
# Private Server Section here!
server {
listen 8086;
allow 127.0.0.1;
deny all;
.....
location / {
index welcome.html;
}
}
Trying to reach the secret server directly
curl -v EXTERNALIP:8086
will fail with HTTP 403.
The NGINX will just allow connections form localhost/127.0.0.1 as defined in the allow/deny directives.
But lets try the iframe with the ip argument.
$# curl localhost:8085/iframe?ip=127.0.0.1:8086
Welcome to our very secure server! Internals only!
It prints the content of the secret server. Whitlisting a proxy-pass like this is never a good idea regardless its working or not.

NGINX virtual hosts with seperate lua_package_path variables

I'm trying to serve two (Openresty) Lua web applications as virtual hosts from NGINX which both require their own unique lua_package_path, but have a hard time getting the configuration right.
# Failing example.conf
http {
lua_package_path = "/path/to/app/?.lua;;"
server{
listen 80;
server_name example.org
}
}
http {
lua_package_path = "/path/to/dev_app/?.lua;;"
server{
listen 80;
server_name dev.example.org
}
}
If you define the http twice (one for each host), you will receive this error: [emerg] "http" directive is duplicate in example.conf
If you define the lua_package_path inside the server block, you will receive this error: [emerg] "lua_package_path" directive is not allowed here in example.conf
If you define the lua_package_path twice in a http block (which does not make any sense anyway), you will receive this error: [emerg] "lua_package_path" directive is duplicate in example.conf
What is the best practise of serving multiple (Openresty) Lua applications with their own lua_package_path, being virtual hosts on the same IP and port?
I faced this issue several month ago.
I do not recommend no use debug and release projects in the same server. For instance, you launch the one nginx application for both (debug and release) key may lead to unexpectable behaviour.
But, nevertheless, you can setup:
package.path = './mylib/?.lua;' .. package.path inside lua-script.
You can setup your own local DEBUG = false state and manage inside the app.
Obviously, use the other machine for debug. Imo, the best solution.
Execute different my.release.lua or my.debug.lua file:
http {
lua_package_path "./lua/?.lua;/etc/nginx/lua/?.lua;;";
server{
listen 80;
server_name dev.example.org;
lua_code_cache off;
location / {
default_type text/html;
content_by_lua_file './lua/my.debug.lua';
}
}
server{
listen 80;
server_name example.org
location / {
default_type text/html;
content_by_lua_file './lua/my.release.lua';
}
}
}
Fixed it removing the lua_package_path from the NGINX configuration (since the OpenResty bundle already takes care of loading packages) and pointing my content_by_lua_file to the absolute full path of my app: /var/www/app/app.lua
# example.conf
http {
server{
listen 80;
server_name example.org
location / {
content_by_lua_file '/var/www/app/app.lua';
}
}
server{
listen 80;
server_name dev.example.org
location / {
content_by_lua_file '/var/www/app_dev/app.lua';
}
}
}
After that I included this at the top of my app.lua file:
-- app.lua
-- Get the current path of app.lua
local function script_path()
local str = debug.getinfo(2, "S").source:sub(2)
return str:match("(.*/)")
end
-- Add the current path to the package path
package.path = script_path() .. '?.lua;' .. package.path
-- Load the config.lua package
local config = require("config")
-- Use the config
config.env()['redis']['host']
...
This allows me to read the config.lua from the same directory as my app.lua
-- config.lua
module('config', package.seeall)
function env()
return {
env="development",
redis={
host="127.0.0.1",
port="6379"
}
}
end
Using this I can now use multiple virtual hosts with their own package paths.
#Vyacheslav Thank you for the pointer to package.path = './mylib/?.lua;' .. package.path! That was really helpful! Unfortunately it also kept using the NGINX conf root instead of my application root. Even with prepending the . for the path.

Nginx location part not being replaced in proxy_pass when using variable

I have a service listening on myservice.mycompany.local
We're proxifying request like this
server {
listen 80;
location /myservice/ {
proxy_pass http://myservice.mycompany.local/;
}
}
it all works fine requests on public.mycompany.com/myservice/api/1/ping are correctly transformed into request to http://myservice.mycompany.local/api/1/ping as there is the trailing /
but now if we try to use a variable
server {
listen 80;
set $MY_SERVICE "myservice.mycompany.local";
location /acm/ {
proxy_pass http://$MY_SERVICE/;
}
}
the local service will only receive a requests to / with the URI part being lost
I've been able to reproduce this "problem" with several version of nginx
1.8.1-1~wheezy
1.4.6-1ubuntu3.5
I'm able also to reproduce it locally by replacing the proxified service by a simple nc -l 127.0.0.2 8080 and using it as the value of my variable, so it really seems to be something happening inside nginx
And this behaviour is not covered in http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
You may have discovered an undocumented feature, but you can always use a rewrite ... break instead of proxy_pass aliasing:
server {
listen 80;
set $MY_SERVICE "myservice.mycompany.local";
location /acm {
rewrite ^/acm(/.*)$ $1 break;
proxy_pass http://$MY_SERVICE;
}
}

How to look for a certain header in nginx

I'm using nginx as a proxy server to basically serve image files and hand off everything else to another server at port 9000.
What I want to do is have nginx return an HTTP 500 error code if the incoming request does not contain a specific header (X-AUTH-TOKEN), but only if the requests are not for the resources "/register" or "/events". In that case, they need to go straight to port 9000.
Here's the configuration I currently have:
http {
sendfile on;
upstream my-backend {
server 127.0.0.1:9000;
}
# main ngingx server
server {
server_name localhost;
location / {
proxy_pass http://my-backend;
}
location /images/ {
root /home/images;
}
}
}
Any idea how to implement this kind of logic? Thanks.
There is native HttpCoreModule feature exists:
You can check any header exists/match by something like this:
location /blah {
if ( $http_x_auth_token ) {
// do something, allow
}
}
http://wiki.nginx.org/HttpCoreModule#.24http_HEADER
Hope it will help :)

nGINX read Header & Pass it to different Application Server

I have an nGINX server running. I want to read custom HTTP Header from the incoming Request and redirect it to different application server. I did search for similar questions but found for writing custom headers but not how to read..
if a header is set with this -> "version = Version 1.0" then it should redirect different application (say uwsgi_pass x.x.x.x:80)
if it is set as "version = Version 2.0" then it should redirect to (uwsgi_pass x.x.x.x:99)
I tried in my nginx.conf file
server{
listen 80;
server_name xyz.com;
if ($http_version ~ 'Version 1.0') {
proxy_pass http://192.168.0.116:99/calc;
}
if ($http_version ~ 'Version 2.0') {
proxy_pass http://192.168.0.116:99;
}
location /hello {
proxy_pass http://192.168.0.116:99/calc;
}
}
I'm getting error when I restart my nGINX
nginx: [emerg] "proxy_pass" directive is not allowed here in /etc/nginx/nginx.conf:19
nginx: configuration file /etc/nginx/nginx.conf test failed
Suppose you set a custom header in this form:
version: Version 1.0
Then you can configure nginx like in this way:
location / {
if ($http_version ~ 'Version 1.0') {
uwsgi_pass localhost:8888;
}
if ($http_version ~ 'Version 2.0') {
uwsgi_pass localhost:9999;
}
}
Reference: http://wiki.nginx.org/HttpCoreModule#.24http_HEADER

Resources