Difference between revisions of "NGINX"
Line 232: | Line 232: | ||
deny all; # optional | deny all; # optional | ||
} | } | ||
+ | ``` | ||
+ | |||
+ | ``` | ||
+ | apt install apache2-utils | ||
+ | touch /etc/nginx/htpasswd/example.io.htpasswd | ||
+ | htpasswd /etc/nginx/htpasswd/example.io.htpasswd user1 | ||
+ | # htpasswd -n username | ||
``` | ``` | ||
Revision as of 00:25, 8 August 2020
NGINX Modules
NGINX Auth
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
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
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
Allow ip or auth
location / { index index.html; satisfy any; allow 10.0.0.0/8; auth_basic "Authorized Only"; auth_basic_user_file /etc/nginx/htpasswd/example.io.htpasswd; deny all; # optional }
apt install apache2-utils touch /etc/nginx/htpasswd/example.io.htpasswd htpasswd /etc/nginx/htpasswd/example.io.htpasswd user1 # htpasswd -n username
References
- https://certbot.eff.org/all-instructions
- https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx.html
- https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
- https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-on-centos-7
- https://www.nginx.com/resources/wiki/start/topics/examples/full/
- https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/
- https://nginx.org/en/docs/http/websocket.html
- https://www.shellhacks.com/create-csr-openssl-without-prompt-non-interactive/
- https://yos.io/2016/01/28/building-an-api-gateway-with-lua-and-nginx/
- https://github.com/openresty/lua-nginx-module