history 32 of 36
Set Up an SSL Certificate on a CentOS Apache Web Server
Creating a key, CSR and self-signed certificate with OpenSSL, adding them to Apache mod_ssl on CentOS, and redirecting HTTP to HTTPS.
Written
- Web servers
- Monitoring and security
- Written for CentOS
- Written for Apache
From my Linux study notes, 2018. Some commands and versions here are old, so please reuse them carefully. Anything marked "added later", and the notes at the end, explain what has changed since.
These are my notes for adding SSL (HTTPS) to an Apache web server on CentOS using mod_ssl and a certificate made with OpenSSL. The certificate here is self-signed, which is fine for testing but not for a public website (see the notes at the end).
Before you start
-
Run the commands as root (or with
sudo). -
Apache (
httpd) should already be installed and working over HTTP. -
Back up any Apache config file before you edit it, for example:
Terminal window cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak -
Replace
your_namein the commands with a name for your site, such as the domain.
1. Install mod_ssl and OpenSSL
yum install mod_ssl openssl(The original had Yum with a capital Y; Linux commands are case-sensitive, so it must be yum.) Installing mod_ssl also adds the file /etc/httpd/conf.d/ssl.conf, which sets Apache up to listen on port 443.
2. Create the key and certificate
The original commands used two different sets of file names (ca.key/ca.crt in some lines, your_name.key/your_name.crt in others), so they would not work as written. Here they are first as I wrote them, then corrected to use one set of names.
As originally written:
# Generate private keyopenssl genrsa -out ca.key 1024
# Generate CSRopenssl req -new -key ca.key -out your_name.csr
# Generate Self Signed Keyopenssl x509 -req -days 365 -in your_name.csr -signkey your_name.key -out your_name.crtCorrected:
# Generate private key (2048 bits)openssl genrsa -out your_name.key 2048
# Generate CSR (certificate signing request)openssl req -new -key your_name.key -out your_name.csr
# Generate the self-signed certificate, valid for 365 daysopenssl x509 -req -days 365 -in your_name.csr -signkey your_name.key -out your_name.crtWhat changed and why:
- One set of names. The certificate must be signed with the same key the CSR was made from, so
-signkeymust point to the key created in the first command. - 2048 bits instead of 1024. 1024-bit RSA keys are considered too weak: certificate authorities no longer issue certificates for them, and many current systems refuse them. 2048 bits is the usual minimum.
What each file is:
your_name.key: the private key. Keep it secret.your_name.csr: the certificate signing request. You send this to a certificate authority if you buy a certificate.openssl reqasks for details such as country and organisation; the Common Name must be the site’s host name, for examplemysite.example.com.your_name.crt: the certificate Apache presents to visitors.
3. Copy the files to the correct locations
As originally written:
cp ca.crt /etc/pki/tls/certs/your_name.crtcp ca.key /etc/pki/tls/private/your_name.keycp ca.csr /etc/pki/tls/private/your_name.csrCorrected to match the file names above:
cp your_name.crt /etc/pki/tls/certs/your_name.crtcp your_name.key /etc/pki/tls/private/your_name.keycp your_name.csr /etc/pki/tls/private/your_name.csrMake the private key readable by root only:
chmod 600 /etc/pki/tls/private/your_name.key4. Point Apache at the certificate
vi /etc/httpd/conf.d/ssl.confChange the paths for SSLCertificateFile and SSLCertificateKeyFile:
SSLCertificateFile /etc/pki/tls/certs/your_name.crtSSLCertificateKeyFile /etc/pki/tls/private/your_name.keyRestart Apache:
service httpd restart5. Set up virtual host files
Edit the main Apache config:
vi /etc/httpd/conf/httpd.confAdd this line at the end:
Include conf/vhosts/*.confThe path is relative to Apache’s ServerRoot, which is /etc/httpd on CentOS, so this loads every .conf file in /etc/httpd/conf/vhosts/.
Create the folders:
mkdir /etc/httpd/conf/ssl-vhostsmkdir /etc/httpd/conf/vhostsCreate the virtual host files:
vi /etc/httpd/conf/ssl-vhosts/vhosts-ssl.confvi /etc/httpd/conf/vhosts/vhosts.confMy original note said only “add this line in this page” here, without saying which line. Two points to be aware of:
- Only the
vhostsfolder is included by the line above. A file inssl-vhostsis not loaded unless you also addInclude conf/ssl-vhosts/*.conftohttpd.conf. - The virtual host blocks in the next step are what go in these files: the port 80 block in
vhosts.confand the port 443 block invhosts-ssl.conf.
6. Redirect HTTP to HTTPS
To redirect, do as follows. This port 80 virtual host sends every visitor to the HTTPS address:
<VirtualHost *:80> ServerName mysite.example.com DocumentRoot /usr/local/apache2/htdocs Redirect permanent / https://mysite.example.com</VirtualHost>Correction (added later): give the target a trailing slash, Redirect permanent / https://mysite.example.com/. Redirect adds the rest of the requested path to the target, so without the slash a request for /page is sent to https://mysite.example.compage.
/usr/local/apache2/htdocs is the document root of an Apache built from source. On a CentOS package install the usual folder is /var/www/html. Because this block only redirects, the DocumentRoot here is not used for serving pages. Redirect permanent sends a 301 response, so browsers and search engines remember the new address.
The HTTPS virtual host:
<VirtualHost _default_:443> ServerName mysite.example.com DocumentRoot /var/www/your_dir SSLEngine On</VirtualHost>SSLEngine On turns on SSL but does not say which certificate to use, so add the certificate lines inside the block. Also note that the stock ssl.conf already contains a <VirtualHost _default_:443> block with the certificate paths from step 4. If you only have one HTTPS site, editing that existing block (its ServerName and DocumentRoot) is the simplest option; if you add your own block as well, check the Apache documentation on name-based virtual hosts for your version.
<VirtualHost _default_:443> ServerName mysite.example.com DocumentRoot /var/www/your_dir SSLEngine On SSLCertificateFile /etc/pki/tls/certs/your_name.crt SSLCertificateKeyFile /etc/pki/tls/private/your_name.key</VirtualHost>Check the configuration, then restart Apache:
apachectl configtestservice httpd restartapachectl configtest should print Syntax OK. If not, it shows the file and line with the problem.
How to check it worked
-
Visit
http://mysite.example.com; it should redirect tohttps://mysite.example.com. -
With a self-signed certificate the browser shows a warning; this is expected.
-
From the server, check the certificate Apache is presenting:
Terminal window openssl s_client -connect localhost:443 -servername mysite.example.com
Notes for today
-
Use a free trusted certificate for real sites. Self-signed certificates make browsers show a security warning, so they are only suitable for testing or internal use. For a public website, free certificates from Let’s Encrypt are the common choice today. They are issued with the
certbottool, which can also set up Apache and renew the certificates automatically. Let’s Encrypt certificates are short-lived, so automatic renewal matters. Installation instructions for your system are at https://certbot.eff.org/. -
Turn off old protocols. SSLv2, SSLv3, TLS 1.0 and TLS 1.1 are insecure and should not be enabled. In
ssl.confyou can allow only TLS 1.2 and 1.3:SSLProtocol -all +TLSv1.2 +TLSv1.3+TLSv1.3needs a recent Apache 2.4 built with OpenSSL 1.1.1 or later. Ifapachectl configtestrejects it on an older system, useSSLProtocol -all +TLSv1.2. -
CentOS end of life: CentOS 7 reached end of life on 30 June 2024 (CentOS 6 on 30 November 2020). Rocky Linux and AlmaLinux are the common free replacements; the
/etc/pki/tls/and/etc/httpd/paths are the same there. -
Services and packages:
service httpd restartbecamesystemctl restart httpd, andyumbecamednfon newer Red Hat-family systems. -
Firewall: open HTTPS on Rocky Linux and AlmaLinux with
sudo firewall-cmd --permanent --add-service=httpsthensudo firewall-cmd --reload. -
Apache’s official documentation, including mod_ssl, is at https://httpd.apache.org/docs/.