VMware ESXi and vSphere Cluster Management

Configure HTTPS (SSL/TLS) for Apache

Learn to enable mod_ssl, configure Apache HTTPS virtual hosts, install certificates, open port 443, and verify secure access on Ubuntu or Debian.

What HTTPS does

HTTPS is HTTP transported over TLS. It encrypts traffic between a browser and the Apache web server, helping prevent other parties on the network from reading or modifying requests and responses.

During a TLS connection, Apache presents a certificate. This public identity document contains the site name and a public cryptographic key. Apache also uses the matching private key, which must remain secret. Together, they help authenticate the server and establish encrypted communication.

Apache requires the mod_ssl module to serve HTTPS. Although Apache configuration commonly uses the word “SSL”, modern secure deployments use TLS rather than the obsolete SSL protocols.

Prerequisites and the Debian/Ubuntu layout

This lesson assumes Apache is installed, running, and already serving a working HTTP site. You should also have a domain name resolving to the server when configuring a public site, plus a certificate and matching private key for that domain.

Common Apache locations on Debian and Ubuntu include:

Purpose — Typical path — Notes

Default SSL site configuration/etc/apache2/sites-available/default-ssl.conf — Packaged HTTPS virtual-host configuration.

Default HTTP site configuration/etc/apache2/sites-available/000-default.conf — Packaged HTTP virtual host.

Enabled sites/etc/apache2/sites-enabled/ — Contains links to configurations enabled with a2ensite.

Available sites/etc/apache2/sites-available/ — Stores configurations that are not necessarily active.

Test certificate/etc/ssl/certs/ssl-cert-snakeoil.pem — Distribution-provided self-signed certificate for testing.

Test private key/etc/ssl/private/ssl-cert-snakeoil.key — Private key paired with the test certificate.

Default document root/var/www/html — Content directory for the packaged default site.

Access log/var/log/apache2/access.log — Records incoming requests and response details.

Error log/var/log/apache2/error.log — Records startup, configuration, and request-processing errors.

A real site may use a different document root, such as /var/www/example.com. Check the active virtual-host configuration rather than assuming every site uses /var/www/html.

TCP port 443 is the standard HTTPS port. The host firewall and any cloud security group, router, reverse proxy, or load balancer must permit inbound TCP 443.

Enable Apache TLS support

Use Apache's Debian/Ubuntu helper command to enable mod_ssl:

sudo a2enmod ssl

Module activation changes Apache's enabled-module configuration. Apache must be reloaded or restarted before it uses the module. First validate the complete configuration:

sudo apache2ctl configtest

A successful check normally reports Syntax OK. Apply the change with a reload when possible:

sudo systemctl reload apache2

A restart is also available, but it causes a more disruptive service transition:

sudo systemctl restart apache2

Understand the default HTTPS virtual host

An Apache VirtualHost is a configuration block defining a site, including the address and port on which it is served. An HTTPS site normally contains a virtual host listening on port 443:

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

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

The packaged file /etc/apache2/sites-available/default-ssl.conf is the usual starting point. The default HTTP site, commonly /etc/apache2/sites-available/000-default.conf, listens on port 80. The default SSL site is a separate virtual host that serves content over port 443. The two configurations can use the same document root, but they do not have to.

Directive — Purpose — Example

SSLEngine — Enables TLS processing for the virtual host. — SSLEngine on

SSLCertificateFile — Points to the server certificate or certificate-chain file. — /etc/ssl/certs/example.com/fullchain.pem

SSLCertificateKeyFile — Points to the matching private key. — /etc/ssl/private/example.com/privkey.pem

ServerName — Defines the primary hostname for the site. — example.com

ServerAlias — Adds other hostnames handled by the same virtual host. — www.example.com

DocumentRoot — Selects the directory from which content is served. — /var/www/example.com

ErrorLog — Selects the virtual host's error log. — ${APACHE_LOG_DIR}/example.com-ssl-error.log

CustomLog — Selects the access log and its format. — ${APACHE_LOG_DIR}/example.com-ssl-access.log combined

Test certificates and production certificates

The packaged configuration commonly references:

/etc/ssl/certs/ssl-cert-snakeoil.pem
/etc/ssl/private/ssl-cert-snakeoil.key

These are suitable for local or temporary testing. A self-signed certificate is signed by itself instead of by a certificate authority (CA) trusted by browsers. As a result, browsers normally display a trust warning. The connection may still be encrypted, but the warning means the browser cannot verify the server's identity through a trusted chain.

Characteristic — Bundled self-signed certificate — Trusted CA-issued certificate

Appropriate use — Local testing and development. — Public or managed production services.

Browser trust — Usually produces a warning. — Normally trusted when the chain is correctly served.

Hostname validation — May not contain the requested public hostname. — Must include the site's names, usually in subject alternative names.

Public deployment — Not suitable for normal Internet-facing users. — Suitable when valid, current, and correctly configured.

Renewal — Usually replaced manually or with test setup changes. — Must be renewed before expiration and followed by an Apache reload when required.

For a public site, use a certificate issued by a trusted CA and the private key that belongs to that certificate. Do not treat a browser warning as an acceptable normal outcome for public users.

Enable the packaged default HTTPS site

Enable the distribution-provided SSL site with:

sudo a2ensite default-ssl

Validate before applying the configuration:

sudo apache2ctl configtest

If the result is successful, reload Apache:

sudo systemctl reload apache2

