How to Create a Self-Signed SSL Certificate with SAN for Apache on Ubuntu
Securing your web applications with SSL certificates is crucial for ensuring the confidentiality and integrity of data transmitted between the client and server. In this tutorial, we’ll walk through the process of generating a self-signed SSL certificate with a Subject Alternative Name (SAN) for an Apache web server on Ubuntu.
Prerequisites
Before you begin, make sure you have the following:
- Ubuntu server with Apache installed
openssl
tool installed
At the beginning, Go to your frontend folder
Step 1: Create Directory
Create a directory for certificates
mkdir certificates
cd certificates
Step 2: Generate a Private Key
openssl genpkey -algorithm RSA -out private.key
genpkey
: This sub-command is used for generating private keys.-algorithm RSA
: Specifies the algorithm to be used for key generation. In this case, RSA (Rivest–Shamir–Adleman), a widely used asymmetric cryptographic algorithm.-out private.key
: Specifies the output file for the generated private key. In this example, the private key will be saved in a file namedprivate.key
.
[Not Recommended] If you want your private.key remains password protected, then -
openssl genpkey -algorithm RSA -aes256 -out private.key
-aes256
:
- Indicates the encryption algorithm to be used for the private key. In this case, it’s AES (Advanced Encryption Standard) with a key length of 256 bits. This parameter ensures that the private key is encrypted using AES-256 for added security. The user will be prompted to enter a passphrase during the key generation process, and this passphrase is used to encrypt the private key.
You’ll be prompted to enter a passphrase; remember this passphrase as you’ll need it later.
Step 3: Create a SAN Configuration File
Create a file named san.conf
with the following content:
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[req_distinguished_name]
CN = localhost
C = BD
ST = Dhaka
L = Motijheel
O = Robist
OU = Developers
emailAddress = smazoomder@gmail.com
[req_ext]
subjectAltName = IP:192.168.0.88
(In Ip place your IP)
[req]
: This section specifies the attributes for the certificate request.distinguished_name = req_distinguished_name
: Refers to the distinguished name section, where you define various details about the entity requesting the certificate.req_extensions = req_ext
: Points to the extensions section, which allows you to include additional information in the certificate.prompt = no
: Disables prompting for certificate details during the certificate creation process.[req_distinguished_name]
: Defines various distinguished name attributes, such as Common Name (CN), Country (C), State (ST), Locality (L), Organization (O), Organizational Unit (OU), and Email Address.CN = localhost
: Specifies the Common Name (CN), typically the domain name associated with the certificate.C = BD
: Country attribute, indicating the country (Bangladesh in this case).ST = Dhaka
: State attribute, specifying the state or region (Dhaka in this case).L = Motijheel
: Locality attribute, indicating the locality or city (Motijheel in this case).O = Robist
: Organization attribute, denoting the organization name (Robist in this case).OU = Developers
: Organizational Unit attribute, representing the organizational unit or department (Developers in this case).emailAddress = smazoomder@gmail.com
: Email address associated with the certificate.[req_ext]
: Extensions section, allowing for the inclusion of additional extensions in the certificate.subjectAltName = IP:192.168.0.88
: Specifies the Subject Alternative Name (SAN) extension, including an IP address (192.168.0.88) as an alternative identifier for the entity associated with the certificate.
Breakdown of Subject Alternative Name (SAN) :
- Subject: In the context of SSL/TLS certificates, the “subject” typically refers to the entity (such as a website or server) for which the certificate is issued. It often includes information like the Common Name (CN), organization, and location.
- Alternative Name: The “Alternative Name” refers to additional identifiers that can be included in the SSL/TLS certificate. These identifiers go beyond the Common Name (CN) and provide flexibility in specifying other valid names for the certificate.
Why SAN is Needed:
- Support for Multiple Identifiers: SAN allows a single SSL/TLS certificate to be valid for multiple identifiers. Traditionally, SSL certificates were issued based on the Common Name (CN) field, which represented the main domain. However, with the growing need for flexibility, SAN enables the inclusion of additional names.
- Multi-Domain Certificates: SAN is particularly useful in scenarios where a single certificate needs to cover multiple domains or subdomains. Instead of obtaining separate certificates for each domain, a multi-domain certificate with SAN extension can include all the necessary identifiers.
- IP Addresses and Email Addresses: SAN is not limited to domain names; it can also include IP addresses and email addresses as alternative identifiers. This is valuable in situations where certificates need to cover services accessed via IP addresses or email communication.
- Wildcard Certificates: SAN is commonly used in conjunction with wildcard certificates. A wildcard certificate covers a domain and its subdomains, and SAN can further extend its coverage to additional domains.
- Avoidance of Certificate Mismatch Issues: Including SAN helps prevent issues related to certificate mismatches. When a user accesses a service through an alternative name, the presence of SAN ensures that the certificate is still considered valid.
In summary, Subject Alternative Name (SAN) is an extension to SSL/TLS certificates that allows for the inclusion of multiple identifiers, providing flexibility and broader coverage for various naming scenarios in secure communications.
Step 4: Generate a Certificate Signing Request (CSR)
openssl req -new -key private.key -out certificate.csr -config san.conf
openssl req
:
- This is the OpenSSL command used for creating and processing certificate requests.
-new
:
- Indicates that a new CSR (Certificate Signing Request) is being generated.
-key private.key
:
- Specifies the private key file to be used for generating the CSR. The private key generated in the previous step (
private.key
) is used here.
-out certificate.csr
:
- Specifies the output file where the generated CSR will be saved. In this example, the CSR will be saved to a file named
certificate.csr
.
-config san.conf
:
- Specifies a configuration file (
san.conf
) that contains additional settings, including Subject Alternative Names (SANs) for the certificate.
Step 5: Generate a Self-Signed Certificate
openssl x509 -req -in certificate.csr -signkey private.key -out server.cert -days 365
openssl x509
:
- This is the OpenSSL command used for signing and displaying X.509 certificate files.
-req
:
- Indicates that the input file (
certificate.csr
) is a Certificate Signing Request (CSR).
-in certificate.csr
:
- Specifies the input file containing the Certificate Signing Request (CSR) that needs to be signed. In this example, the CSR file is
certificate.csr
.
-signkey private.key
:
- Specifies the private key (
private.key
) to be used for signing the CSR and generating the certificate.
-out server.cert
:
- Specifies the output file where the signed X.509 certificate will be saved. In this example, the certificate file is named
server.cert
.
-days 365
:
- Specifies the validity period of the certificate in days. In this case, the certificate will be valid for 365 days (1 year).
Breakdown of X.509 Ceritificate
An X.509 certificate is a digital certificate that follows the X.509 standard, which defines the format and structure for public-key certificates. These certificates are widely used in internet security protocols, including TLS/SSL for secure web communication. Here’s a breakdown of the X.509 certificate:
Key Components of an X.509 Certificate:
- Version: Indicates the version of the X.509 standard used in the certificate (e.g., version 1, 2, or 3).
- Serial Number: A unique identifier assigned by the certificate issuer (Certificate Authority) to differentiate certificates.
- Signature Algorithm: Specifies the cryptographic algorithm used by the Certificate Authority to sign the certificate.
- Issuer: Identifies the entity (usually a Certificate Authority) that issued the certificate.
- Validity Period: Defines the time period during which the certificate is considered valid. It includes a “Not Before” and “Not After” date.
- Subject: Identifies the entity (e.g., a person, organization, or device) associated with the public key in the certificate.
- Subject Public Key Info: Contains the public key and the algorithm used by the subject.
- Extensions: Additional information or attributes associated with the certificate. This may include Subject Alternative Names (SAN), key usage, and more.
- Certificate Signature Algorithm: Specifies the algorithm used by the Certificate Authority to sign the certificate.
- Certificate Signature Value: Contains the digital signature created by the Certificate Authority, ensuring the integrity and authenticity of the certificate.
Purpose of X.509 Certificates:
- Authentication: Verifies the identity of the certificate holder (subject).
- Encryption: Facilitates secure communication by providing a means to encrypt data using the public key.
- Digital Signatures: Allows for the creation and verification of digital signatures, ensuring data integrity.
- Key Exchange: Supports the exchange of cryptographic keys in secure communication protocols.
Usage in SSL/TLS:
- In the context of SSL/TLS protocols, X.509 certificates are essential for establishing secure connections between clients and servers. When a client connects to a secure website, the server presents its X.509 certificate, which the client verifies to ensure a secure and trusted connection.
- X.509 certificates may be self-signed for internal use or signed by a trusted Certificate Authority for public-facing websites.
Understanding X.509 certificates is crucial for anyone involved in web security, system administration, or software development.
Step 6: Update Apache Configuration
Update your Apache VirtualHost configuration (/etc/apache2/sites-available/your-site.conf
):
<VirtualHost *:443>
ServerName localhost
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/your-project/backend/public
SSLEngine on
SSLUseStapling off
SSLCertificateFile /var/www/html/your-project/certificates/server.cert
SSLCertificateKeyFile /var/www/html/your-project/certificates/private.key
ServerAlias 192.168.0.88
<Directory "/var/www/html/your-project/backend/public">
Options All
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Breakdown of the Configuration:
<VirtualHost *:443>
: Defines a VirtualHost block for HTTPS communication on port 443.
ServerName localhost
: Specifies the primary domain name associated with this VirtualHost. In this case, it is set to “localhost.”
ServerAdmin webmaster@localhost
: Email address of the server administrator.
DocumentRoot /var/www/html/your-project/backend/public
: Sets the document root directory for this VirtualHost. This is the location where the web server looks for files to serve.
SSLEngine on
: Enables the SSL engine for this VirtualHost, indicating that it should handle SSL connections.
SSLUseStapling off
: Disables SSL stapling. SSL stapling is a mechanism to enhance SSL/TLS certificate verification, but it’s turned off in this example.
SSLCertificateFile /var/www/html/your-project/certificates/server.cert
: Specifies the path to the SSL certificate file. This is the public key certificate file generated in previous steps.
SSLCertificateKeyFile /var/www/html/your-project/certificates/private.key
: Specifies the path to the private key file associated with the SSL certificate.
ServerAlias 192.168.0.88
: Additional domain names or IP addresses that this VirtualHost should respond to. In this case, it includes the IP address 192.168.0.88.
<Directory "/var/www/html/your-project/backend/public">
: Begins the configuration block for the specified directory.
Options All
: Allows all available options for this directory.
AllowOverride All
: Allows the use of the .htaccess file for configuration overrides in this directory.
Require all granted
: Grants access to all users.
</Directory>
: Ends the configuration block for the specified directory.
</VirtualHost>
: Ends the VirtualHost block.
Purpose of the Configuration:
- This configuration block ensures that Apache knows how to handle SSL connections for the specified domain (localhost and 192.168.0.88). It points to the SSL certificate files and defines access settings for the associated directory.
- Make sure to replace placeholders like “/var/www/html/your-project” with the actual paths used in your project.
Then enable it :
sudo a2ensite your-site.conf
Step 7: Restart Apache
sudo systemctl restart apache2
You’ll be prompted to enter the passphrase for the SSL/TLS keys.
Step 8: Check Apache Error Logs
sudo tail -f /var/log/apache2/error.log
Look for any error messages related to SSL.
Step 9: Set Permissions for Laravel Storage
cd /var/www/html/your-project/backend
sudo chmod -R 775 storage
sudo chown -R www-data:www-data storage
Now, you should be able to access your application securely at https://192.168.0.88
(Your IP)
Step 10: if you running react/laravel application
in frontend env :
REACT_APP_NAME = 'your-project'
REACT_APP_VERSION = v1.1.0
GENERATE_SOURCEMAP = false
REACT_APP_API_BASE_URL='https://192.168.0.88/api'
REACT_APP_ASSET_BASE_URL='https://192.168.0.88/storage'
REACT_APP_MAIN_DOMAIN='192.168.0.88:3000'
REACT_APP_API_DOMAIN='https://192.168.0.88'
REACT_APP_BACK_DOMAIN = 'https://192.168.0.88'
REACT_APP_SITE_KEY = 'your-key'
in backend env :
APP_URL=https://192.168.0.88
APP_SITE_URL="https://192.168.0.88:3000"
Congratulations! You have successfully created a self-signed SSL certificate with a Subject Alternative Name for your Apache web server on Ubuntu.
If you have a problem, then run
sudo systemctl restart apache2
cd /var/www/html/your-project/backend
sudo chmod -R 775 storage
sudo chown -R www-data:www-data storage
(Optional) Update /etc/hosts
Ensure that your /etc/hosts
file includes an entry for localhost
and the IP address 192.168.0.88
(your IP)
(Optional) Import Certificate into Chrome:
- Creating Authority & Convert the certificate to CRT format:
openssl x509 -in server.cert -out server.crt
- Convert Certificate and Key to PKCS#12 Format:
openssl pkcs12 -export -out certificate.pfx -inkey private.key -in server.cert
You’ll be prompted to enter the passphrase for the private key.
3. Import Certificate into Chrome:
- Open Chrome and go to
Settings
. - Scroll down and click on
Advanced
. - Under
Privacy and security
, click onManage certificates
. - In the
Certificates
window, go to thePersonal
tab. - Click on
Import
and select thecertificate.pfx
file you generated. - Follow the import wizard, enter the passphrase when prompted, and choose the certificate store.
4. If you want to make sure to add the Certificate Authority(CA) in trusted list :
sudo cp server.crt /usr/local/share/ca-certificates/server.crt
sudo update-ca-certificates
Use the following command to make sure that your certificates have been added to the trust list:
awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep -i localhost
To check the full details of the certificate, you can use OpenSSL or another tool. For example, using OpenSSL:
openssl x509 -in server.cert -text -noout
Check Expiry Date: Ensure that the SSL certificate has not expired. You can use the following OpenSSL command to check the expiry date:
openssl x509 -enddate -noout -in server.cert
Verify Certificate Content:
You can use OpenSSL to view the content of your certificate and private key files. Check if they contain the expected information:
openssl x509 -in server.cert -text -noout
openssl rsa -in private.key -text -noout
If you need that, the private key file is not password-protected. If it is, you may need to remove the passphrase from the private key.
openssl rsa -in private.key -out private.key
If you want to verify the certificate
openssl verify server.crt