Setting up a Highly responsive site with HTTP/2 and NGINX on a CentOS 7.6 VPS

Ghost is not installed.

But before we can start it we need to setup the Firewall, SELinux and NGINX.

We will also get a certificate so we can use HTTPS and HTTP/2.

0 to access the blog.

In the firewall we want to open port 80 which is the default port for HTTP and port 443 which is the default for HTTPS and we want to add the http and https protocols to the firewall as well.

Do the following commands and check that the results looks similar to the results below.

# sudo firewall-cmd — staterunning# sudo firewall-cmd — get-default-zonepublic# sudo firewall-cmd — get-active-zonespublic interfaces: eth0# sudo firewall-cmd — list-allpublic (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: ssh dhcpv6-client ports: 2244/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:# sudo firewall-cmd — zone=public — permanent — add-service=httpsuccess# sudo firewall-cmd — zone=public — permanent — add-service=httpssuccess# sudo firewall-cmd — zone=public — permanent — add-port=80/tcpsuccess# sudo firewall-cmd — zone=public — permanent — add-port=443/tcpsuccess# sudo firewall-cmd — reloadsuccess# sudo firewall-cmd — list-allpublic (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: ssh dhcpv6-client http https ports: 2244/tcp 80/tcp 443/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:“`And thats it, the firewall is ready.

Let’s encrypt & CertbotIn this tutorial I will use Let’s encrypt to get free certificates for the site to be used with HTTPS but you can obviously use whatever provider you want.

The following two commands will install certbot on your server.

# sudo yum install epel-release# sudo yum install certbot-nginxNext we will request a certificate for the domain which this server is connected to and where you want your blog to be.

In this step I expect that you already have a domain and its connected to the droplet you’re currently connected to.

# sudo certbot certonlyHere you get three options, I usually go with: spin up temp web server.

Fill in all info for you and your domain.

If all goes well you will get a long success message and the location to where your certificates are installed.

NGINXNow its time to install NGINX and set it up to serve your ghost blog over HTTP/2.

0 which includes HTTPS by default and we’ll redirect all the normal HTTP traffic to HTTPS.

 Yum doesn come with the NGINX repo in it so we’ll start by adding a new repofile like this# sudo vi /etc/yum.

repos.

d/nginx.

repoand paste the following text in the file.

[nginx]name=nginx repobaseurl=http://nginx.

org/packages/centos/$releasever/$basearch/gpgcheck=0enabled=1Save and quit, then install nginx.

# sudo yum install nginx# sudo systemctl status nginxWe wont start NGINX just yet, so the status should be inactive.

Then we will edit the nginx config file.

What we want to do is change min max allowed file upload size to 50mb, the default is 2mb, so you can upload photos or files larger than 2mb to your blog.

Then we will add some settings for https with which protocols and ciphers to use.

And the last three lines are for activating some cache so your blog can be served faster.

Look out for any duplicate lines.

# sudo vi /etc/nginx/nginx.

confAdd the following after line with `#gzip on;`client_max_body_size 50M; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # Forward secrecy settings ssl_protocols TLSv1.

2 TLSv1.

3; ssl_prefer_server_ciphers on; ssl_ciphers “EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4”;ssl_stapling on;ssl_stapling_verify on;include /etc/nginx/conf.

