Install Nginx as a Reverse Proxy on Fedora 27



  • Way back in 2015, I posted a guide for setting up Nginx reverse proxy on CentOS 7.

    Well here is the process for Fedora 27 using Certbot to create the certs.

    As always I start a guide with a Fedora 27 Minimal install. You are free to start from whatever source you wish, some packages may already be installed on your system if you start form a different template. That is absolutely fine.

    Make sure Fedora is up to date

    dnf upgrade -y --refresh
    

    Install packages needed

    The package policycoreutils-python-utils is required to use semanage if you need to add a non-standard port to SELinux.

    dnf install -y certbot-nginx nginx policycoreutils-python-utils
    

    Install nano because I prefer it over vi

    Skip this if you want

    dnf install -y nano
    

    Open the firewall for inbound traffic on ports 80 and 443.

    firewall-cmd --add-port=http/tcp --permanent
    firewall-cmd --add-port=https/tcp --permanent
    firewall-cmd --reload
    

    Tell SELinux to allow Nginx to connect out to your backend servers

    setsebool -P httpd_can_network_connect 1
    

    Verifiy what ports you will be using

    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.
    Most of the time you never need to do anything here as you are sending traffic back to another webserver on standard ports.
    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 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

    Start nginx and set it to start on boot also

    systemctl start nginx
    systemctl enable nginx
    

    That is all it takes to get Nginx running, now you need to tell it what to do.

    Create a configuration file to route the inbound traffic.

    This bit is based on a few assumptions.

    1. You are going to use certbot --nginx to obtain your certs
    2. You already have the FQDN setup for your domain.
      1. I am using nc.domain.com as an example.
    3. You already have the backend Nextcloud server setup and listening on port 80.
      1. I am using 10.150.0.17 as an example backend IP.

    Before you can request your SSL certificate, you have to have a valid configuration file in place listening on port 80.
    Nginx stores the configuration files in /etc/nginx/conf.d/, so let's make our nextcloud.conf.
    I am not going to go aver all the pieces here. If you want ot know more about what all these settings mean, go look them up.
    Finally, this is a sample base don Nextcloud. Change it to fit your application needs.
    The structure may look strange at first, but there is a method to my madness. It is based on how certbot --nginx works.

    cat > /etc/nginx/conf.d/nextcloud.conf <<EOF
    server {
        client_max_body_size 40M;
        server_name nc.domain.com;
        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_redirect off;
        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.150.0.17;
            proxy_redirect off;
            # Socket.IO Support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    ##    ssl_stapling on;
    ##    ssl_stapling_verify on;
    ##    ssl_session_cache shared:SSL:10m;
    ##    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
        listen 80;
    }
    ##server {
    ##    client_max_body_size 40M;
    #    listen 80;
    ##    server_name nc.domain.com;
    ##    return 301 https://$host$request_uri;
    ##}
    EOF
    

    NOTE: This is on purpose only one # while the others have two, # listen 80;.

    Test the config

    nginx -t
    

    Reload Nginx

    nginx -s reload
    

    At this point your application will be publicly accessible via normal HTTP. So let's go get that certificate to encrypt it.

    Run certbot

    certbot --nginx -n --email [email protected] --agree-tos --domains nc.domain.com
    

    Assuming you did not get an error, your nextcloud.conf has been modified by certbot.

    Verify your configuration changed

    cat /etc/nginx/conf.d/nextcloud.conf
    

    You will see these new lines after there listen 80; that was at the bottom of the server block.

        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/nc.domain.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/nc.domain.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    

    Uncomment SSL options and HTTP rewrite

    Some of you might get why I had all the commented out stuff in there. Made it easy to uncomment now.
    First, comment out the listen 80; in the first block we do not want it there.

    sed -i "s/    listen 80;/#    listen 80;/" /etc/nginx/conf.d/nextcloud.conf
    

    Now remove the other commented out bits

    sed -i "s/##//" /etc/nginx/conf.d/nextcloud.conf
    

    Test the Nginx config and reload

    Same as before.

    nginx -t
    

    If nothing is in error, reload

    nginx -s reload
    

    You now have a fully SSL protected website, with HTTP traffic rerouted to HTTPS.

    Don't forget to automate the cert renew

    Create a cron job to run the renew everyday. Certbot will not actually do anything if it does not see any certs needing renew within 30 days. So you can run this as often as you want. Cerbot themselves recommends running it twice a day with this.
    Use crontab -e to edit your crontab.

    0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 
    


  • Received following error:

    nginx: [warn] could not build optimal types_hash, you should increase either nginx: [warn] could not build optimal types_hash, you should increase either types_hash_max_size: 2048 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size

    I went into /etc/nginx/nginx.conf and changed types_hash_max_size to a higher value as instructed. Removed the error.



  • Great guide. Probably your best yet.



  • Guess if I have my own SSL I don't need to run the certbot stuff and just add the SSL file locations in.

    Also if I have a wild card cert *.domain.co.uk do I still add the SSL to each .conf file or just the default.conf for nginx?



  • But going to redo my nginx install using this guide Monday.

    Might just use certbot anyway 😁 for the new servers as I redo and sort them



  • @hobbit666 said in Install Nginx as a Reverse Proxy on Fedora 27:

    Guess if I have my own SSL I don't need to run the certbot stuff and just add the SSL file locations in.

    Also if I have a wild card cert *.domain.co.uk do I still add the SSL to each .conf file or just the default.conf for nginx?

    100% correct.



  • This guide is fortuitous. I had this planned for migration from Ubuntu this week. This makes my job easier. Thanks!



  • I'm assuming you would recommend using the .well-known addition to the conf files in the server block to avoid shutting down Nginx?

       location /.well-known/acme-challenge {
                root /var/www/letsencrypt;
             }
    


  • @nashbrydges said in Install Nginx as a Reverse Proxy on Fedora 27:

    I'm assuming you would recommend using the .well-known addition to the conf files in the server block to avoid shutting down Nginx?

       location /.well-known/acme-challenge {
                root /var/www/letsencrypt;
             }
    

    Not in this example as I am using the certbot --nginx switch. It knows how to handle things because of that.

    But if you were doing something else? yes.



  • @wirestyle22 said in Install Nginx as a Reverse Proxy on Fedora 27:

    Received following error:

    nginx: [warn] could not build optimal types_hash, you should increase either nginx: [warn] could not build optimal types_hash, you should increase either types_hash_max_size: 2048 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size

    I went into /etc/nginx/nginx.conf and changed types_hash_max_size to a higher value as instructed. Removed the error.

    1. This is only a warning.
    2. Unless you are hosting hundred of domains behind Nginx, this really doesn't matter.
    3. If you increase it to not have a warning, keep it as small as possible.

    I just went through jumping down in halves from 3000 until I found what made it stop complaining on my system.

        types_hash_max_size 2249;
    

    2248 threw the warning still.

    Reference to what this is: http://nginx.org/en/docs/hash.html



  • @jaredbusch said in Install Nginx as a Reverse Proxy on Fedora 27:

    @hobbit666 said in Install Nginx as a Reverse Proxy on Fedora 27:

    Guess if I have my own SSL I don't need to run the certbot stuff and just add the SSL file locations in.

    Also if I have a wild card cert *.domain.co.uk do I still add the SSL to each .conf file or just the default.conf for nginx?

    100% correct.

    Last question.

    What's the answer for this part of the question 🙂
    "Also if I have a wild card cert *.domain.co.uk do I still add the SSL to each .conf file or just the default.conf for nginx"

    😁



  • @hobbit666 said in Install Nginx as a Reverse Proxy on Fedora 27:

    @jaredbusch said in Install Nginx as a Reverse Proxy on Fedora 27:

    @hobbit666 said in Install Nginx as a Reverse Proxy on Fedora 27:

    Guess if I have my own SSL I don't need to run the certbot stuff and just add the SSL file locations in.

    Also if I have a wild card cert *.domain.co.uk do I still add the SSL to each .conf file or just the default.conf for nginx?

    100% correct.

    Last question.

    What's the answer for this part of the question 🙂
    "Also if I have a wild card cert *.domain.co.uk do I still add the SSL to each .conf file or just the default.conf for nginx"

    😁

    Each server block needs it. Or you can use an include I guess like this.

    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    

    Just make your own file with all the ssl settings you want and drop the include in the various conf files.



  • @jaredbusch Thanks



  • @JaredBusch This is transparent to the www application server? I mean, Nextcloud server itself has no https configuration, it all handled through this proxy?
    If so, this same process could be done using IIS sites in addition to apache correct?



  • @momurda said in Install Nginx as a Reverse Proxy on Fedora 27:

    @JaredBusch This is transparent to the www application server? I mean, Nextcloud server itself has no https configuration, it all handled through this proxy?
    If so, this same process could be done using IIS sites in addition to apache correct?

    Can be, and is, used with anything that has a web interface. Apache, Nginx, IIS, NodeJS, it doesn't care. A Reverse proxy is just a proxy in front of whatever HTTP traffic is behind it. So the platform behind it doesn't matter. Mix and match anything and everything.



  • @scottalanmiller So if i set this up to work with an IIS site, this IIS site has an existing cert, i would first uninstall that ssl cert, and not install another? This is what I picture.



  • @momurda said in Install Nginx as a Reverse Proxy on Fedora 27:

    @scottalanmiller So if i set this up to work with an IIS site, this IIS site has an existing cert, i would first uninstall that ssl cert, and not install another? This is what I picture.

    You can do either, with small adjustments. Your servers behind your reverse proxy can use HTTP or HTTPS as you desire. but there is rarely much point to the overhead of HTTPS, so many of us skip it unless there is a specific reason to have it (like you are using it without the reverse proxy for LAN based access.)



  • @scottalanmiller said in Install Nginx as a Reverse Proxy on Fedora 27:

    @momurda said in Install Nginx as a Reverse Proxy on Fedora 27:

    @scottalanmiller So if i set this up to work with an IIS site, this IIS site has an existing cert, i would first uninstall that ssl cert, and not install another? This is what I picture.

    You can do either, with small adjustments. Your servers behind your reverse proxy can use HTTP or HTTPS as you desire. but there is rarely much point to the overhead of HTTPS, so many of us skip it unless there is a specific reason to have it (like you are using it without the reverse proxy for LAN based access.)

    If the existing server is designed for HTTP, I usually do not remove it. I just point the Nginx server block at it.

    Even if it is expired or self signed, it is sitll encyrpted between the proxy and the backend server.

    Now if the backend server has no encryption, I will not add it for no reason.

    Finally, if the backend server is across a public IP space, I will always use at least a self signed SSL cert for the connection.



  • Here is the command if you want a wildcard cert:

    sudo certbot  -i nginx -d "*.aaronstuder.com" -d aaronstuder.com --server https://acme-v02.api.letsencrypt.org/directory --manual --preferred-challenges dns


  • @aaronstuder said in Install Nginx as a Reverse Proxy on Fedora 27:

    Here is the command if you want a wildcard cert:

    sudo certbot  -i nginx -d "*.aaronstuder.com" -d aaronstuder.com --server https://acme-v02.api.letsencrypt.org/directory --manual --preferred-challenges dns
    

    Wildcard form LE is useless until you automate the DNS challenge.



  • @jaredbusch It's coming. Right now it just pauses and you update DNS manually, or you can use acme.sh



  • If you're using one reverse proxy to serve traffic to more than one server, do you typically put all of the configurations in one file, or have a main configuration file, and use include to reference other files? Methinks the way to go is just have one file with server blocks for however many servers you need.



  • @eddiejennings said in Install Nginx as a Reverse Proxy on Fedora 27:

    If you're using one reverse proxy to serve traffic to more than one server, do you typically put all of the configurations in one file, or have a main configuration file, and use include to reference other files? Methinks the way to go is just have one file with server blocks for however many servers you need.

    Using separate config is more easier to manage.



  • "Install nano because I prefer it over vi"

    Nano really should just be the standard at this point, IMO.



  • @bbigford said in Install Nginx as a Reverse Proxy on Fedora 27:

    "Install nano because I prefer it over vi"

    Nano really should just be the standard at this point, IMO.

    I worded it like that to appease people like @scottalanmiller to prevent some stupid commentary about unneeded packages







  • @jaredbusch said in Install Nginx as a Reverse Proxy on Fedora 27:

    @coliver said in Install Nginx as a Reverse Proxy on Fedora 27:

    @jaredbusch 0_1524226298968_a9d48ad2-c13d-440c-94c5-a6951b5f6887-image.png

    Pretty much exactly

    I can't make fun. I prefer Vim. I've tried to use nano and I felt clunky. But to each their own. Just don't use emacs 🙃



  • @stacksofplates said in Install Nginx as a Reverse Proxy on Fedora 27:

    @jaredbusch said in Install Nginx as a Reverse Proxy on Fedora 27:

    @coliver said in Install Nginx as a Reverse Proxy on Fedora 27:

    @jaredbusch 0_1524226298968_a9d48ad2-c13d-440c-94c5-a6951b5f6887-image.png

    Pretty much exactly

    I can't make fun. I prefer Vim. I've tried to use nano and I felt clunky. But to each their own. Just don't use emacs 🙃

    I use vi/vim almost exclusively. I just enjoy poking fun at the people who are evangelical about it.



  • @coliver said in Install Nginx as a Reverse Proxy on Fedora 27:

    @stacksofplates said in Install Nginx as a Reverse Proxy on Fedora 27:

    @jaredbusch said in Install Nginx as a Reverse Proxy on Fedora 27:

    @coliver said in Install Nginx as a Reverse Proxy on Fedora 27:

    @jaredbusch 0_1524226298968_a9d48ad2-c13d-440c-94c5-a6951b5f6887-image.png

    Pretty much exactly

    I can't make fun. I prefer Vim. I've tried to use nano and I felt clunky. But to each their own. Just don't use emacs 🙃

    I use vi/vim almost exclusively. I just enjoy poking fun at the people who are evangelical about it.

    Given a choice, nano. I'm good with vi/vim as well tho, IRIX really required competency with it.