Httpd SSL Configuration: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(48 intermediate revisions by the same user not shown)
Line 8: Line 8:


* [[httpd Configuration#Subjects]]
* [[httpd Configuration#Subjects]]
* [[SSL]]
* [[SSL/TLS]]
* [[Let's Encrypt]]


=Overview=
=Overview=
Line 15: Line 16:


=Procedure=
=Procedure=
==Obtain Certificate==
Obtain a certificate. Options:
* Use a generated self-signed certificate. Note that a Centos installation comes with a local certificate available in <code>/etc/pki/tls/certs/localhost.crt</code> and a private key <code>/etc/pki/tls/private/localhost.key</code>, which can be used for testing. httpd is configured by default to use it. This is how you [[openssl Operations#Generate_a_Self-Signed_Certificate|generate a self-signed certificate]].
* Install a valid certificated provided by Let's Encrypt. The procedure is available here, and usually is fully automatic:
{{Internal|Let's Encrypt#Procedure|Let's Encrypt}}
* Obtain a commercial certificate signed by a known CA.


==Install mod_ssl and openssl==
==Install mod_ssl and openssl==


<pre>
<syntaxhighlight lang='bash'>
yum install mod_ssl
yum -y install mod_ssl
yum install openssl
yum -y install openssl
</pre>
</syntaxhighlight>


By default, this ends up installing mod_ssl.so in <tt>/etc/httpd/modules</tt>. It also creates the default SSL configuration file ssl.conf in <tt>/etc/httpd/conf.d</tt>.
By default, this ends up installing <code>mod_ssl.so</code> in <code>/etc/httpd/modules</code>. It also creates the default SSL configuration file <code>ssl.conf</code> in <code>/etc/httpd/conf.d</code>.


==ssl.conf==
==ssl.conf==


ssl.conf must be included. Usually the main httpd.conf configuration file contains an "include all conf.d" line:
<code>ssl.conf</code> must be included explicitly, yum installation, while it creates, it does not include it. However, usually the main <code>httpd.conf</code> configuration file contains an "include all conf.d" line:


<pre>
<syntaxhighlight lang='text'>
IncludeOptional conf.d/*.conf
IncludeOptional conf.d/*.conf
</pre>
</syntaxhighlight>


which should take care of ssl.conf inclusion. More about <tt>[[httpd IncludeOptional|IncludeOptional]]</tt>.
which should take care of ssl.conf inclusion. More about <code>[[httpd IncludeOptional|IncludeOptional]]</code>.


If not present, explicitly add the following <tt>Include</tt> directive above the virtual host area:
If not present, explicitly add the following <code>Include</code> directive above the virtual host area:


<pre>
<syntaxhighlight lang='text'>
Include conf.d/ssl.conf
Include conf.d/ssl.conf
</pre>
</syntaxhighlight>


ssl.conf contains the configuration of a default secure virtual host, and the custom secure virtual hosts should be added under it. See [[#Secure_Virtual_Hosts|Secure Virtual Hosts]]
<code>ssl.conf</code> contains the configuration of a default secure virtual host, and the custom secure virtual hosts should be added under it. See [[#Secure_Virtual_Hosts|Secure Virtual Hosts]]


==Listen==
==Listen==
Line 47: Line 55:
Restrict the secure server to listen to a specific, dedicated interface by specifying it in ssl.conf <tt>Listen</tt>:
Restrict the secure server to listen to a specific, dedicated interface by specifying it in ssl.conf <tt>Listen</tt>:


<pre>
<syntaxhighlight lang='text'>
Listen 1.2.3.4:443 https
Listen 1.2.3.4:443 https
</pre>
</syntaxhighlight>


More details about <tt>Listen</tt> are available here <tt>[[httpd Listen|Listen]]</tt>.
Note that the main configuration file might still contain a <code>Listen</code> directive for port 80. This is fine if your web server still wants to serve unsecured pages, multiple <code>Listen</code> directives '''for different ports''' are legal. ⚠️ However, if more than one <code>Listen</code> directives instruct the server to listen '''on the same port''', the server will fail to start. More details about <code>Listen</code> are available here:
{{Internal|httpd Listen|<tt>Listen</tt> directive}}


==Log Location==
==Log Location==
Line 57: Line 66:
By default, the SSL logs level and location is different:
By default, the SSL logs level and location is different:


<pre>
<syntaxhighlight lang='text'>
ErrorLog logs/ssl_error_log
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
TransferLog logs/ssl_access_log
LogLevel warn
LogLevel warn
</pre>
</syntaxhighlight>
 
==localhost Key and Certificate==
 
These are self-signed, test certificates.


==Secure Virtual Hosts==
==Secure Virtual Hosts==


Add custom secure virtual hosts at the bottom of ssl.conf:
Add custom secure virtual hosts at the bottom of <code>ssl.conf</code>:


<pre>
<syntaxhighlight lang='text'>
<VirtualHost 1.2.3.4:443>
<VirtualHost 1.2.3.4:443>
     ServerName praetorian.novaordis.com
     ServerName praetorian.novaordis.com
Line 73: Line 86:
     SSLCertificateFile "/etc/pki/tls/certs/praetorian.novaordis.com.crt"
     SSLCertificateFile "/etc/pki/tls/certs/praetorian.novaordis.com.crt"
     SSLCertificateKeyFile "/etc/pki/tls/private/praetorian.novaordis.com.key"
     SSLCertificateKeyFile "/etc/pki/tls/private/praetorian.novaordis.com.key"
    SSLCertificateChainFile "/etc/pki/tls/certs/praetorian.novaordis.com-godaddy-chain.crt"
    DocumentRoot "/var/www/praetorian.novaordis.com"
</VirtualHost>
</VirtualHost>
</pre>
</syntaxhighlight>


GoDaddy certificate installation instructions: https://www.godaddy.com/help/installing-an-ssl-certificate-in-apache-centos-5238
GoDaddy certificate installation instructions: https://www.godaddy.com/help/installing-an-ssl-certificate-in-apache-centos-5238


==Secure Site Private Key==
==Site Private Key==


Place the private key under <tt>/etc/pki/tls/private</tt>.
Place the private key under <tt>/etc/pki/tls/private</tt>.
Line 86: Line 101:
Make it available to apache:apache and only it:
Make it available to apache:apache and only it:


<pre>
<syntaxhighlight lang='text'>
chown apache:apache praetorian.novaordis.com.key
chown apache:apache praetorian.novaordis.com.key
chmod go-rwx praetorian.novaordis.com.key
chmod go-rwx praetorian.novaordis.com.key
</pre>
</syntaxhighlight>


==Secure Site Certificate==
==Site Certificate==


Place the certificate file under <tt>/etc/pki/tls/certs</tt>.
Place the certificate file under <tt>/etc/pki/tls/certs</tt>.


Name it <tt><secure-site-FQN>.crt</tt>. Example: praetorian.novaordis.com.crt.
Name it <tt><secure-site-FQN>.crt</tt>. Example: praetorian.novaordis.com.crt.
==Site Chain/Intermediate Certificate==
Most trusted certificates require that you install at least one other intermediate/chain certificate on the server, to link your certificate up to the trusted source. For example, the GoDaddy-issued certificates require that.
Place the intermediate/chain certificate file under <tt>/etc/pki/tls/certs</tt>.
Name it <tt><secure-site-FQN>-godaddy-chain.crt</tt>. Example: praetorian.novaordis.com-godaddy-chain.crt.
Specify the path to the certificate chain under the corresponding secure virtual host as:
<syntaxhighlight lang='text'>
SSLCertificateChainFile "/etc/pki/tls/certs/praetorian.novaordis.com-godaddy-chain.crt"
</syntaxhighlight>
Note that for Apache 2.4.8 and higher you need to use SSLCACertificatePath instead.
==Test Certificate==
Use all of below. Testing is a good idea, test may reveal weaknesses and vulnerabilities. If everything was installed correctly, the checks should be successful.
* https://casecurity.ssllabs.com
* https://www.sslshopper.com/ssl-checker.html or similar.
==Other Details==
* Protect against the [[POODLE Attack]].
* Disable support for [[RC4 Cipher]]
* Support [[Forward Secrecy]] with the reference browsers.
=Troubleshooting=
=="SSLCertificateFile: file '/etc/pki/tls/certs/kb.novaordis.com.crt' does not exist or is empty"==
If I get an error message similar to <tt>SSLCertificateFile: file '/etc/pki/tls/certs/kb.novaordis.com.crt' does not exist or is empty</tt>, and the certificate file exists, is readable and it is a valid certificate, the cause is related to selinux misconfiguration.

Latest revision as of 03:03, 18 November 2021

External

Internal

Overview

In order to protect a web site with SSL, you will need to make sure mod_ssl is available and functional, then create a virtual host that listens on port different from the non-SSL protected sites (usually 443), turn the SSLEngine on for that virtual host, and specify the paths to the certificate and the private key.

Procedure

Obtain Certificate

Obtain a certificate. Options:

  • Use a generated self-signed certificate. Note that a Centos installation comes with a local certificate available in /etc/pki/tls/certs/localhost.crt and a private key /etc/pki/tls/private/localhost.key, which can be used for testing. httpd is configured by default to use it. This is how you generate a self-signed certificate.
  • Install a valid certificated provided by Let's Encrypt. The procedure is available here, and usually is fully automatic:
Let's Encrypt
  • Obtain a commercial certificate signed by a known CA.

Install mod_ssl and openssl

yum -y install mod_ssl
yum -y install openssl

By default, this ends up installing mod_ssl.so in /etc/httpd/modules. It also creates the default SSL configuration file ssl.conf in /etc/httpd/conf.d.

ssl.conf

ssl.conf must be included explicitly, yum installation, while it creates, it does not include it. However, usually the main httpd.conf configuration file contains an "include all conf.d" line:

IncludeOptional conf.d/*.conf

which should take care of ssl.conf inclusion. More about IncludeOptional.

If not present, explicitly add the following Include directive above the virtual host area:

Include conf.d/ssl.conf

ssl.conf contains the configuration of a default secure virtual host, and the custom secure virtual hosts should be added under it. See Secure Virtual Hosts

Listen

Restrict the secure server to listen to a specific, dedicated interface by specifying it in ssl.conf Listen:

Listen 1.2.3.4:443 https

Note that the main configuration file might still contain a Listen directive for port 80. This is fine if your web server still wants to serve unsecured pages, multiple Listen directives for different ports are legal. ⚠️ However, if more than one Listen directives instruct the server to listen on the same port, the server will fail to start. More details about Listen are available here:

Listen directive

Log Location

By default, the SSL logs level and location is different:

ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn

localhost Key and Certificate

These are self-signed, test certificates.

Secure Virtual Hosts

Add custom secure virtual hosts at the bottom of ssl.conf:

<VirtualHost 1.2.3.4:443>
    ServerName praetorian.novaordis.com
    SSLEngine on
    SSLCertificateFile "/etc/pki/tls/certs/praetorian.novaordis.com.crt"
    SSLCertificateKeyFile "/etc/pki/tls/private/praetorian.novaordis.com.key"
    SSLCertificateChainFile "/etc/pki/tls/certs/praetorian.novaordis.com-godaddy-chain.crt"
    DocumentRoot "/var/www/praetorian.novaordis.com"
</VirtualHost>

GoDaddy certificate installation instructions: https://www.godaddy.com/help/installing-an-ssl-certificate-in-apache-centos-5238

Site Private Key

Place the private key under /etc/pki/tls/private.

Name it <secure-site-FQN>.key. Example: praetorian.novaordis.com.key.

Make it available to apache:apache and only it:

chown apache:apache praetorian.novaordis.com.key
chmod go-rwx praetorian.novaordis.com.key

Site Certificate

Place the certificate file under /etc/pki/tls/certs.

Name it <secure-site-FQN>.crt. Example: praetorian.novaordis.com.crt.

Site Chain/Intermediate Certificate

Most trusted certificates require that you install at least one other intermediate/chain certificate on the server, to link your certificate up to the trusted source. For example, the GoDaddy-issued certificates require that.

Place the intermediate/chain certificate file under /etc/pki/tls/certs.

Name it <secure-site-FQN>-godaddy-chain.crt. Example: praetorian.novaordis.com-godaddy-chain.crt.

Specify the path to the certificate chain under the corresponding secure virtual host as:

SSLCertificateChainFile "/etc/pki/tls/certs/praetorian.novaordis.com-godaddy-chain.crt"

Note that for Apache 2.4.8 and higher you need to use SSLCACertificatePath instead.

Test Certificate

Use all of below. Testing is a good idea, test may reveal weaknesses and vulnerabilities. If everything was installed correctly, the checks should be successful.

Other Details

Troubleshooting

"SSLCertificateFile: file '/etc/pki/tls/certs/kb.novaordis.com.crt' does not exist or is empty"

If I get an error message similar to SSLCertificateFile: file '/etc/pki/tls/certs/kb.novaordis.com.crt' does not exist or is empty, and the certificate file exists, is readable and it is a valid certificate, the cause is related to selinux misconfiguration.