SomeBlog

Just some things I've found useful in IT.. Check out the Blog

General Information, NGINX, Web Servers

NGINX – Reverse Proxy

This has to be defined before I get further; basically all of my web apps depend on a single NGINX reverse proxy for SSL and basic security. It can proxy to http or https and the only difference in configuration is http turns into https where the back-end server is defined.

Reverse proxies like this run much of the websites online today, do a reverse lookup of almost any website’s IP and you’ll find anywhere from several to thousands of sites running behind the same public IP address.

The config for each site can be in one file or split by actual site, it just depends how you’d like to manage your configuration. There are many different types of web applications so there’s really no “one size fits all” config, but there is a basic config that fits most. It gets a little different if you need websockets – and the location of backend resources like PHP can also be odd. However, when it comes to proxying any location block, you have to have the back-end configured first, so you basically just mirror it within the proxy.

Advantages: Centralized log location, simplified SSL management – if all sites are subdomains of the same domain, you can use the same wildcard cert and key for each site. Physical firewall policy is easier, just push 80 and 443 to a single internal host. Save yourself some public IPs for other resources – like your VPN, etc.

I do like a separate file for my http block, it includes every server name, plus a redirect for bots trying my site by IP address – almost all bad bots scan by IP address, so make a server for your raw IP and send it somewhere else.

sudo nano /etc/nginx/sites-available/tohttps

server {

listen 80;

server_name somesite.com another.com canhavehundreds.com rootdomainsdont.care itsprettycool.net;

return 301 https://$host$request_uri;

}

# send the bots to hell – you need a 443 block for this WITH valid SSL config.

server {

listen 80;

server_name pub IP address;

return 301 https://hell.com;

}

server {

listen 443;

server_name pub IP address;

return 301 https://hell.com;

ssl_certificate /path/to/fullchain.crt;

ssl_certificate_key /path/to/priv.key;

}

So that’s the http to https file – Add that to /etc/nginx/sites-available/ and link it to ../sites-enabled/

ln -s /etc/nginx/sites-available/tohttps /etc/nginx/sites-enabled/tohttps

Then create another file in ../sites-available/ for the actual proxy configuration.

sudo nano /etc/nginx/sites-available/rproxy

This works for WordPress – I like docker on the back side for this, you can have a pile of WordPress sites on the same host-

server {

listen 443 ssl http2;

server_name somesite.com;

ssl_certificate /path/to/fullchain.crt;

ssl_certificate_key /path/to/priv.key;

# this part is WP specific:

ssl_session_cache builtin:1000 shared:SSL:10m;

ssl_protocols TLSv1.2;

ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;

ssl_prefer_server_ciphers on;

access_log /var/log/nginx/blog.access.log;

# this is the proxy part, this config works for most sites without the extra ssl args above, key and crt are always req.

# Remember, if it’s PHP, you need to proxy the php location. This is why docker makes a lot of things easier- 🙂

# If I want HTTP Authentication, this is where I put it, it will only apply to this server, even if there are 20

# others defined in this file.

location / {

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# Some sites require websockets, usually chat servers, this is what you need:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;

# below here is normal config again.

proxy_pass http://192.168.1.20:8047;

proxy_read_timeout 90;

proxy_redirect http://192.168.1.20:8047 https://somesite.com;

}

}

Now link the file to sites-enabled: ln -s /etc/nginx/sites-available/rproxy /etc/nginx/sites-enabled/rproxy

That basically covers everything- If the back-end is already HTTPS, then change the proxy_pass and proxy_redirect lines to https://ipaddress:port – you should specify the port even when it’s 443.

Leave a Reply