As part of berrynews.org, I have been battling for quite some time with certificates. I was so upset at one point that I even blocked port :80
at fw --firewall level and stopped all traffic on http
.
But that is not the way things should be handled, and even though it took me about 3 days to figure it out, now, I can proudly say that I have the recipe for success.
Here is the specific situation the article will tackle:
- 1x apache2 web-server
- 1x primary domain: berrynews.org
- 2x subdomains:
- certificates are generated using certbot -- free SSL certificate generator
- DNS provider is GoDaddy
- certificate is
invalid
for www.berrynews.org - www.edu.berrynews.org and www.crypto.berrynews.org
do not exist
and when you try to access them you get anerror
Outcome:
- www and non-www will have valid SSL certificates
- HTTP requests will be redirected at the web server level to HTTPS
You Can Configure SSL Certificates in 3 Steps
- Domain and DNS Setup
- Web Server Configuration
- Obtain SSL Certificates
To configure SSL certificates for both www
and non-www
versions of a domain, as well as for subdomains, see below for detailed steps:
-
Domain and DNS Setup:
-
Ensure that your domain and subdomains are properly set up in your DNS settings. You should have
A
records pointing to both the root domain (@
) and thewww
version to your server's IP address.
-
For subdomains, you should have
A
orCNAME
records pointing each subdomain to the server's IP address or the main domain, respectively.
DNS setup example with emphasis on: 2xA → server IP, 2x
CNAME
for each subdomain; Domain: berrynews.org ; Exported (y-m-d hh:mm:ss): 2023-11-08 13:03:00 ; ; This file is intended for use for informational and archival ; purposes ONLY and MUST be edited before use on a production ; DNS server. ; ; In particular, you must update the SOA record with the correct ; authoritative name server and contact e-mail address information, ; and add the correct NS records for the name servers which will ; be authoritative for this domain. ; ; For further information, please consult the BIND documentation ; located on the following website: ; ; http://www.isc.org/ ; ; And RFC 1035: ; ; http://www.ietf.org/rfc/rfc1035.txt ; ; Please note that we do NOT offer technical support for any use ; of this zone data, the BIND name server, or any other third- ; party DNS software. ; ; Use at your own risk. $ORIGIN berrynews.org. ; SOA Record @ 3600 IN SOA ns35.domaincontrol.com. dns.jomax.net. ( 2023110806 28800 7200 604800 3600 ) ; A Record @ 600 IN A 94.211.67.63 www 600 IN A 94.211.67.63 ; NS Record @ 3600 IN NS ns35.domaincontrol.com. @ 3600 IN NS ns36.domaincontrol.com. ; CNAME Record crypto 3600 IN CNAME @ edu 3600 IN CNAME @ www.crypto 3600 IN CNAME crypto.berrynews.org. www.edu 3600 IN CNAME edu.berrynews.org.
-
-
Web Server Configuration:
-
Configure your web server (Apache, Nginx, etc.) to serve both the
www
and non-www
versions of your domain, as well as any subdomains. This usually involves setting up server blocks or virtual hosts for each.
Here is how
/etc/apache2/sites-enabled/000-default.conf
should look like, with emphasis onServerName
,ServerAlias
andRewrite*
<VirtualHost *:80> # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. ServerName berrynews.org ServerAlias www.berrynews.org DocumentRoot /var/www/html/ # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # For most configuration files from conf-available/, which are # enabled or disabled at a global level, it is possible to # include a line for only one particular virtual host. For example the # following line enables the CGI configuration for this host only # after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf RewriteEngine on RewriteCond %{HTTP_HOST} ^www\.berrynews\.org [NC,OR] RewriteCond %{HTTP_HOST} ^berrynews\.org [NC] RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </VirtualHost> <VirtualHost *:80> ServerName edu.berrynews.org ServerAlias www.edu.berrynews.org DocumentRoot /var/www/html/edu <Directory /var/www/html/edu> Options Indexes FollowSymLinks MultiViews AllowOverride all Order allow,deny allow from all Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.edu.log CustomLog ${APACHE_LOG_DIR}/access.edu.log combined </VirtualHost> <VirtualHost *:80> ServerName crypto.berrynews.org ServerAlias www.crypto.berrynews.org DocumentRoot /var/www/html/crypto <Directory /var/www/html/crypto> Options Indexes FollowSymLinks MultiViews AllowOverride all Order allow,deny allow from all Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/error.crypto.log CustomLog ${APACHE_LOG_DIR}/access.crypto.log combined # Add Rewrite rules here if you want to force HTTPS for the crypto subdomain RewriteEngine on RewriteCond %{SERVER_NAME} =crypto.berrynews.org [OR] RewriteCond %{SERVER_NAME} =www.crypto.berrynews.org RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
Here is how
/etc/apache2/sites-enabled/000-default-le-ssl.conf
should look like, with emphasis onServerName
,ServerAlias
andSSLCert*
Replace berrynews.org with your own domain ++ you can skip the SSLCert; it will automatically be added by certbot.
<IfModule mod_ssl.c> <VirtualHost *:443> #Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self';" # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. ServerName berrynews.org ServerAlias www.berrynews.org DocumentRoot /var/www/html # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # For most configuration files from conf-available/, which are # enabled or disabled at a global level, it is possible to # include a line for only one particular virtual host. For example the # following line enables the CGI configuration for this host only # after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/berrynews.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/berrynews.org/privkey.pem </VirtualHost> </IfModule> <IfModule mod_ssl.c> <VirtualHost *:443> ServerName edu.berrynews.org ServerAlias www.edu.berrynews.org DocumentRoot /var/www/html/edu <Directory /var/www/html/edu> Options Indexes FollowSymLinks MultiViews AllowOverride all Order allow,deny allow from all Require all granted </Directory> ErrorLog /var/log/apache2/error.edu.log CustomLog /var/log/apache2/access.edu.log combined Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/edu.berrynews.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/edu.berrynews.org/privkey.pem </VirtualHost> </IfModule> <IfModule mod_ssl.c> <VirtualHost *:443> ServerName crypto.berrynews.org ServerAlias www.crypto.berrynews.org DocumentRoot /var/www/html/crypto <Directory /var/www/html/crypto> Options Indexes FollowSymLinks MultiViews AllowOverride all Order allow,deny allow from all Require all granted </Directory> ErrorLog /var/log/apache2/error.crypto.log CustomLog /var/log/apache2/access.crypto.log combined Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/crypto.berrynews.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/crypto.berrynews.org/privkey.pem </VirtualHost> </IfModule>
-
-
Obtain SSL Certificates:
-
Use a tool like Let's Encrypt's Certbot to obtain SSL certificates. You can include multiple domains and subdomains in a single certificate by using the
-d
flag multiple times, like so:sudo certbot --apache -d example.com -d www.example.com -d subdomain.example.com
-
Follow the Certbot prompts to complete the validation process and install the certificates.
Here’s a snippet from my
history
in-hash:1144 sudo certbot --apache -d berrynews.org -d www.berrynews.org 1150 sudo certbot --apache -d berrynews.org -d www.berrynews.org 1176 sudo certbot --apache -d crypto.berrynews.org -d www.crypto.berrynews.org 1190 sudo certbot --apache -d crypto.berrynews.org -d www.crypto.berrynews.org 1197 sudo certbot --apache -d edu.berrynews.org -d www.edu.berrynews.org 1202 sudo certbot --apache -d edu.berrynews.org -d www.edu.berrynews.org
-
-
Web Server SSL Configuration:
- For each virtual host or server block, configure the paths to the SSL certificate and private key provided by Let's Encrypt.
- Ensure you have the
SSLEngine on
directive for Apache or the equivalent for other web servers.
-
Include a
ServerName
directive for the non-www
version and aServerAlias
directive for thewww
version. For subdomains, set up a separate virtual host or server block with itsServerName
.
This has been tackled at point 2, if point 3 fails remove SSL certificates from ssl.conf
-
Redirection Rules:
-
Implement redirection rules in your server configuration to redirect HTTP traffic to HTTPS, and optionally redirect
www
to non-www
or vice versa, based on your preference.This has been tackled at point 2, use the example from .conf file
-
-
Test Configuration:
-
After making changes to your web server configuration, always test to make sure there are no syntax errors. For Apache, you can use:
sudo apachectl configtest
-
If the syntax is OK, restart your web server to apply the changes.
# example output root@berrynews:/home/ubuntu# sudo apachectl configtest Syntax OK
-
-
Verification:
-
Verify that your domains and subdomains are correctly serving content over HTTPS by using
curl
or by visiting them in a web browser.
-
You can also use online tools to test your SSL setup, such as SSL Labs' SSL Test.
curl -Iv https://berrynews.org curl -Iv https://www.berrynews.org curl -Iv https://edu.berrynews.org curl -Iv https://www.edu.berrynews.org curl -Iv https://crypto.berrynews.org curl -Iv https://www.crypto.berrynews.org
The
curl
response should return 200!curl -Iv https://www.crypto.berrynews.org * Trying 94.211.67.63:443... * Connected to www.crypto.berrynews.org (94.211.67.63) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * CAfile: /etc/ssl/certs/ca-certificates.crt * CApath: /etc/ssl/certs * TLSv1.0 (OUT), TLS header, Certificate Status (22): * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS header, Certificate Status (22): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS header, Finished (20): * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.2 (OUT), TLS header, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS header, Supplemental data (23): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=crypto.berrynews.org * start date: Nov 8 18:47:08 2023 GMT * expire date: Feb 6 18:47:07 2024 GMT * subjectAltName: host "www.crypto.berrynews.org" matched cert's "www.crypto.berrynews.org" * issuer: C=US; O=Let's Encrypt; CN=R3 * SSL certificate verify ok. * TLSv1.2 (OUT), TLS header, Supplemental data (23): > HEAD / HTTP/1.1 > Host: www.crypto.berrynews.org > User-Agent: curl/7.81.0 > Accept: */* > * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.2 (IN), TLS header, Supplemental data (23): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * TLSv1.2 (IN), TLS header, Supplemental data (23): * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < Date: Wed, 08 Nov 2023 20:43:39 GMT Date: Wed, 08 Nov 2023 20:43:39 GMT < Server: Apache/2.4.52 (Ubuntu) Server: Apache/2.4.52 (Ubuntu) < Last-Modified: Wed, 08 Nov 2023 20:38:01 GMT Last-Modified: Wed, 08 Nov 2023 20:38:01 GMT < ETag: "14585-609aa103f57f4" ETag: "14585-609aa103f57f4" < Accept-Ranges: bytes Accept-Ranges: bytes < Content-Length: 83333 Content-Length: 83333 < Vary: Accept-Encoding Vary: Accept-Encoding < Content-Type: text/html Content-Type: text/html < * Connection #0 to host www.crypto.berrynews.org left intact
-
-
Renewal Setup:
-
Ensure that automatic renewal of certificates is set up. Certbot usually does this for you by creating a cron job or systemd timer.
-
-
Firewall Configuration:
-
Make sure your firewall is configured to allow HTTPS traffic on port 443.
-
-
Monitor and Maintain:
- Regularly check your websites to ensure that SSL certificates are being renewed and that there are no security warnings. It's also good practice to stay informed about any updates to your web server software or the Certbot tool.
By point 3 with certificate generation, you should already be done.
Hope this helped, and feel free to reach out if you have any questions.
If you liked the article & would like to support content creators such as myself,
Make sure to:
🔔 Follow me Bogdan Tudorache