Unlock secure web communication on your Rocky Linux 10 server without the cost of a commercial certificate. This comprehensive guide shows you how to implement a self-signed SSL certificate with proper Subject Alternative Names (SAN) for Apache, preventing common browser errors like ERR_CERT_COMMON_NAME_INVALID. Ideal for staging, internal applications, or development labs, you’ll learn to configure robust HTTPS, integrate a crucial HTTP to HTTPS redirect, and leverage Rocky Linux’s built-in crypto policies. Dive in to master your Rocky Linux SSL setup and enhance your Apache HTTPS configuration with confidence.
Modern web browsers demand robust security, and older methods of creating self-signed certificates often fall short by omitting Subject Alternative Names (SAN). Without SAN support, visitors encounter errors like ERR_CERT_COMMON_NAME_INVALID, even if the Common Name appears correct. This guide will walk you through creating a proper self-signed certificate using a san.cnf configuration file with crucial SAN entries. You’ll then configure a complete Apache SSL VirtualHost for store.linuxapp.com and apply recommended TLS security settings. This procedure is also fully compatible with RHEL 10 and AlmaLinux 10 systems.
Prerequisites for Your Rocky Linux SSL Setup
Before proceeding with your Rocky Linux SSL setup, ensure you have the following:
- Rocky Linux 10 installed with a non-root sudo user.
- A domain name pointed to your server’s IP address (this guide uses
store.linuxapp.comas the example). - Ports 80 and 443 are accessible, or you have the ability to modify firewall rules.
If you need a Linux server to follow along, DigitalOcean offers reliable cloud VPS plans starting at $4/month. You also get $200 in free credits to spin up your first server and try it yourself, available for TecMint members. We may earn a commission at no extra cost to you.
TecMint Weekly Newsletter
Get the Learn Linux 7 Days Crash Course free when you join 34,000+ Linux professionals reading every Thursday.
Check your email for a magic link to get started.
Something went wrong. Please try again.
Step 1: Install Apache and Enable SSL/TLS Support
Rocky Linux 10 comes with OpenSSL pre-installed. However, to enable Apache HTTPS configuration, you’ll need Apache (httpd) and the mod_ssl package, which integrates SSL/TLS capabilities into your web server.
sudo dnf install httpd mod_ssl -yUpon installation, mod_ssl automatically creates a default SSL configuration file at:
/etc/httpd/conf.d/ssl.confNext, start the Apache service and configure it to launch automatically at boot time:
sudo systemctl start httpd
sudo systemctl enable --now httpdVerify that Apache is running as expected:
sudo systemctl status httpdStep 2: Configure FirewallD for Web Traffic (HTTP & HTTPS)
Rocky Linux utilizes Firewalld for managing network traffic. By default, only explicitly allowed services and ports can communicate with your server. For Apache to serve both regular web traffic on port 80 (HTTP) and encrypted traffic on port 443 (HTTPS), both ports must be opened. Otherwise, your website will be unreachable.
Execute the following commands to open these essential ports:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reloadTo confirm that both services are now allowed through the firewall, run:
sudo firewall-cmd --list-servicesYou can also verify that Apache is listening on both web ports:
sudo ss -tlnp | grep httpdWith the firewall configured, the next crucial step is to create a robust self-signed certificate SAN-enabled SSL certificate.
Step 3: Craft Your OpenSSL Configuration with Subject Alternative Names (SAN)
A Subject Alternative Name (SAN) is vital for modern browsers, as it specifies the hostnames and IP addresses a certificate is valid for. Browsers no longer rely solely on the Common Name (CN) for certificate verification. Without a SAN entry, browsers like Chrome, Firefox, and Edge will reject your certificate with errors such as:
ERR_CERT_COMMON_NAME_INVALIDFirst, create a dedicated directory to store your certificate, private key, and configuration file:
sudo mkdir -p /etc/ssl/store.linuxapp.comNext, create the OpenSSL configuration file:
sudo vi /etc/ssl/store.linuxapp.com/san.cnfAdd the following content to the file:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = v3_req
[dn]
C = IN
ST = Maharashtra
L = Mumbai
O = LinuxApp
OU = IT
CN = store.linuxapp.com
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = store.linuxapp.com
DNS.2 = www.store.linuxapp.comLet’s break down the key sections:
[dn]: Contains the certificate identity information, withCN(Common Name) specifying the primary hostname.[v3_req]: Enables certificate extensions, withsubjectAltNameinstructing OpenSSL to use the entries defined in[alt_names].[alt_names]: Defines the hostnames that browsers will trust for this certificate. In this example,store.linuxapp.comis the main website, andwww.store.linuxapp.comcovers itswwwvariant.
Remember to replace all occurrences of store.linuxapp.com with your actual domain name. You can also extend the [alt_names] section to include additional domains or subdomains:
[alt_names]
DNS.1 = store.linuxapp.com
DNS.2 = www.store.linuxapp.com
DNS.3 = api.store.linuxapp.com
DNS.4 = admin.store.linuxapp.comFor internal applications accessed by IP address, you can also include IP-based SAN entries:
[alt_names]
DNS.1 = store.linuxapp.com
IP.1 = 192.168.1.100Save the file and exit the editor once you’ve finished customizing it.
Step 4: Generate Your Self-Signed SSL Certificate and Private Key
With the san.cnf file prepared, you can now generate both the private key and the self-signed certificate SAN-enabled certificate with a single OpenSSL command.
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/ssl/store.linuxapp.com/apache.key \
-out /etc/ssl/store.linuxapp.com/apache.crt \
-config /etc/ssl/store.linuxapp.com/san.cnfOpenSSL will display progress indicators as it generates the RSA key. After the command completes, you will have two new files:
apache.key– Your private key.apache.crt– Your self-signed SSL certificate.
It’s critical to secure your private key, as its compromise would allow unauthorized impersonation of your website. Set appropriate permissions:
sudo chmod 600 /etc/ssl/store.linuxapp.com/apache.key
sudo chmod 644 /etc/ssl/store.linuxapp.com/apache.crtVerify that both files exist with the correct permissions:
ls -l /etc/ssl/store.linuxapp.com/Output will resemble:
total 12
-rw-r--r--. 1 root root 1371 Jun 1 11:24 apache.crt
-rw-------. 1 root root 1704 Jun 1 11:24 apache.key
-rw-r--r--. 1 root root 334 Jun 1 11:24 san.cnfFinally, confirm that the SAN entries were correctly embedded into your certificate:
openssl x509 -in /etc/ssl/store.linuxapp.com/apache.crt -text -noout | grep -A2 "Subject Alternative"If your hostnames are listed under “Subject Alternative Name,” your certificate was generated correctly. If this section is missing or empty, browsers will reject the certificate due to hostname validation errors, even if the Common Name appears to match.
Step 5: Configure Your Apache SSL VirtualHost for Secure Connections
While mod_ssl installs a default ssl.conf, it’s best practice to create a dedicated VirtualHost file for each website. This keeps your Apache HTTPS configuration organized and simplifies managing multiple sites on a single server.
Before configuring Apache, create a basic test website in your DocumentRoot directory:
sudo mkdir -p /var/www/store.linuxapp.com
echo "<html><body><h1>Welcome to LinuxApp Secure!</h1></body></html>" | sudo tee /var/www/store.linuxapp.com/index.htmlNow, create your dedicated Apache configuration file for SSL:
sudo vi /etc/httpd/conf.d/store.linuxapp.com-ssl.confAdd the following configuration to the file:
<VirtualHost *:443>
ServerName store.linuxapp.com
ServerAlias www.store.linuxapp.com
DocumentRoot /var/www/store.linuxapp.com
SSLEngine on
SSLCertificateFile /etc/ssl/store.linuxapp.com/apache.crt
SSLCertificateKeyFile /etc/ssl/store.linuxapp.com/apache.key
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLHonorCipherOrder on
SSLSessionTickets off
<Directory /var/www/store.linuxapp.com>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/store.linuxapp.com-ssl-error.log
CustomLog /var/log/httpd/store.linuxapp.com-ssl-access.log combined
</VirtualHost>Save the file and exit. Apache now knows the location of your website files and which SSL certificate to use.
Step 6: Implement Automatic HTTP to HTTPS Redirection
Apache is now configured for HTTPS on port 443. However, users might still try to access your site via an http:// URL or by simply typing the domain name. To ensure all traffic is encrypted, create a second VirtualHost that listens on port 80 and automatically redirects visitors to HTTPS.
Create a new configuration file for the HTTP VirtualHost:
sudo vi /etc/httpd/conf.d/store.linuxapp.com.confAdd the following configuration:
<VirtualHost *:80>
ServerName store.linuxapp.com
ServerAlias www.store.linuxapp.com
Redirect permanent / https://store.linuxapp.com/
</VirtualHost>Before reloading Apache, always verify your configuration for syntax errors:
sudo apachectl configtestIf Apache detects an issue, it will display the configuration file and line number. Correct any reported errors and re-run configtest until you see Syntax OK. Once validated, reload Apache to apply changes without interrupting existing connections:
sudo systemctl reload httpdConfirm Apache is listening on both HTTP and HTTPS ports:
sudo ss -tlnp | grep httpdExample output:
LISTEN 0 511 *:443 *:* users:(("httpd",pid=6076,fd=6)
LISTEN 0 511 *:80 *:* users:(("httpd",pid=6076,fd=4)Seeing entries for both 80 and 443 means Apache is ready to serve HTTP requests and redirect them securely to HTTPS.
Step 7: Verify Your HTTPS Setup and Redirects
With Apache reloaded and the SSL VirtualHost active, it’s time to confirm your HTTPS setup is functioning correctly.
Add a Temporary Hosts Entry (Optional)
If your domain’s DNS isn’t yet pointing to your server, add a temporary entry to your local machine’s hosts file. Replace 192.168.1.10 with your server’s actual IP address. This allows your system to resolve the hostname locally:
echo "192.168.1.10 store.linuxapp.com www.store.linuxapp.com" | sudo tee -a /etc/hostsVerify hostname resolution:
getent hosts store.linuxapp.comExample output:
192.168.1.10 store.linuxapp.comTest the HTTPS Connection
Use curl to test the HTTPS connection. Since the certificate is self-signed, curl won’t trust it by default, so use the -k option to bypass certificate validation:
curl -kv https://store.linuxapp.com 2>&1 | grep -E "SSL|subject|issuer|Connected"Example output will include lines like:
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / RSASSA-PSS
* subject: C=IN; ST=Maharashtra; L=Mumbai; O=LinuxApp; OU=IT; CN=store.linuxapp.com
* issuer: C=IN; ST=Maharashtra; L=Mumbai; O=LinuxApp; OU=IT; CN=store.linuxapp.com
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
* Connected to store.linuxapp.com (192.168.122.247) port 443
Server: Apache/2.4.63 (Rocky Linux) OpenSSL/3.5.1Verify the HTTP Redirect
Next, confirm that all HTTP traffic is correctly redirected to HTTPS:
curl -I http://store.linuxapp.comExample output:
HTTP/1.1 301 Moved Permanently
Date: Mon, 01 Jun 2026 06:20:10 GMT
Server: Apache/2.4.63 (Rocky Linux) OpenSSL/3.5.1
Location: https://store.linuxapp.com/
Content-Type: text/html; charset=iso-8859-1This confirms that unencrypted HTTP requests are automatically redirected to the secure HTTPS version of your site.
Test in a Web Browser
Open https://store.linuxapp.com in your web browser. You will observe a certificate warning, which is expected since no publicly recognized CA has signed this certificate. Click “Advanced” and proceed to confirm that the page loads and the connection is encrypted.
Pro Tip for Internal Use: For internal applications where a self-signed certificate is intentionally used, you can often import your apache.crt into the trusted root certificate store of your organization’s devices or browser settings. This allows users within your network to access the HTTPS site without persistent browser warnings, creating a smoother experience for internal tools or development environments.
Understanding Rocky Linux Crypto Policies for Enhanced Security
One significant advantage of Rocky Linux 10 is its inheritance of RHEL 10’s system-wide cryptographic policy framework. This framework provides secure defaults for TLS-enabled applications like Apache, Nginx, OpenSSH, and others, significantly simplifying your Linux server security efforts.
The default policy, aptly named DEFAULT, automatically disables outdated protocols and enforces modern cryptographic standards across the operating system. You can inspect the currently active policy with:
sudo update-crypto-policies --showWith the DEFAULT policy active, Rocky Linux 10 enforces a minimum of TLS 1.2 and uses strong cipher suites by default. This means you don’t need to manually maintain complex SSLCipherSuite strings in your Apache configuration to achieve a secure baseline. This is why the VirtualHost configuration in this guide only specifies:
SSLProtocol -all +TLSv1.2 +TLSv1.3The operating system manages the lower-level cryptographic details, resulting in simpler and more consistent SSL/TLS configuration.
Conclusion: Mastering Self-Signed Certificates on Rocky Linux
In this guide, you successfully installed Apache with SSL support, opened essential firewall ports, generated a self-signed certificate SAN-enabled certificate, configured a dedicated HTTPS VirtualHost, and implemented an HTTP to HTTPS redirect. The critical SAN verification step ensures modern browsers correctly validate your certificate, avoiding common errors that plague older tutorials.
For internal services, development environments, and lab systems, a self-signed certificate offers a straightforward way to enable encrypted HTTPS connections without relying on an external Certificate Authority. When you’re ready to deploy a public-facing site, you can seamlessly switch to a trusted certificate from Let’s Encrypt while maintaining the same robust Apache VirtualHost structure you’ve already established.
TecMint Weekly Newsletter
Get the Learn Linux 7 Days Crash Course free when you join 34,000+ Linux professionals reading every Thursday.
Check your email for a magic link to get started.
Something went wrong. Please try again.
FAQ
Question 1: Why do browsers display security warnings for self-signed SSL certificates?
Answer 1: Browsers warn users because self-signed certificates are not issued by a publicly trusted Certificate Authority (CA). Since the certificate’s authenticity cannot be verified by a third party, browsers flag it as potentially insecure. This is expected behavior for internal or development use cases where you generate your own trust.
Question 2: Is it safe to use a self-signed certificate for production websites?
Answer 2: Generally, no. Self-signed certificates are unsuitable for public-facing production websites because browsers will consistently issue security warnings, deterring visitors and potentially blocking access. For production, always use a certificate from a trusted CA, such as a free one from Let’s Encrypt or a commercial certificate.
Question 3: How long should I set the validity period (days) for a self-signed certificate?
Answer 3: For self-signed certificates, a validity period of 365 days (one year) or even slightly longer (e.g., 730 days for two years) is common. Unlike publicly trusted certificates, which often have shorter lifespans (e.g., 90 days for Let’s Encrypt), the renewal process for a self-signed certificate is a manual overwrite, so a longer period reduces maintenance frequency. However, avoid excessively long periods (e.g., 10+ years) as it can pose security risks if the private key is ever compromised.

