Reference outside text file content from Nginx configuration file - nginx

I am looking at options to add client-side certificate authentication with a fingerprint whitelist to a local site, and have successfully configured nginx to operate in the intended manner. My configuration is as follows:
# Client Certificate Whitelisting
map $ssl_client_fingerprint $reject {
default 1;
<ALLOWED_FINGERPRINT_1> 0;
<ALLOWED_FINGERPRINT_2> 0;
...
<ALLOWED_FINGERPRINT_N> 0;
}
server {
...
ssl_client_certificate /etc/pki/tls/certs/Private-CA-bundle.pem;
ssl_verify_client on;
...
if ($reject) { return 403; }
...
}
However, I would like to store the fingerprint list in a separate text file, rather than manipulating the nginx configuration file directly each time. Is this possible?
As a bonus, it would be great if I could modify the contents of the text file and have them take effect without reloading nginx. It is acceptable for removals to still require a service restart or other manual session teardown procedure.
---- EDIT ----
Based on the accepted answer, I was able to get this working.
The updated configuration file is:
# Client Certificate Whitelisting
map $ssl_client_fingerprint $reject {
default 1;
include /etc/nginx/cert-whitelist;
}
I was able to add a new certificate and apply the changes without a full service restart.
### Attempt connection with client certificate; returns 403 Forbidden
[root]# cat /run/nginx.pid
5606
[root]# echo "${FINGERPRINT} 0;" >> /etc/nginx/cert-whitelist
[root]# kill -1 $(cat /run/nginx.pid)
[root]# cat /run/nginx.pid
5606
### Attempt connection with client certificate; success

The map directive has the ability to source a correctly formatted file. See this document for details.
You can use SIGHUP to re-read the configuration file without restarting Nginx. See this document for details.

Related

NGINX Remote Editing of Configurations

I'm currently running a number of servers, each running NGINX used as reverse proxies to other websites. However, if I need to change a backend IP address or change other variables within NGINX, I need to manually SSH into the server and change the configurations OR log onto NGINX Proxy Manager.
What I'm looking to do is create a central website that will enable me to edit NGINX variables such as 'proxy_pass' and send the updated value to the selected remote server, updating the NGINX config and reloading the service.
Is there any current way to do this and how could I implement that? What comes to mind is some kind of CURL request to the remote server, and then I'm not sure how I'd automatically rewrite the correct portion of NGINX config etc.
Any help would be appreciated!
If you have root access on those servers, all you need is a service or a script that will fill the new values. The simplest way I see fit is to do it with a bash script and a template for the config file.
Template config file: /home/user/nginx_config/nginx.config.sample:
-- your generic config settings
proxy_pass
location /your/location {
proxy_pass {{proxy_pass}};
}
-- rest of standard file
The bash script for filling the template: /home/user/nginx_config/generator.sh
new_ip=$1
template_path="/home/user/nginx_config/nginx.config.sample"
config_path="/etc/nginx/nginx.conf"
if [[ -z $1 ]]
then echo "Missing IP param"; exit;
fi
cp "$config_path" "${config_path}.bak"
sed "s/{{proxy_pass}}/$new_ip/g" "$template_path" > "$config_path"
echo "Done! Updated $config_path file to $1:"
cat "$config_path"
Then, all you need to do is to make a local script to connect using ssh and run the generator script (with 1.2.3.4 as your new IP address)
sshpass -p password ssh -oStrictHostKeyChecking=no -oCheckHostIP=no user#your_server "bash /home/user/nginx_config/generator.sh 1.2.3.4"

Trying to set file upload limit in mup/nginx-proxy

I am running into a file upload error with files > 10M. I have followed the advice here: http://meteor-up.com/docs.html#advanced-configuration which says how to set it in the nginx proxy by setting the clientUploadLimit: '50M'
I pushed the changes using mup proxy reconfig-shared, and it told me it had restarted the proxy. It didn't work, I still get the 413 (Request Entity Too Large) error.
I checked inside the nginx-proxy docker instance, and the file /etc/nginx/conf.d/my_proxy.conf has the correct entry client_max_body_size 50M. I restarted the EC2 box to make sure, but it's still not working.
This article https://www.tecmint.com/limit-file-upload-size-in-nginx/ suggests that the setting needs to go inside a http block, like this:
By default, Nginx has a limit of 1MB on file uploads. To set file upload size, you can use the client_max_body_size directive, which is part of Nginx’s ngx_http_core_module module. This directive can be set in the http, server or location context.
http {
client_max_body_size 100M;
}
I can't see how to achieve this, as the .conf file is read only and somehow locked.
Any ideas on how to proceed?
I suppose I could try a custom nginx.conf file, but I'm not sure what should go in there, and in fact whether it will even improve the situation.
Any help is appreciated :)
I'm happy to report that I solved it... I will explain how.
I was setting the limit in the nginx reverse proxy in the mup.js file
proxy: {
domains: 'website.com,www.website.com',
shared: { clientUploadLimit: '50M' }
}
But it turns out that there is an option to set it for each independent server like this:
proxy: {
domains: 'website.com,www.website.com',
clientUploadLimit: '50M'
}
The limit was being set to 10M by default. I found it by shelling into the nginx-proxy docker image and doing a search with the command grep -R client_max_body_size /etc/nginx and it showed me all the places where it was set (for each vhost)
So I changed the mup.js file for my server, did a mup stop, and a mup setup (to re-do the settings) and then a mup deploy
Now this is speculation but have you tried going to the docker container's root shell changed the permissions to give write permission to root or your user chmod 760 /etc/nginx/nginx.conf and edit the nginx file there?