d/*.

conf;server { listen 127.

0.

0.

1; server_name localhost;}proxy_cache_path /home/toor/ghostcache levels=1:2 keys_zone=ghostcache:60m max_size=300m inactive=24h; proxy_cache_key “$scheme$request_method$host$request_uri”; proxy_cache_methods GET HEAD;save quitNext we will add a config file specifically for the domain you want to use, which I will call “myghostblog.

com” here.

Change it to whatever name you want.

# sudo vi /etc/nginx/conf.

d/myghostblog.

com.

confWhat you see here below is the settings I use on my domain.

I’m mainly defining everything which should happen on port 443 (https) and as a last thing I redirect any requests on port 80 (http) to port 443.

Ghost generally runs on port 2368 and since it runs on this server we will tell NGINX to point any requests to http://127.

0.

0.

1:2368, if you use a different port just change to that port in the two places below.

Then you can see ssl_certificate and …_key, they are the keys which was created during the certbot step.

Put the correct file locations below.

We will again specify some ciphers and protocols for https.

Then in the 4 sections starting with location we’re setting up some caching, some response headers, and the physical file locations to be use on the server for serving some of the blog content.

So copy and paste the below part with your changes.

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;server { listen 443 ssl http2; listen [::]:443 ipv6only=on ssl http2; gzip off; server_name myghostblog.

com; ssl_certificate /etc/letsencrypt/live/myghostblog.

com/fullchain.

pem; ssl_certificate_key /etc/letsencrypt/live/myghostblog.

com/privkey.

pem; ssl_dhparam /etc/nginx/ssl/dhparam.

pem; ssl_ciphers “EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4”; ssl_protocols TLSv1.

2 TLSv1.

3; add_header Strict-Transport-Security max-age=31536000; add_header X-Frame-Options SAMEORIGIN;location / { proxy_cache ghostcache; proxy_cache_valid 60m; proxy_cache_valid 404 1m; proxy_cache_bypass $http_cache_control; proxy_ignore_headers Set-Cookie; proxy_hide_header Set-Cookie; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_ignore_headers Cache-Control; add_header X-Cache-Status $upstream_cache_status;limit_req zone=one burst=20 nodelay; proxy_pass http://127.

0.

0.

1:2368; proxy_set_header Host $http_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; proxy_buffering off;}location ^~ /assets/ { root /home/toor/ghost/content/themes/casper;}location ^~ /content/images/ { root /home/toor/ghost;}location ^~ /ghost/ { proxy_set_header Host $http_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; proxy_pass http://127.

0.

0.

1:2368; }}server { listen 80; listen [::]:80 ipv6only=on; server_name myghostblog.

com; return 301 https://$server_name$request_uri;}Then save and quit.

In the file above you might have seen linking to a file called dhparam.

pem.

This is an extra certificate for some added security over https which we need to create which can be done with the two following steps.

# sudo mkdir /etc/nginx/ssl# sudo openssl dhparam -out /etc/nginx/ssl/dhparam.

pem 4096This can take a while so go and grab yourself something to drink.

When done we also need to create the folder we have specified above for the caching.

# sudo mkdir /home/toor/ghostcacheDone!.Now we want to check that all the next NGINX configurations are correct.

Just type nginx -t, -t is for test.

# sudo nginx -tWhich hopefully will outputnginx: the configuration file /etc/nginx/nginx.

conf syntax is oknginx: configuration file /etc/nginx/nginx.

conf test is successfulAt this moment you can try to start NGINX, but it will most likely fail.

# sudo systemctl start nginxJob for nginx.

service failed because a configured resource limit was exceeded.

See “systemctl status nginx.

service” and “journalctl -xe” for details.

Check the NGINX status to find the problem.

# sudo systemctl status nginx.

service● nginx.

service — nginx — high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.

service; disabled; vendor preset: disabled) Active: failed (Result: resources) since Wed 2019–02–13 11:59:42 UTC; 19s ago Docs: http://nginx.

org/en/docs/ Process: 28161 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.

conf (code=exited, status=0/SUCCESS)Feb 13 11:59:41 temp-test systemd[1]: Starting nginx — high performance web server…Feb 13 11:59:42 temp-test nginx[28161]: nginx: [emerg] open() “/var/run/nginx.

pid” failed (13: Permission denied)Feb 13 11:59:42 temp-test systemd[1]: Failed to read PID from file /var/run/nginx.

pid: Invalid argumentFeb 13 11:59:42 temp-test systemd[1]: Failed to start nginx — high performance web server.

Feb 13 11:59:42 temp-test systemd[1]: Unit nginx.

service entered failed state.

Feb 13 11:59:42 temp-test systemd[1]: nginx.

service failed.

selinux and nginx problem: nginx: [emerg] open() “/var/run/nginx.

pid” failed (13: Permission denied)As you can see SELinux is blocking NGINX, so we need to let SELinux know that NGINX is cool.

For that we need to install policycoreutils-devel and allow NGINX to run.

# sudo yum install -y policycoreutils-devel# sudo grep nginx /var/log/audit/audit.

log | audit2allow -M nginx# sudo semodule -i nginx.

ppTry again to start NGINX.

# sudo systemctl start nginx# sudo systemctl status nginx.

service● nginx.

service — nginx — high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.

service; disabled; vendor preset: disabled) Active: active (running) since Wed 2019–02–13 12:05:49 UTC; 5s ago Docs: http://nginx.

org/en/docs/ Process: 28917 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.

conf (code=exited, status=0/SUCCESS) Main PID: 28918 (nginx) CGroup: /system.

slice/nginx.

service ├─28918 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.

conf ├─28919 nginx: worker process ├─28920 nginx: cache manager process └─28921 nginx: cache loader processFeb 13 12:05:49 temp-test systemd[1]: Starting nginx — high performance web server…Feb 13 12:05:49 temp-test systemd[1]: PID file /var/run/nginx.

pid not readable (yet?) after start.

Feb 13 12:05:49 temp-test systemd[1]: Started nginx — high performance web server.

Now nginx is running.

Try to visit your domain!It should show you a 502 bad gateway error because we haven’t started ghost yet.

But before we do that we need to allow http to use the port ghost uses in SELinux.

# sudo semanage port — add — type http_port_t — proto tcp 2368And we also need to allow nginx serve files directly and allow it to cache which again we need to tell SELinux.

# sudo chcon -R -t httpd_sys_content_t /home/toor/ghostAnd finally lets start ghost.

# cd ghost# ghost startVisit your domain again!Let me know if you liked this tutorial.

.

. More details

Leave a Reply