Use a restart if a reload does not apply a required change:

sudo systemctl restart apache2

To roll back the enabled default SSL site:

sudo a2dissite default-ssl
sudo apache2ctl configtest
sudo systemctl reload apache2

Visit and verify HTTPS

Open the site with an https URL, for example https://example.com/. For a local test using the bundled certificate, use https://localhost/ and expect a browser trust warning.

Check that Apache is running and that a process is listening on port 443:

sudo systemctl status apache2
sudo ss -ltnp | grep ':443'

Inspect the certificate and TLS handshake with OpenSSL. The -servername option supplies the hostname used for SNI, which helps Apache select the intended HTTPS virtual host:

openssl s_client -connect example.com:443 -servername example.com

For a local self-signed test, make an HTTP request while explicitly allowing the untrusted certificate:

curl -kI https://localhost/

The -k option disables curl's certificate trust verification for this test. Do not use it as a way to hide certificate problems in production. A successful result should show that TLS negotiation completed and that Apache returned an HTTP response. This is different from browser trust: an encrypted response can succeed even while the certificate is untrusted.

Create a dedicated HTTPS virtual host

For a real domain, create a site-specific configuration instead of relying on the packaged default. For example, save the following as /etc/apache2/sites-available/example.com-ssl.conf:

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

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/ssl/private/example.com/privkey.pem

    ErrorLog ${APACHE_LOG_DIR}/example.com-ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-ssl-access.log combined
</VirtualHost>

Ensure the document root exists and contains the intended site. The certificate names must include every hostname users will request, such as both example.com and www.example.com. The certificate file may include the server certificate and required intermediate chain, depending on how the CA provides it.

Enable and apply the dedicated site:

sudo a2ensite example.com-ssl
sudo apache2ctl configtest
sudo systemctl reload apache2

Protect the private key. A typical private-key directory is readable only by root or by the group Apache needs for the configured key-management arrangement. Do not place a private key under a publicly served document root or expose it through source control.

HTTPS name-based virtual hosting depends on the requested hostname and TLS SNI. Apache uses the hostname supplied by the client to select a certificate and virtual host. If the hostname is missing, misspelled, or absent from the certificate, Apache may select a default site or present a certificate-name warning.

Optional HTTP-to-HTTPS redirection

After HTTPS works and the certificate is trusted, redirect the HTTP site so users are sent to the encrypted URL:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

Test the HTTPS site before enabling this redirect. Otherwise, a broken HTTPS configuration can make the site unavailable through both the original and redirected URL.

Logs and operational checks

Apache access logs show requests and response status codes. Error logs show configuration failures, certificate-file problems, permission errors, and request-processing issues. Follow the logs while making a test request:

sudo tail -f /var/log/apache2/access.log /var/log/apache2/error.log

A dedicated virtual host may write to separate files such as /var/log/apache2/example.com-ssl-access.log and /var/log/apache2/example.com-ssl-error.log. Also check service status and listening sockets when a site cannot be reached:

sudo systemctl status apache2
sudo ss -ltnp | grep ':443'

Troubleshooting HTTPS

Apache will not restart

  • Run sudo apache2ctl configtest and correct the reported syntax error.
  • Confirm that the certificate and key paths exist and are spelled correctly.
  • Check that Apache can read the private key without making the key publicly readable.
  • Verify that mod_ssl is enabled.
  • Review sudo systemctl status apache2 and the Apache error log.

The browser says the certificate is not trusted

  • The packaged self-signed test certificate is probably still configured.
  • The certificate chain may be incomplete.
  • The issuing CA may not be trusted by the client.
  • Inspect the certificate with openssl s_client, then replace testing credentials with a trusted CA-issued certificate for public use.

The hostname does not match

  • Check that the requested hostname appears in the certificate's subject alternative names.
  • Check ServerName and ServerAlias.
  • Check that the correct SNI hostname is supplied when using OpenSSL.
  • Review enabled port-443 virtual hosts if Apache is selecting the wrong certificate.

HTTPS is refused or times out

  • Confirm Apache is active.
  • Confirm an enabled virtual host listens on *:443.
  • Confirm TCP 443 is allowed by local and upstream firewall rules, cloud security groups, routers, and load balancers.

HTTPS serves the wrong site

  • Review all enabled configurations in /etc/apache2/sites-enabled/.
  • Look for overlapping ServerName or ServerAlias values.
  • Ensure the requested hostname matches the intended virtual host.
  • If no hostname matches, Apache may serve the default HTTPS virtual host.

HTTP works but HTTPS returns 403 or 404

  • Compare the HTTP and HTTPS DocumentRoot values.
  • Confirm that the expected files exist in the HTTPS document root.
  • Review directory access rules and filesystem permissions.
  • Inspect the HTTPS access and error logs for the request.

Security and maintenance checklist

  • Use a trusted CA-issued certificate for Internet-facing services.
  • Keep private-key files secret and restrict their ownership and permissions.
  • Allow inbound TCP 443 only where required by the network design.
  • Track certificate expiration dates and plan renewal before expiration.
  • Reload Apache after renewal when the service must reread the certificate files.
  • Validate configuration with apache2ctl configtest before every reload or restart.
  • Enable an HTTP-to-HTTPS redirect only after confirming the HTTPS site works.
  • Do not present certificate warnings as normal for public users.

For this topic, continue with Apache SSL/TLS configuration when reviewing the complete workflow.