Deploy a Jekyll site

Jekyll is a static site generator developed in Ruby.

Information and requirements

These elements are to be taken into consideration to follow this article:

Preliminary steps

Build your site

Once you’re ready to deploy your site, build it.

bundler exec jekyll build

Zip your static files

cd _site/
zip -qr *

Send it to your server

scp blog.lan:/tmp

Update the system

sudo dnf -y update

Install required utilities

sudo dnf -y install vim httpd mod_ssl unzip epel-release firewalld

Unzip your files

sudo mkdir -p /var/www/blog
sudo unzip -q /tmp/ -d /var/www/blog

Set correct permissions

sudo chown -R apache:apache /var/www/blog
sudo find /var/www/blog -type d -exec chmod 0755 {} \;
sudo find /var/www/blog -type f -exec chmod 0644 {} \;

HTTPD configurations

General configurations

By adding ServerTokens Prod directive, you remove the Apache2 version from HTTP headers, it’s a good practice for security reasons.

echo "ServerTokens Prod" | sudo tee -a /etc/httpd/conf/httpd.conf

General TLS configurations

Add these headers and the cache configuration for OCSP stapling just before the default virtual host (<VirtualHost _default_:443>) into /etc/httpd/conf.d/ssl.conf.

# Headers
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set Referrer-Policy no-referrer

# OCSP stapling
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

Set the Diffie-Hellman parameters. First, you must generate the parameters. Here, the size of the generated parameter set will be 4096 bits.

sudo openssl dhparam -out /etc/pki/tls/private/dhparam.pem 4096
sudo chmod 440 /etc/pki/tls/private/dhparam.pem

Then, specify to Apache2 where the file is located via the DHParameters directive.

# Key exchange
SSLOpenSSLConfCmd DHParameters "/etc/pki/tls/private/dhparam.pem"

Disable TLS session tickets and enable the addition of OCSP responses to TLS negociation just before the end of the virtual host (</VirtualHost>) into /etc/httpd/conf.d/ssl.conf.

SSLSessionTickets Off
SSLUseStapling On

Accept all protocols except those before TLSv1.2.

sudo sed -i 's/#SSLProtocol.*/SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1/' /etc/httpd/conf.d/ssl.conf

Generate a self-signed certificate (local server only)

Generate a private key for a curve. Here, I use the curve secp521r1 but you can use another one by executing openssl ecparam -list_curves.

sudo openssl ecparam -check -name secp521r1 -genkey -noout -out /etc/pki/tls/private/privkey.pem -rand /dev/urandom
checking elliptic curve parameters: ok

You can set the temporary curve used for ephemeral ECDH modes. You can use the same curve you just used to generate the private key. Add the following statement juste after the SSLOpenSSLConfCmd DHParameters directive into /etc/httpd/conf.d/ssl.conf.

SSLOpenSSLConfCmd ECDHParameters secp521r1

Create a self-signed certificate. Feel free to personalize the answers to the questions asked. This self-signed certificate is used for testing purposes so it is not essential that the information given is correct.

sudo openssl req -utf8 -new -x509 -key /etc/pki/tls/private/privkey.pem -out /etc/pki/tls/certs/cert.pem -days 365 -rand /dev/urandom
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letters code) [XX]:FR
State or Province Name (full name) []:Rhone-Alpes
Locality Name (eg, city) [Default City]:Lyon
Organizational Name (eg, company) [Default Company Ltd]:Blog
Organizational Unit Name (eg, section) []:IT Department
Common Name (eg, your name or your server's hostname) []:blog.lan
Email Address []:contact@blog.lan

Set the correct permission.

sudo chmod 440 /etc/pki/tls/private/privkey.pem
sudo chmod 644 /etc/pki/tls/certs/cert.pem

Then, create the virtual host configuration into /etc/httpd/conf.d/vhost.conf.

<VirtualHost *:80>
    ServerName blog.lan:80
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

<VirtualHost *:443>
    DocumentRoot /var/www/blog

    ServerName blog.lan:443
    ServerAlias blog.lan
    ServerAdmin contact@blog.lan

    SSLCertificateFile /etc/pki/tls/certs/cert.pem
    SSLCertificateKeyFile /etc/pki/tls/private/privkey.pem
    SSLCACertificateFile /etc/pki/tls/certs/cert.pem

    Protocols h2 http/1.1

    ErrorDocument 404 /404.html

    ErrorLog /var/log/blog/error_log
    CustomLog /var/log/blog/access_log combined

Request a Let’s Encrypt certificate (public server only)

In case you wish to obtain free certificates (via Let’s Encrypt), two methods are available to you. Luck is on your side, you will find here the method to obtain a certificate from Let’s Encrypt, and here a slightly more advanced method that allows you to obtain a certificate based on elliptic curve cryptography (still via Let’s Encrypt).

The reverse proxy configuration is the exact same. Things you have to modify are the location of the certificate, private key and the chain of trust, but it is documented in the article previously mentionned.

Create the logs directory

sudo mkdir -p /var/log/blog

Modify the security context

sudo chcon -R -t httpd_sys_content_t /var/www/blog
sudo setsebool -P httpd_read_user_content on

Modify authorized ports

sudo firewall-cmd --add-port={80/tcp,443/tcp} --permanent
sudo firewall-cmd --reload

Enable gzip compression

The HTTP server’s module mod_deflate allows to compress HTML, CSS and JS files into gzip. Thus you can reduce the load of the transmitted data by up to 70%. It will reduce your website’s loading time.

Copy the following snippet into /etc/httpd/conf.d/mod_deflate.conf.

<FilesMatch "\.(js|html|css)$">
    SetOutputFilter DEFLATE

Enable and start HTTPD service

sudo systemctl enable --now httpd.service