Install Nginx as Reverse Proxy on CentOS 7

This post is a simple walkthrough for installing Nginx, and configuring it as a reverse proxy. This is the setup I run at home, which allows me to use a self-signed wild card SSL server, and access all my services through this without putting those services directly on the internet. Currently, I am using this for Guacamole, SABnzbd/SickBeard/CouchPotatoServer/Headphones, SubSonic, Plex Media Server, and Owncloud.

For clarity, I will be running Nginx as a user called nginx. SELinux will be disable, and firewalld will be configured to only allow inbound 22 and 443 traffic (only 443 will be available on the internet).

Let's Get Started!

1.) prerequisites:
sed -i /etc/selinux/config -r -e 's/^SELINUX=.*/SELINUX=disabled/g'   # Disabled SELinux
yum -y install epel-release   # Install EPEL repo
yum -y update && systemctl reboot   # Run all updates before starting, and apply new SELinux settings

Easy.

2.) nginx install:
yum -y install nginx   # Install nginx
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig   # Create backup of nginx.conf
vi /etc/nginx/nginx.conf
---
user  nginx;
worker_processes  2;   # Set to number of CPU cores

error_log  /var/log/nginx/error.log;

pid  /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
  include  /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
              '$status $body_bytes_sent "$http_referer" '
              '"$http_user_agent" "$http_x_forwarded_for"';

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

  sendfile  on;

  keepalive_timeout  65;

  include /etc/nginx/conf.d/*.conf;

  index  index.html index.htm;
}
---

Nginx server is configured. Now to create the proxied sites config.

vi /etc/nginx/conf.d/reverseproxy.conf
---
ssl_certificate  ssl/domain.crt;   # Replace with your cert info (I generate my own self-signed certs with openssl)
ssl_certificate_key  ssl/domain.key;   # Replace with your cert info (I generate my own self-signed certs with openssl)
ssl_dhparam  ssl/domain.pem;   # Replace with your cert info (I generate my own self-signed certs with openssl)
ssl_session_timeout  5m;
ssl_prefer_server_ciphers  on;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers  AES256+EECDH:AES256+EDH:!aNULL;

server  {

  listen  80;   # Redirect any port http/80 requests, to https/443 -- generally only matters for internal requests
  server_name  *.domain.com;
  return 301 https://$host$request_uri;
}

server  {
  listen  443 ssl;   # Return 404 page if requesting the root url; can set this to whatever you want, but I just leave this at a 404
  server_name domain.com;
  ssl  on;
  location  / {
    return  404;
  }
}

server  {
  listen  443 ssl;   # Example config for SubSonic, browsable at https://subsonic.domain.com
  server_name  subsonic.domain.com;
  ssl  on;
  location  / {
    proxy_pass  http://interal_ip_to_subsonic:4040/;
  }
}

server  {
  listen  443 ssl;   # Example config for OwnCloud, browsable at https://owncloud.domain.com
  server_name  owncloud.domain.com;
  client_max_body_size  0;
  ssl  on;
  location  / {
    proxy_pass  http://internal_ip_to_owncloud/;
  }
}

server  {
  listen  443 ssl;   # Example config for SABnzbd, browsable at https://sab.domain.com
  server_name  sab.domain.com;
  ssl  on;
  location  / {
    proxy_pass  http://internal_ip_to_sabnzbd:8080/;
  }
}

server  {
  listen  443 ssl;   # Example config for SickRage, browsable at https://sr.domain.com
  server_name  sr.domain.com;
  ssl  on;
  location  / {
    proxy_pass  http://interal_ip_to_sickrage:8081/;
  }
}

server  {
  listen  443 ssl;   # Example config for CouchPotatoServer, browsable https://cps.domain.com
  server_name  cps.domain.com;
  ssl  on;
  location  / {
    proxy_pass  http://internal_ip_to_sickbeard:5050/;
  }
}

server  {
  listen  443 ssl;   # Example config for Headphones, browsable at https://hp.domain.com
  server_name  hp.domain.com;
  ssl  on;
  location  / {
    proxy_pass  http://internal_ip_to_headphones:9090/;
  }
}

server  {
  listen  443 ssl;   # Example config for Guacamole, browsable at https://guac.domain.com/guacamole
  server_name  guac.domain.com;
  ssl  on;
  location  / {
    proxy_buffering  off;
    proxy_pass  http://interl_ip_to_guacamole:8080/;
    proxy_http_version  1.1;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Upgrade $http_upgrade;
    proxy_set_header  Connection $http_connection;
    access_log  off;
  }
}

server  {
  listen  443 ssl;   # Example config for Plex Media Server, browsable at https://pms.domain.com/web
  server_name  pms.domain.com;
  ssl  on;
  location  / {
    proxy_pass  http://internal_ip_to_plex:32400/;
  }
}

server {
  listen  443 ssl;    # Example config for Stash, browsable at https://git.domain.com
  server_name  git.domain.com;
  ssl  on;
  client_max_body_size  256m;
  location  / {
    proxy_pass  http://internal_ip_to_stash:7990;
    proxy_set_header  X-Forwarded-Host $host;
    proxy_set_header  X-Forwarded-Server $host;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}
---

systemctl enable nginx.service   # Start nginx as system boot

Obviously, you don't have to use all the server blocks listed above, and use only what you need. I am providing these as easy examples, and this same config may or may not work for other service. Please leave a comment if you get it working with any other service!

2.) firewalld config:
systemctl enable firewalld.service   # Start firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https

And finally...

3.) finish:
systemctl reboot   # Reboot to finish up

Once the server boots back up, it should be ready to. Don't forget to forward port 443 on your firewall, and set up dns entries with your dns provider (pro-tip: Set up a wild card A Record such as *.domain.com and point that to your IP).

Feedback is always welcome!


Related Posts


Share on: Twitter | Facebook | Google+ | Email


comments powered by Disqus