MYOWNCA / DOCUMENTATION

Apache: HTTPS & client certificates

Use certificates issued by myOwnCA to secure a service with Apache. Start with HTTPS, then add client-certificate authentication when you need it.

Before you start

Configuration checked with Apache 2.4.68, using TLS 1.2 and TLS 1.3. The checks use disposable test certificates; adapt and verify the example in your own environment.

This guide configures an example website served by Apache, using your private CA. It assumes a running myOwnCA installation, an active issuer, OpenSSL, and a Linux host with Apache 2.4 with mod_ssl. Commands use Debian/Ubuntu-style service names; adjust paths for your distribution.

  • Choose service.home.arpa for this example and resolve it to your server using local DNS or a hosts entry.
  • Use a TLS server template that permits this DNS SAN and the serverAuth extended key usage. Obtain the required Certificate Operator approvals.
  • Keep the CA root private key offline. Only certificates and the service’s own private key belong on the web host.
  • The example uses an unencrypted service key for unattended startup, protected by restrictive filesystem permissions.

New to private trust? Follow the homelab guide first. These examples require one issuing CA between the root and the leaf.

1. Generate a key and submit a CSR

Run on the web-service host
umask 077
openssl req -new -newkey rsa:3072 -nodes \
  -keyout service.key -out service.csr \
  -subj '/CN=service.home.arpa' \
  -addext 'subjectAltName=DNS:service.home.arpa'

Submit service.csr in myOwnCA using the TLS server template and the appropriate holder. Confirm the requested SAN survives template validation. After approval and issuance, export the leaf as service.crt, the issuing CA as issuer.crt, and the root as root.crt. Keep service.key on this host.

Verify the issued certificate and install service files
# Run in the directory holding your exported PEM certificates.
# service.crt: issued leaf; issuer.crt: issuing CA; root.crt: root CA.
openssl verify -CAfile root.crt -untrusted issuer.crt service.crt
cat service.crt issuer.crt > service-fullchain.pem
cat issuer.crt root.crt > client-ca.pem
sudo install -d -m 0755 /etc/myownca-example/tls /var/www/myownca-example
sudo install -m 0600 service.key /etc/myownca-example/tls/service.key
sudo install -m 0644 service-fullchain.pem client-ca.pem /etc/myownca-example/tls/
printf '%s\n' 'Private HTTPS is working.' | sudo tee /var/www/myownca-example/index.html

The served full chain contains the leaf first, then the issuer. The root is distributed as a trust anchor separately. Verify its fingerprint through a trusted channel before installing it on clients.

2. Configure HTTPS

Save the following as /etc/apache2/sites-available/myownca-example.conf. Replace the hostname consistently if you use another name. Enable one example virtual host at a time; the mTLS configuration below replaces this one.

Apache HTTPS virtual host
# Private HTTPS
# Enable mod_ssl, mod_authz_core, mod_authz_host, and mod_dir first.
# Configure Listen 443 once in the main server configuration.
<VirtualHost *:443>
    ServerName service.home.arpa
    DocumentRoot /var/www/myownca-example
    DirectoryIndex index.html

    SSLEngine on
    SSLCertificateFile /etc/myownca-example/tls/service-fullchain.pem
    SSLCertificateKeyFile /etc/myownca-example/tls/service.key
    SSLProtocol -all +TLSv1.2 +TLSv1.3

    <Directory /var/www/myownca-example>
        Options -Indexes
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

Download the HTTPS configuration

On Debian/Ubuntu, enable the SSL module and site. The distribution’s ports.conf supplies Listen 443 when SSL is enabled; do not add a duplicate listener.

Enable Apache SSL and the example site
sudo a2enmod ssl
sudo a2ensite myownca-example
Check configuration before reloading
sudo apachectl configtest && sudo systemctl reload apache2
Verify server trust and hostname from a client
# Run on a client. Replace 192.0.2.10 with your service's address.
curl --cacert root.crt \
  --resolve service.home.arpa:443:192.0.2.10 \
  https://service.home.arpa/

Expect Private HTTPS is working. without disabling certificate verification. Browser access additionally requires installing your root into the browser or operating system trust store. If Apache cannot read the private key, use the account and access policy required by your installation; do not make the key world-readable.

3. Optionally require client certificates

Generate a separate client key and CSR on the client machine. Request a certificate using a template with the clientAuth extended key usage, then export it as client.crt.

