SAN Certificates on Ubuntu

Self-Signed SSL/TLS with Subject Alternative Names for Local Networks

What You'll Learn

This guide covers creating self-signed SSL certificates with Subject Alternative Names (SAN) for secure HTTPS communication on your local network. Perfect for homelab environments, development servers, and internal infrastructure.

Server
Generate Certificate
→
Apache
Configure SSL
→
Client
Trust Certificate
Use Case: When you need HTTPS on your local network (e.g., cerberus-ai.local) without certificate warnings.
1

Generate SSL Certificate on Server

1.1 Create Certificate Directory

sudo mkdir -p /etc/ssl/cerberus cd /etc/ssl/cerberus

1.2 Create OpenSSL Configuration with SAN

Create a configuration file that includes Subject Alternative Names:

sudo tee openssl.cnf > /dev/null <
Customize: Replace cerberus-ai.local with your hostname and 192.168.1.32 with your server's IP.

1.3 Generate Private Key and Certificate

# Generate private key sudo openssl genrsa -out cerberus-ai.local.key 2048 # Generate certificate (valid for 10 years) sudo openssl req -new -x509 -days 3650 \ -key cerberus-ai.local.key \ -out cerberus-ai.local.crt \ -config openssl.cnf \ -extensions v3_req

1.4 Verify Certificate

# Check certificate details sudo openssl x509 -in cerberus-ai.local.crt -noout -text # Verify SAN entries sudo openssl x509 -in cerberus-ai.local.crt -noout -text | grep -A 1 "Subject Alternative Name"
You should see your DNS names and IP addresses listed under Subject Alternative Name.

1.5 Set Proper Permissions

sudo chmod 600 cerberus-ai.local.key sudo chmod 644 cerberus-ai.local.crt
2

Configure Apache for SSL

2.1 Enable SSL Module

sudo a2enmod ssl sudo a2enmod headers

2.2 Edit SSL Virtual Host Configuration

sudo nano /etc/apache2/sites-available/default-ssl.conf

Add/modify these lines inside the <VirtualHost *:443> section:

ServerName cerberus-ai.local DocumentRoot /var/www/html SSLCertificateFile /etc/ssl/cerberus/cerberus-ai.local.crt SSLCertificateKeyFile /etc/ssl/cerberus/cerberus-ai.local.key
Important: These lines should replace the default snakeoil certificate paths.

2.3 Complete Configuration Example

<IfModule mod_ssl.c> <VirtualHost _default_:443> ServerAdmin webmaster@localhost ServerName cerberus-ai.local DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/cerberus/cerberus-ai.local.crt SSLCertificateKeyFile /etc/ssl/cerberus/cerberus-ai.local.key <Directory /var/www/html> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </IfModule>

2.4 Enable SSL Site and Restart Apache

# Enable the SSL site sudo a2ensite default-ssl # Test configuration sudo apache2ctl configtest # Restart Apache sudo systemctl restart apache2 # Verify Apache is running sudo systemctl status apache2
Apache should restart without errors. If you see "Syntax OK", you're good to go!
3

Install Certificate on Ubuntu Client

3.1 Copy Certificate from Server

On your client machine, copy the certificate:

# Copy certificate to your home directory scp [email protected]:/etc/ssl/cerberus/cerberus-ai.local.crt ~/ # Or if using hostname: scp [email protected]:/etc/ssl/cerberus/cerberus-ai.local.crt ~/

3.2 Install to System Trust Store

# Copy to system certificates directory sudo cp ~/cerberus-ai.local.crt /usr/local/share/ca-certificates/ # Update certificate store sudo update-ca-certificates
You should see output like:
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

3.3 Verify Installation

# Test with curl (should work without warnings) curl https://cerberus-ai.local # Test with wget wget https://cerberus-ai.local -O -
What's Trusted: The certificate is now trusted by:
  • curl
  • wget
  • Python requests library
  • Chrome/Chromium
  • Most command-line tools
4

Browser-Specific Configuration

4.1 Firefox (Uses Own Certificate Store)

