For a few years now I have been a fan of CentOS for my servers, its light weight and simple to use. Lately I have been experimenting with HTTP/2 and trying to have my server serve my pages as quickly and modernly as possible which I have written about in other articles.
CentOS 7.3 how ever doesn't come with all which is needed to serve your page over HTTP/2 out of the box. So have have made this article as a collection of links and tutorials to have it working on CentOS.
This was done on a clean installation of CentOs 7.3 on a DigitalOcean Droplet.
Start by updating your installation with:
yum update
OpenSSL
NGINX needs OpenSSL 1.0.2 to function however CentOS 7.3 comes with 1.0.1e pre-installed. CentOS 7.4 which should be released around August/September 2017 comes with 1.0.2 installed. So if you have 7.4 you can skip this step.
Start by installing the Development tools.
yum groupinstall "Development Tools"
First check your OpenSSL version.
openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
You can also check the available version in the vendors directory too.
yum info openssl
To download the latest version of OpenSSL, do as follows:
cd /usr/local/src
wget https://www.openssl.org/source/openssl-1.0.2-latest.tar.gz
tar -zxf openssl-1.0.2-latest.tar.gz
To manually compile OpenSSL and install/upgrade OpenSSL, do as follows:
cd openssl-1.0.2k
./config
make
make test
make install
If the old version is still displayed or installed before, please make a copy of openssl bin file :
mv /usr/bin/openssl /root/
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
Now verify the OpenSSL version.
openssl version
OpenSSL 1.0.2k 26 Jan 2017
NGINX
For installing nginx 1.13 install the following REPO. This usually includes OpenSSL as well, but I prefer to install it myself.
https://brouken.com/brouken-centos-7-repo/
yum -y install yum-utils
yum-config-manager --add-repo https://brouken.com/brouken.repo
Additional highly recommended configuration (if you’re using EPEL!):
yum-config-manager --save --setopt=epel.exclude=nginx*;
Then just install NGINX like this:
yum install nginx
To check that NGINX installed correctly:
nginx -v
Which should output something like:
nginx version: nginx/1.13.2
Optional, change SSH port
When ever I create a new droplet on digitalocean, after just a month or so using I start having a lot unsuccessful logins on my server, probably being one or multiple hacking robots trying to access my server. A simple solution to make it slightly more safe for yourself I prefer to change the SSH port to something else random.
As a root user edit the ssh config file:
vi /etc/ssh/sshd_config
Find the line with
# Port 22
Remove the # and change 22 to the port you want to use instead. Like 222 or 333 or whatever else you prefer. Just make sure you remember it.
Then restart the SSH service
service sshd restart
Get some SSL certificates
HTTP/2 needs https to work. So you'll need to get some valid certificates to get it working. Check out Let's encrypt to get some.
When you have the certs you could create a dhparam's file for extra security like this:
cd /etc/ssl/certs (use your path provided by letsencrypt)
openssl dhparam -out dhparam.pem 4096
Setup NGINX
Enabling nginx with http2 and https
Start by creating a config file for your domain.
vi /etc/nginx/conf.d/example.com.conf
Paste the following and change example.com for your domain and change the paths for the certificates to the ones provided by lets encrypt.
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_dhparam /etc/letsencrypt/live/example.com/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";
add_header Strict-Transport-Security max-age=31536000;
add_header X-Frame-Options SAMEORIGIN;
location / {
limit_req zone=one burst=20 nodelay;
proxy_pass http://localhost:2368; <- make this line point to where your web site is running.
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;
}
}
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
Then lastly to speedup the loading of your page you can add GZIPPING to your NGINX settings.
vi /etc/nginx/nginx.conf
After gzip, add:
gzip on;
##
# SSL settings
##
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Forward secrecy settings
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
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";
Conclusion
This is pretty much it. My server is running a ghost blog which runs on port 2368 so as seen in the nginx setup its pointing to the blog. You should now be able to test your page and see it is now being served over HTTP/2 and with https enabled.
To test the security of your page you can use this url and change to your domain: https://www.ssllabs.com/ssltest/analyze.html?d=example.com