← Back to Apache Course | Chapter 3: Modules | Lesson 2 of 5

mod_ssl

mod_ssl is the Apache module that adds HTTPS support -- encrypting traffic between the browser and the server using TLS certificates. Without it, Apache can only serve plain, unencrypted HTTP.

Enabling mod_ssl

On Ubuntu/Debian: sudo a2enmod ssl followed by a reload. On RHEL-family systems, installing the mod_ssl package (sudo yum install mod_ssl) both installs and enables it, and typically drops a starter /etc/httpd/conf.d/ssl.conf.

The Key Directives

Inside a <VirtualHost *:443> block, three directives do the essential work: SSLEngine On turns TLS on for that virtual host, SSLCertificateFile points to the site's certificate, and SSLCertificateKeyFile points to its private key. Many CAs also require SSLCertificateChainFile (or a combined bundle) to supply intermediate certificates so browsers can verify the chain of trust.

Getting a Certificate

You need an actual TLS certificate before any of this works. Let's Encrypt, via the free certbot tool, is the standard modern choice and can even edit your Apache VirtualHost automatically with certbot --apache. A self-signed certificate works for local testing but will show a browser warning, since no public certificate authority vouches for it.

Redirecting HTTP to HTTPS

A separate <VirtualHost *:80> block for the same domain typically exists purely to redirect visitors who type the plain http:// address over to https://, usually with mod_rewrite (as shown in the previous lesson) or a plain Redirect permanent / https://example.com/.

Note: Keep the certificate paths in sync with your renewal tool -- Let's Encrypt certificates expire every 90 days, and certbot renew (usually run automatically via a cron job or systemd timer) needs to actually reload Apache afterward for the new certificate to take effect.

Example: An HTTPS VirtualHost with mod_ssl

apacheconf
<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/example.com/public

    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/example.com.key
    SSLCertificateChainFile /etc/ssl/certs/example.com-chain.crt
</VirtualHost>

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com/
</VirtualHost>
{# Flagged by hand after confirming a runner can't handle this example (a shell command / go.mod file stored as a TopicExample, a language feature the configured runner version doesn't support, or output that blows a runner's sandbox limit) -- see TopicExample.norun. Never render the run button for these, regardless of language, since it would just fail at execute_code (or worse, hang the Judge0 queue on a submission that can never finish cleanly). #}

⚠️ This example can't run in the browser editor. Try it in your own local environment instead.

{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Pointing SSLCertificateFile at just the domain certificate and skipping SSLCertificateChainFile/the intermediate bundle, which works in some browsers but fails validation in others.
  2. Forgetting the separate port 80 VirtualHost, so visitors who type the bare domain without https:// never get redirected to the secure version.
  3. Letting a Let's Encrypt certificate expire because the renewal job never actually reloads Apache after renewing, leaving the old (now-invalid) certificate file in use.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.