Setting up Nginx on CentOS 7 as a reverse proxy



  • This is a pretty straight forward process. I always start with CentOS 7 Minimal as a base install image.

    Update the system
    yum -y update

    Install the epel
    yum -y install epel-release

    Install nginx and nano (because I do not like vi) and utils for selinux
    yum -y install nginx nano policycoreutils-python

    Open the firewall ports, assuming only 80/443 for inbound web traffic
    firewall-cmd --zone=public --add-port=http/tcp --permanent
    firewall-cmd --zone=public --add-port=https/tcp --permanent
    firewall-cmd --reload

    Start nginx and set it to start on boot also
    systemctl start nginx
    systemctl enable nginx

    Make a list of ports that your proxy will need to reach out on to hit the other servers behind it. These ports will need allowed through SELinux
    This is the default list of allowed http/tcp ports.
    http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

    You can see what is current allowed like this
    semanage port -l | egrep '(^http_port_t)'

    For example I have a nodeBB forum on 4567. This port already has a label, so you need to modify it.
    semanage port -m -t http_port_t -p tcp 4567
    I also have a servers running on ports 8040 and 8090. These have no label so add them..
    semanage port -a -t http_port_t -p tcp 8040
    semanage port -a -t http_port_t -p tcp 8090

    At this point nginx is all setup and running. Now you need to create your domain.conf files for each domain name you will be redirecting. Your will store all your conf files in /etc/nginx/conf.d/ because this location is included by the default configuration as a location for you. Just save everything with a .conf

    Here is a typical set of server blocks for a site with both http and https all on the standard ports.

    #save as file: /etc/nginx/conf.d/domain.conf
    server {
    	client_max_body_size 40M;
    	listen 443 ssl;
    	server_name www.domain.com domain.com;	#change to your domain name
    	ssl          on;
    	ssl_certificate /etc/ssl/cacert.pem;	#this needs to be the path to your certificate information
    	ssl_certificate_key /etc/ssl/privkey.pem;	#this needs to be the path to your certificate information
    
    	location / {
    		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;
    		proxy_pass https://10.0.0.2:443;	#change to your internal server IP
    		proxy_redirect off;
    	}
    }
    server {
    	client_max_body_size 40M;
    	listen 80;
    	server_name www.domain.com domain.com;	#change to your domain name
    
    	location / {
    		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;
    		proxy_pass http://10.0.0.2:80;	#change to your internal server IP
    		proxy_redirect off;
    	}
    }
    

    Now restart nginx
    systemctl reload nginx

    Update the port forwarding in your router and you should now be proxying all info through Nginx.



  • Now for a site on a non standard back end port that is still coming in on port 80 like my nodeBB example above, it is very similar.

    #save as file: /etc/nginx/conf.d/forum.domain.conf
    server {
    	client_max_body_size 40M;
    	listen 80;
    	server_name forum.domain.com;
    
    	location / {
    		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;
    		proxy_pass http://10.0.0.3:4567;
    		proxy_redirect off;
    	}
    }
    

    Now restart nginx
    systemctl reload nginx



  • The non standard port redirect also works with SSL. Again you need your proper certificate information in here. This example is used for my helpdesk.

    #save as file: /etc/nginx/conf.d/helpdesk.domain.conf
    server {
    	client_max_body_size 40M;
    	listen 443 ssl;
    	server_name helpdesk.domain.com;
    	ssl          on;
    	ssl_certificate /etc/ssl/cacert.pem;
    	ssl_certificate_key /etc/ssl/privkey.pem;
    
    	location / {
    		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;
    		proxy_pass https://10.0.0.4:8090;
    		proxy_redirect off;
    	}
    }
    

    Now restart nginx
    systemctl reload nginx



  • @JaredBusch Thanks, with your tutorial it's very easy to set up.



  • This post is deleted!


  • @anonymous said:

    So I have ScreenConnect setup using the reverse proxy, but the clients can't connect the to relay port. How do I fix this?

    What ports are you using? What is the proxy config?



  • This post is deleted!


  • @anonymous said:

    I think I will have to port forward the relay port to the ScreenConnect server?

    From the reading I have done, yes. That connection is not SSL, but pre encrypted by ScreenConnect itself.



  • This post is deleted!


  • Considering the new found love of Fedora, should this be done on Fedora instead?



  • @dashrender said in Setting up Nginx on CentOS 7 as a reverse proxy:

    Considering the new found love of Fedora, should this be done on Fedora instead?

    Yeah, I need to make a new guide for Fedora.

    Process is basically the same. Substitute dnf in place of yum, generally.

    No need for the epel



  • If I have multiple web servers, how does nginx know which host is which when they are both using the same port? It it just the subdomain and internal IP (proxy_pass)?

    Example:

    server {
    	client_max_body_size 40M;
    	listen 443 ssl;
    	server_name nc.skynetli.com;	#change to your domain name
    	ssl          on;
    	ssl_certificate /etc/ssl/cacert1.pem;	#this needs to be the path to your certificate information
    	ssl_certificate_key /etc/ssl/privkey1.pem;	#this needs to be the path to your certificate information
    
    	location / {
    		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;
    		proxy_pass https://192.168.1.205:443;	#change to your internal server IP
    		proxy_redirect off;
    	}
    }
    server {
    	client_max_body_size 40M;
    	listen 443;
    	server_name xo.skynetli.com;	#change to your domain name
    
    	location / {
    		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;
    		proxy_pass http://192.168.1.206:443;	#change to your internal server IP
    		proxy_redirect off;
    	}
    }
    


  • You use multiple server config areas in your example code, and then server_name and proxy_pass for each site using different ports.



  • @tim_g So essentially what I did above, correct?



  • I'll find a good link to reference, I can't do this on my phone... gimme a few mins.



  • @tim_g Np. Thanks



  • I prefer to have each server block for each domain/subdomain in it's own config file.

    0_1514323567627_24a83769-9483-4b32-af2c-3a190ad8f60d-image.png



  • @jaredbusch said in Setting up Nginx on CentOS 7 as a reverse proxy:

    I prefer to have each server block for each domain/subdomain in it's own config file.

    0_1514323567627_24a83769-9483-4b32-af2c-3a190ad8f60d-image.png

    wow, you are hosting a lot there.



  • [[email protected] ~]$ cat /etc/nginx/conf.d/daerma.com.conf 
    server {
        client_max_body_size 40M;
        listen 443 ssl;
        server_name www.daerma.com daerma.com;
        ssl          on;
        ssl_certificate /etc/letsencrypt/live/daerma.com-0001/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/daerma.com-0001/privkey.pem;
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    
        location / {
            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;
            proxy_pass https://10.254.0.101:443;
            proxy_redirect off;
        }
    }
    
    server {
        client_max_body_size 40M;
        listen 80;
        server_name www.daerma.com daerma.com;
        rewrite        ^ https://daerma.com$request_uri? permanent;
    }
    


  • Like this, this is a good example of what I meant...

    https://timothy-quinn.com/using-nginx-as-a-reverse-proxy-for-multiple-sites



  • [[email protected] ~]$ cat /etc/nginx/conf.d/unms.bundystl.com.conf 
    server {
        client_max_body_size 40M;
        listen 443 ssl;
        server_name unms.bundystl.com;
        ssl          on;
        ssl_certificate /etc/letsencrypt/live/unms.bundystl.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/unms.bundystl.com/privkey.pem;
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    
        location / {
            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;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass https://10.254.0.39:443;
            proxy_redirect off;
    
            # Socket.IO Support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    
        }
    }
    server {
        client_max_body_size 40M;
        listen 80;
        server_name unms.bundystl.com;
        rewrite        ^ https://$server_name$request_uri? permanent;
    }
    


  • @jaredbusch Understood. Thanks. I bet multiple configs makes it easier organizationally and also when troubleshooting so you have less to go through.



  • @wirestyle22 said in Setting up Nginx on CentOS 7 as a reverse proxy:

    @jaredbusch Understood. Thanks. I bet multiple configs makes it easier organizationally and also when troubleshooting so you have less to go through.

    That is my preference, yes.



  • @dashrender said in Setting up Nginx on CentOS 7 as a reverse proxy:

    @jaredbusch said in Setting up Nginx on CentOS 7 as a reverse proxy:

    I prefer to have each server block for each domain/subdomain in it's own config file.

    0_1514323567627_24a83769-9483-4b32-af2c-3a190ad8f60d-image.png

    wow, you are hosting a lot there.

    Not really. Just everything is broken out.



  • So I ran into this
    0_1514509710111_1.PNG

    but the nginx documentation here points to this: https://nginx.org/en/docs/http/server_names.html
    0_1514509728545_2.PNG

    Is there an error here I'm not seeing? I mean, there must be. Each time I make a change I systemctl reload nginx



  • This post is deleted!


  • This post is deleted!


  • Actually I think I figured it out. made a mistake with the .conf files



  • @wirestyle22 Share your resolution if you will. I was trying to install nginx on a server with wiki.js the other day and was running into the same error.



  • I never run certbot with one of the specific switches like --nginx or --apache. Ever.

    Fuck letting some 3rd party script edit my configuration files.

    I run in standalone mode and edit the conf files myself.

    I also include multiple SAN on my certs, so the same SSL file is in multiple conf files.