Firefox doesn't use the system certificate store, so you need to import manually:

  • Open Firefox
  • Go to Settings → Privacy & Security
  • Scroll to Certificates → Click View Certificates
  • Go to Authorities tab
  • Click Import
  • Select ~/cerberus-ai.local.crt
  • Check "Trust this CA to identify websites"
  • Click OK

4.2 Chrome/Chromium

Chrome uses the system certificate store on Linux, so it should work automatically after step 3.2.

If you still see warnings, try:
  • Restart Chrome completely
  • Clear Chrome's SSL state: chrome://settings/security → Clear browsing data → Cached images and files

4.3 Testing Browser Access

# Visit in your browser: https://cerberus-ai.local # You should see: ✓ Secure padlock icon ✓ No certificate warnings ✓ Certificate issued to "cerberus-ai.local"
5

Optional: HTTP to HTTPS Redirect

5.1 Enable Rewrite Module

sudo a2enmod rewrite

5.2 Configure Redirect

Edit your default site configuration:

sudo nano /etc/apache2/sites-available/000-default.conf

Add inside the <VirtualHost *:80> section:

ServerName cerberus-ai.local RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]

5.3 Restart Apache

sudo systemctl restart apache2
Now visiting http://cerberus-ai.local will automatically redirect to https://cerberus-ai.local
6

Troubleshooting

6.1 Certificate Not Trusted

# Verify certificate is in system store ls -la /usr/local/share/ca-certificates/ # Re-run update sudo update-ca-certificates --fresh # Check if certificate is in trusted store ls -la /etc/ssl/certs/ | grep cerberus

6.2 Apache Won't Start

# Check Apache error logs sudo tail -50 /var/log/apache2/error.log # Test configuration sudo apache2ctl configtest # Verify certificate files exist and have correct permissions ls -la /etc/ssl/cerberus/

6.3 Browser Still Shows Warning

  • Clear browser cache and SSL state
  • Completely close and restart browser
  • Check certificate expiry: sudo openssl x509 -in /etc/ssl/cerberus/cerberus-ai.local.crt -noout -dates
  • Verify SAN includes the hostname you're accessing

6.4 Connection Refused

# Check if Apache is listening on port 443 sudo netstat -tlnp | grep :443 # Check firewall sudo ufw status # If firewall is blocking, allow HTTPS sudo ufw allow 443/tcp

🎉 Congratulations! SSL/TLS is Now Configured

What you've achieved:

  • Self-signed SSL certificate with SAN support
  • Secure HTTPS access on your local network
  • No browser certificate warnings
  • Support for multiple hostnames and IP addresses
  • System-wide trust configuration
💡

Advanced Tips

Adding More Devices to Trust Store

To add the certificate to other Ubuntu machines on your network:

# From the new client: scp [email protected]:/etc/ssl/cerberus/cerberus-ai.local.crt ~/ sudo cp ~/cerberus-ai.local.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates

Certificate Renewal

Self-signed certificates last 10 years (3650 days). When it expires:

# Check expiry date sudo openssl x509 -in /etc/ssl/cerberus/cerberus-ai.local.crt -noout -dates # Regenerate when needed (repeat Step 1.3)

Using Custom CA for Multiple Servers

For advanced setups with multiple servers, create your own Certificate Authority:

  • Generate a CA certificate once
  • Sign individual server certificates with your CA
  • Install only the CA certificate on clients
  • All servers signed by your CA will be trusted

Security Best Practices

  • Keep private keys secure: Never share .key files
  • Use strong key sizes: 2048 bits minimum (4096 for higher security)
  • Restrict key permissions: chmod 600 on private keys
  • Regular rotation: Consider rotating certificates annually
  • Monitor expiry: Set reminders before certificates expire
Important Note: Self-signed certificates are perfect for local networks and development environments. For production internet-facing sites, use certificates from a trusted Certificate Authority like Let's Encrypt.
Security Reminder: These certificates should only be used on trusted local networks. Never expose services using self-signed certificates directly to the internet without additional security measures.
← Back to Operations Center