paint-brush
SSL Certificates for Both www and non-www versions of a Domainby@tudoracheabogdan
358 reads
358 reads

SSL Certificates for Both www and non-www versions of a Domain

by Bogdan TudoracheNovember 8th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

TL;DR: Secure your main and subdomains with SSL; use Certbot for setup and validation; implement HTTPS redirects for safety.
featured image - SSL Certificates for Both www and non-www versions of a Domain
Bogdan Tudorache HackerNoon profile picture

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 an error


Outcome:

  1. www and non-www will have valid SSL certificates
  2. HTTP requests will be redirected at the web server level to HTTPS

You Can Configure SSL Certificates in 3 Steps

  1. Domain and DNS Setup
  2. Web Server Configuration
  3. 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:

  1. 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 the www version to your server's IP address.


    • For subdomains, you should have A or CNAME 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.
    
    
    


  2. 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 on ServerName, ServerAlias and Rewrite*

      <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 on ServerName, ServerAlias and SSLCert*


      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>
    
    
  3. 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
      
  4. 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.


  5. Include a ServerName directive for the non-www version and a ServerAlias directive for the www version. For subdomains, set up a separate virtual host or server block with its ServerName.


    This has been tackled at point 2, if point 3 fails remove SSL certificates from ssl.conf


  6. 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


  7. 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
      
  8. 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
    
  9. 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.


  10. Firewall Configuration:

    • Make sure your firewall is configured to allow HTTPS traffic on port 443.


  11. 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

🔔 Connect w/ me: LinkedIn | Reddit