Httpd SSL Configuration: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(35 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>


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 are legal.
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}}
More details about <tt>Listen</tt> are available here <tt>[[httpd Listen|Listen]]</tt>.


==Log Location==
==Log Location==
Line 59: 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 78: Line 89:
     DocumentRoot "/var/www/praetorian.novaordis.com"
     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
Line 90: 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>


==Site Certificate==
==Site Certificate==
Line 111: Line 122:
Specify the path to the certificate chain under the corresponding secure virtual host as:
Specify the path to the certificate chain under the corresponding secure virtual host as:


<pre>
<syntaxhighlight lang='text'>
      SSLCertificateChainFile "/etc/pki/tls/certs/praetorian.novaordis.com-godaddy-chain.crt"
SSLCertificateChainFile "/etc/pki/tls/certs/praetorian.novaordis.com-godaddy-chain.crt"
</pre>
</syntaxhighlight>


Note that for Apache 2.4.8 and higher you need to use SSLCACertificatePath instead.
Note that for Apache 2.4.8 and higher you need to use SSLCACertificatePath instead.
Line 122: Line 133:
* https://casecurity.ssllabs.com
* https://casecurity.ssllabs.com
* https://www.sslshopper.com/ssl-checker.html or similar.
* 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.