Nginx Snippets Tricks and Hacks
This is possible my first and last post written in English.
Right now, I am writing WAF, it is simple security tool right now based on Nginx and Lua (OpenResty) and I hoping it will solve some of my problems with bots.
I use it for years and backstory about our relation will be written later but I really love it.
This snippets are results of my jurney with writing WAF, using it for years on different applications and stuff like that. You can consider this for cheatsheet. Titles of this snippets will be retarded but there are because of SEO.
BEFORE ANYTHING RTFM
There are simple, well explained, you can find them here with more details of what does what.
Install nginx
Nginx have few different versions. Nginx CE, Nginx Plus (very nice thing but expensive), OpenRest (pre-build nginx with Lua support) and few more not worth mentioning.
Before anything I hope that you have Debian based distro, you can search different kind od packages using apt search nginx
but I advice you using something like:
apt update
apt install nginx-full nginx-extras
- If you are using non-Debian based distros, like RedHat based distros, you are old and you are using Apache.
- If you are using Windows, please see your psychiatrist.
- If you are using FreeBSD, you are not reading this.
Turn off nginx version in header and error pages
in http
block inside /etc/nginx/nginx.conf
put
server_tokens off;
Before:
$ curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.23.3
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
Connection: keep-alive
ETag: "6398a011-267"
Accept-Ranges: bytes
After
$ curl -I localhost
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
Connection: keep-alive
ETag: "6398a011-267"
Accept-Ranges: bytes
Remove nginx server header from requests
You need nginx-extras
package. Put this in http
block
more_clear_headers Server;
server_tokens off;
Change nginx server header
You need nginx-extras
package.
server_tokens off;
more_set_headers 'Server: Comodore 64';
Return test/content directly from nginx
Great for debugging, you do now need any HTML to test if nginx returns something as it should.
location / {
add_header Content-Type text/plain;
return 200 "This is most useful for debugging";
}
Simple HTTP load balancer
Be aware that if you try to start nginx and none of backends are alive, if will fail. Also note that this is HTTP load balancer.
upstream backend {
# select algorithm
least_conn;
# Defint backends
server backend1.example.com weight=2; # weight parameter loads that backend two times more eg. that server have more cpu cores
server backend2.example.com;
server backend3.example.com backup; # of course, use this backend only as backup
}
server {
listen 80;
# Here may come SSL snippet
location / {
proxy_pass http://backend;
}
}
More complex load balancing - TCP/UDP
This is example of TCP/UDP load balancing in nginx. Most of thing is same as in basic load balancing but diffrence is that in simple http loadbalancing, nginx every time handle http connections and deal with http content but with TCP/UDP load balancing you balance any application(mysql, redis, dns), not only the ones with http protocol.
Good topics:
- https://www.nginx.com/blog/tcp-load-balancing-udp-load-balancing-nginx-tips-tricks/
- https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
stream {
upstream stream_backend {
least_conn;
server backend1.example.com:12345 weight=5;
server backend2.example.com:12345 max_fails=2 fail_timeout=30s;
server backend3.example.com:12345 max_conns=3;
}
upstream dns_servers {
least_conn;
server 192.168.136.130:53;
server 192.168.136.131:53;
server 192.168.136.132:53;
}
server {
listen 12345;
proxy_pass stream_backend;
proxy_timeout 3s;
proxy_connect_timeout 1s;
}
server {
listen 53 udp;
proxy_pass dns_servers;
}
}
I stole this from somewhere, sorry author!
React, Angular or any other SPA rewrite for routes
server {
listen 80;
server_name somedomain.com;
root /home/app/www;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Add basic HTTP authentification to website or some of the routes
First of all, unfortunately we will need one Apache package called apache2-utils
so install it.
After you will need to generate file with users and passwords which acts like database.
htpasswd -c /etc/nginx/users admin
You can add unlimited number of users and also you should verify that file okay, it should look something like this:
# cat /etc/nginx/users
admin:$apr1$/woC1jnP$rjh0Ss1w5qeSMjTtn0Ejd1
After you created user, add following config to your server.conf
server {
auth_basic "Super secret area";
auth_basic_user_file /etc/nginx/users;
# rest of your config
# ...
Also, you can put it in only one route
server {
location /admin/ {
auth_basic "Super secret area";
auth_basic_user_file /etc/nginx/users;
}
# rest of your config
# ...
Or you can enable it for all routes and disable only for one
location /public/ {
auth_basic off;
}
Nice thing is that everything support HTTP basic auth so external services can access URL by using following sintax
http://user:[email protected]/sercuredroute/
Add basic browser caching
location ~* \.(?:ico|css|js|gif|jpeg|jpg|png|svg|woff|woff2|ttf)$ {
expires 15d;
add_header Pragma public;
add_header Cache-Control "public";
}
To be continued!