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.
- You are going to use
certbot --nginx
to obtain your certs
- You already have the FQDN setup for your domain.
- I am using
nc.domain.com
as an example.
- You already have the backend Nextcloud server setup and listening on port
80
.
- 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