Difference between revisions of "NGINX"

From UVOO Tech Wiki
Jump to navigation Jump to search
Line 4: Line 4:
  
 
# NGINX Auth
 
# NGINX Auth
 +
 +
[[ NGINX WebDAV ]]
  
 
[[ NGINX Authentication ]]
 
[[ NGINX Authentication ]]

Revision as of 02:54, 23 May 2020

NGINX Modules

NGINX Modules

NGINX Auth

NGINX WebDAV

NGINX Authentication

NGINX Snippets

NGINX Best Practices

You can make http/postgres calls from NGINX but it is probably best to sync your data to local redis data store and make the queries on that. This makes reliablity and performance much better and also may mitigate security issues depending how good/bad your design is.

NodeJS Example

Here is a simple example for a reverse proxy for nodejs app running on port 3000.

Create Non-interactive Self Signed Key

Change params as needed. Remove -subj if you want to be prompted for input.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/C=US/ST=Utah/L=SLC/O=Example Corp/OU=Testing/CN=example.io"

Update NGINX default sites available

This config is for example and a little tighter in security parameters by stapling and limiting protocols and using set preferred ciphers. Change as wanted. Setting

nano /etc/nginx/sites-available

<br />server {
    listen 80 default_server;
    listen [::]:80 default_server;
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }

    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    # server_name example.com www.example.com;
    server_name _;
    root /var/www/html;

    # These may be useful
    # server_name example.com www.example.com;
    # ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # ssl_prefer_server_ciphers on;
    # ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
    # ssl_session_timeout 1d;
    # ssl_stapling on;
    # ssl_session_cache shared:SSL:50m;
    # ssl_stapling_verify on;
    # add_header Strict-Transport-Security max-age=15768000;

    location / {
        client_max_body_size 10m;
        proxy_pass http://localhost:3000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
    }
}

Check and reload nginx service

nginx -t
systemctl reload nginx

Using Let's encrypt

You must have a public ip address or public internet accessible web interface and a dns record for your FQDN setup.

Adding Let's encrypt and nginx

apt-get update
sudo apt-get install nginx python-certbot-nginx
sudo certbot

Auto Renew

/etc/cron.d/certbot

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
# 45 2 * * 6 sudo /usr/local/sbin/certbot-auto renew >> /var/log/certbot-auto.log 2>&1

Test SSL Health

https://www.ssllabs.com/ssltest/

Ultra Simple Common Reverse Proxy Using Cache

http {
    proxy_cache_path  /data/nginx/cache  levels=1:2    keys_zone=STATIC:10m
    inactive=24h  max_size=1g;
    server {
        location / {
            proxy_pass             http://localhost:3000;
            proxy_set_header       Host $host;
            proxy_set_header       X-Real-IP $remote_addr;
            proxy_set_header       Host $host;
            proxy_buffering        on;
            proxy_cache            STATIC;
            proxy_cache_valid      200  1d;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;
        }
    }
}

Quick Install & Prep for SSL Reverse Proxy

sudo apt-get update
sudo apt-get install -y nginx python-certbot-nginx
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/C=US/ST=Utah/L=SLC/O=Example Corp/OU=CI/CN=example.io"

cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bkp

nginx_site_conf='server {
    listen 80 default_server;
    listen [::]:80 default_server;
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }

    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    server_name _;
    root /var/www/html;

    location / {
        client_max_body_size 10m;
        proxy_pass http://localhost:4000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
    }
}'

echo "${nginx_site_conf}" > /etc/nginx/sites-available/default

systemctl restart nginx

Sub Requests in NGINX

Most often you are just gate guarding and something like this will work.

https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-subrequest-authentication/

 location = /auth {
        internal;
        proxy_pass              https://portal.example.io/api/auth_verify_jwt;
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
    }

   location /private/ {
       auth_request /auth;
       auth_request_set $dynamic $upstream_http_x_route;
       proxy_set_header X-Route $dynamic;
       proxy_pass https://portal.example.io/api/jtester2;
    }


If you need more use LUA

https://stackoverflow.com/questions/48348647/fetch-information-from-an-api-before-sending-the-request-upstream

test.conf
  server {
    listen 8080;

    location /fetch_api {
        # this is a service echoing your IP address   
        proxy_pass http://api.ipify.org/;
    }

    location / {
        set $api_result "";
        access_by_lua_file /etc/nginx/conf.d/header.lua;
        proxy_set_header X-Additional-Info $api_result;
        # this service just prints out your request headers
        proxy_pass http://scooterlabs.com/echo;
    }
}
header.lua
local res = ngx.location.capture('/fetch_api', { method = ngx.HTTP_GET, args = {} });

ngx.log(ngx.ERR, res.status);
if res.status == ngx.HTTP_OK then
  ngx.var.api_result = res.body;
else
  ngx.exit(403);
end
results
curl http://localhost:8080/
Simple webservice echo test: make a request to this endpoint to return the HTTP request parameters and headers. Results available in plain text, JSON, or XML formats. See http://www.cantoni.org/2012/01/08/simple-webservice-echo-test for more details, or https://github.com/bcantoni/echotest for source code.


Notice the X-Additional-Info header populated with the data obtained in /fetch_api handler

References