Is it possible to have live reloading of lua scripts using openresty and docker?

I'm newish to LUA and want to practice some LUA scripting using nginx/openrestry.
Is there a workflow where I can use docker that runs openresty, and link my laptops filesystem to my docker container such that when I make a change to my lua script, I can quickly reload openrestry server so I can quickly see my lua changes take effect?
Any help or guidance would be appreciated.
You can disable Lua code cache — https://github.com/openresty/lua-nginx-module#lua_code_cache — add lua_code_cache off inside the http or server directive block. This is not actually “hot reload”, it's more like php request lifecycle:
every request served by ngx_lua will run in a separate Lua VM instance
You can think of it as if the code is hot–reloaded on each request.
However, pay attention to this:
Please note however, that Lua code written inlined within nginx.conf [...] will not be updated
It means that you should move all your Lua code from the nginx config to Lua modules and only require them:
server {
lua_code_cache off;
location /foo {
content_by_lua_block {
-- OK, the module will be imported (recompiled) on each request
require('mymodule').do_foo()
}
}
location /bar {
content_by_lua_block {
-- Bad, this inlined code won't be reloaded unless nginx is reloaded.
-- Move this code to a function inside a Lua module
-- (e.g., `mymodule.lua`).
local method = ngx.req.get_method()
if method == 'GET' then
-- handle GET
elseif method == 'POST' then
-- handle POST
else
return ngx.exit(ngx.HTTP_NOT_ALLOWED)
end
}
}
}
Then you can mount your Lua code from the host to the container using --mount or --volume: https://docs.docker.com/storage/bind-mounts/

'init_by_lua_block' directive not getting executed on nginx start

I wanted one of my lua script to get executed whenever nginx server starts or is reloaded. I tried using init_by_lua_block and init_by_lua_file directive but i dont see any log traces for the lua script in init_by_lua_block when i run the nginx docker. My http block looks like below. nginx.config is located in container path/etc/nginx/nginx.conf .
http {
sendfile on;
init_by_lua_block /etc/nginx/lua/init.lua;
include /etc/nginx/conf.d/proxy-config.conf;
}
Can anyone please tell me what I am missing here?
init_by_lua_block
syntax: init_by_lua_block { lua-script }
https://github.com/openresty/lua-nginx-module#init_by_lua_block
init_by_lua_block expects inlined Lua code, not a path to the Lua file.
Use dofile to execute Lua script:
init_by_lua_block {
dofile('/etc/nginx/lua/init.lua')
}
https://www.lua.org/manual/5.1/manual.html#pdf-dofile
or use init_by_lua_file:
init_by_lua_file /etc/nginx/lua/init.lua;
UPD:
You should use the NOTICE logging level (or higher) in init_by_lua_* directives because your error_log configuration is not yet applied in this phase:
Under the hood, the init_by_lua runs in the nginx configuration loading phase, so your error_log configuration in nginx.conf does not take effect until the whole configuration is loaded successfully (due to the bootstrapping requirements: the configuration loading MAY fail). And nginx initially uses a logger with the NOTICE filtering level upon startup which is effect in the whole first configuration loading process (but not subsequent configuration (re)loading triggered by the HUP signal).
https://github.com/openresty/lua-nginx-module/issues/467#issuecomment-82647228
So, use ngx.log(ngx.NOTICE, ...) (or ngx.WARN, ngx.ERR, etc. — see https://github.com/openresty/lua-nginx-module#nginx-log-level-constants) to see the output in the log.
Alternatively you can use print. It's equivalent to ngx.log(ngx.NOTICE, ...) under the hood: https://github.com/openresty/lua-nginx-module#print

Using nginx to serve local files instead of remote files

Say I'm accessing www.mywebsite.com.
This website fetches the following asset:
http://www.mywebsite.com/styles/app.css
I want to access the website exactly as I normally would, with one exception:
Whenever my browser makes a request to /styles/app.css, instead of fetching it from http://www.mywebsite.com, I want to fetch it from http://localhost:3000/mywebsite/.
So instead it should be fetching:
http://localhost:3000/mywebsite/styles/app.css
Is this possible with nginx?
I tried to do it using the following server config:
{
...
server {
listen 80;
server_name mywebsite.com;
location /styles/ {
proxy_pass http://localhost:3000/mywebsite/styles/;
}
}
But even after restarting nginx (sudo nginx -s quit, sudo nginx), nothing seems to have changed.
When I browse to www.mywebsite.com/styles/app.css, I still get the same old app.css being retrieved from the server, rather than my local one.

Resources