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:
- The manipulations are carried out on Rocky Linux 8.
- Throughout this post, we will access the server via its domain name
blog.local
which is related to its local IP address. - In some snippets of code, the domain name
blog.domain.fr
must be replaced by the one you assigned to your public server.
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 site.zip *
Send it to your server
scp site.zip blog.local:/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/site.zip -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.
sudo sed -i "352i ServerTokens Prod" /etc/httpd/conf/httpd.conf
General TLS configurations
Add these headers and the cache configuration for OCSP stapling just after #SSLCryptoDevice ubsec
into /etc/httpd/conf.d/ssl.conf
. Also, set the Diffie-Hellman parameters’ path and the temporary curve used for ephemeral ECDH modes.
# Headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
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)"
# Key exchange
SSLOpenSSLConfCmd DHParameters "/etc/pki/tls/private/dhparam.pem"
SSLOpenSSLConfCmd Curves secp384r1
Next, you must generate the Diffie-Hellman’s parameters. Here, the size of the generated parameters 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
Disable TLS session tickets and enable the addition of OCSP responses to TLS negociation.
sudo sed -i "214i SSLSessionTickets Off" /etc/httpd/conf.d/ssl.conf
sudo sed -i "215i SSLUseStapling On" /etc/httpd/conf.d/ssl.conf
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 secp384r1
but you can use another one by executing openssl ecparam -list_curves
.
sudo openssl ecparam -check -name secp384r1 -genkey -noout -out /etc/pki/tls/private/privkey.pem -rand /dev/urandom
checking elliptic curve parameters: ok
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) []:Auvergne-Rhone-Alpes
Locality Name (eg, city) [Default City]:Lyon
Organizational Name (eg, company) [Default Company Ltd]:Illuad Technologies
Organizational Unit Name (eg, section) []:IT Security
Common Name (eg, your name or your server's hostname) []:blog.local
Email Address []:contact@blog.local
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.local:80
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /var/www/blog
ServerName blog.local:443
ServerAlias blog.local
ServerAdmin contact@blog.local
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
</VirtualHost>
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
</FilesMatch>
Enable and start HTTPD service
sudo systemctl enable --now httpd