Create a client identity
umask 077
openssl req -new -newkey rsa:3072 -nodes \
  -keyout client.key -out client.csr \
  -subj '/CN=homelab-client'

The client-ca.pem file created earlier contains the issuer and root certificates. Prepare current CRLs from both CAs before enabling the configuration below. Obtain the issuer CRL from myOwnCA’s configured publication endpoint; obtain the root CRL through your offline-root process. Convert DER CRLs to PEM with openssl crl -inform DER -in input.crl -out output.crl.pem if needed.

Install current revocation lists
# Export fresh PEM CRLs for BOTH the issuing CA and root CA.
# issuer.crl.pem covers client certificates; root.crl.pem covers the issuer.
openssl crl -in issuer.crl.pem -noout -issuer -lastupdate -nextupdate
openssl crl -in root.crl.pem -noout -issuer -lastupdate -nextupdate
cat issuer.crl.pem root.crl.pem > client-crls.pem
sudo install -m 0644 client-crls.pem /etc/myownca-example/tls/client-crls.pem
Apache mutual TLS virtual host
# HTTPS with required client certificates and CRL checking
# Enable mod_ssl, mod_authz_core, mod_authz_host, and mod_dir first.
# Configure Listen 443 once in the main server configuration.
<VirtualHost *:443>
    ServerName service.home.arpa
    DocumentRoot /var/www/myownca-example
    DirectoryIndex index.html

    SSLEngine on
    SSLCertificateFile /etc/myownca-example/tls/service-fullchain.pem
    SSLCertificateKeyFile /etc/myownca-example/tls/service.key
    SSLProtocol -all +TLSv1.2 +TLSv1.3

    SSLCACertificateFile /etc/myownca-example/tls/client-ca.pem
    SSLVerifyClient require
    SSLVerifyDepth 2
    SSLCARevocationFile /etc/myownca-example/tls/client-crls.pem
    SSLCARevocationCheck chain
    SSLSessionTickets off

    <Directory /var/www/myownca-example>
        Options -Indexes
        AllowOverride None
        Require all granted
    </Directory>
</VirtualHost>

Download the mTLS configuration. Replace the HTTPS virtual host and check/reload with the same command as above. For this CRL-based example, set SSLSessionCache none in the main server configuration to avoid session resumption bypassing a fresh certificate check.

Connect using the issued client certificate
cat client.crt issuer.crt > client-fullchain.pem
curl --cacert root.crt --cert client-fullchain.pem --key client.key \
  --resolve service.home.arpa:443:192.0.2.10 \
  https://service.home.arpa/

Authentication scope: this example admits any valid client certificate with an acceptable purpose and chain to the configured CA. Use a dedicated client-issuing hierarchy or additional application authorization when access must be limited to particular users. TLS client authentication alone does not assign application roles.

Repeat the HTTPS-only curl command: without a client certificate, it must no longer return the protected page. Certificates from another CA, expired certificates, and certificates on the loaded CRL must also be rejected.

4. Maintain certificates and CRLs

  • Use myOwnCA’s Renew action for the existing identity before expiry, with the template-required approvals. Review the new validity, SAN, and chain.
  • Install the renewed leaf and issuer bundle on the web host. If you rotate the key, install the matching new key as part of the same change. Check configuration and reload.
  • For a revoked client, generate/export the updated issuing CRL, refresh client-crls.pem, and reload. The server reads a local CRL file; it does not automatically download updates from certificate URLs.
  • Refresh both issuer and root CRLs before their nextUpdate time. Missing or expired CRLs can deny otherwise valid clients. Monitor refresh failures.
  • These examples disable TLS session reuse for mTLS. Existing connections still need to close; a graceful reload alone does not immediately terminate all authenticated sessions.

Certificate renewal in myOwnCA does not automatically install the replacement on this service. Treat delivery, installation, reload, and verification as explicit operational steps.

Check the failing boundary

  • Unknown issuer: confirm client root trust and that the server sends the issuing certificate.
  • Hostname mismatch: the requested DNS name must appear in the leaf SAN.
  • Client rejected: verify clientAuth usage, dates, the issuer chain, and current CRLs for both levels.
  • Configuration test fails: check module availability, duplicate virtual hosts/listeners, paths, and key access before reloading.

Directive reference: Apache mod_ssl.

Planning a deployment?

Talk to EnigmaIS