Elliptical Curves are just as strong as RSA, but they have a smaller footprint and require less overhead for cpu/network topologies. When deployed in high traffic situations, any cost savings without compromising something is always welcome. You can choose to generate an RSA or EC certificate and you will be fine with either. For those who have special cases or a need for running both, this is possible and will be discussed in a future update to this document.
su
cd /etc/pki/tls/
ls -l
nano /etc/pki/tls/openssl.cnf
OpenSSL Config File - These are the default fields you will be asked to input during the creation process.
req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US <---this will be the default Country unless you change it in the config file or during certificate creation
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = DC <---this will be the default State unless you change it in the config file or during certificate creation
localityName = Locality Name (eg, city)
localityName_default = Washington <---this will be the default City unless you change it in the config file or during certificate creation
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Company <---this will be the default Company Name unless you change it in the config file or during certificate creation
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = <---this is commented out. If you want to add this field uncomment it in the config file
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Tech <---this will be the default Organizational Unit (OU) unless you change it in the config file or during certificate creation
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = www.EXAMPLE.com <---this will be the default website or FQDN unless you change it in the config file or during certificate creation
commonName_max = 64
emailAddress = Email Address
emailAddress_default = info@EXAMPLE.com <---this will be the default email address unless you change it in the config file or during certificate creation
emailAddress_max = 64
If you use the openssl.cnf file from this site, you need to look at one thing! If you are going to have alternative names, you will have to either add them within the openssl.cnf (noted section below) or comment out (after DNS.1=) this part of the config.
ctrl+v pages down
[ alt_names ]
DNS.1 = EXAMPLE.com
www.EXAMPLE.com is what you are asked to input during the certificate creation. Before you create the cert, you need to change the alt names since they will be automatically added to the certificate during the creation process.
[ alt_names ]
DNS.1 = EXAMPLE.com
DNS.2 = web1.EXAMPLE.com
DNS.3 = mail.EXAMPLE.com
ctrl+o
ctrl+x
cd private/
Please use some naming convention so all certificates are unique descriptive names. The keys will not have passwords on them! If they have passwords on them, each time Apache restarts, you will have to enter the keys password before it will start. The keys and cert's will be protected by file permissions to ensure their integrity.
Free Certificate Authority (CA) based signed certificates can be found here - Ever since Mozilla entered a false CA certificate in their browser, they are the driving force for this effort. Great collaboration effort!
openssl req -x509 -nodes -sha384 -days 365 -newkey rsa:4096 -keyout rsa_EXAMPLE.key -out rsa_EXAMPLE.crt -extensions v3_req
openssl rsa -in rsa_EXAMPLE.key -text -noout
or
openssl rsa -in rsa_EXAMPLE.key -check
(Short Version)
openssl x509 -in rsa_EXAMPLE.crt -text -noout
or (Long Version)
openssl x509 -in rsa_EXAMPLE.crt -text
openssl req -nodes -sha384 -days 1095 -newkey rsa:4096 -keyout rsa_EXAMPLE.key -out rsa_EXAMPLE.csr -extensions v3_req
openssl req -text -noout -verify -in rsa_EXAMPLE.csr
Cut & Paste the csr file into the Comodo CA request box and choose Apache mod SSL or Apache OpenSSL for the server.- nano rsa_EXAMPLE.csr
nano rsa_EXAMPLE.csr
You receive the following files after Comodo signs your certificate.
To create the CA Chain Certificate
cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt >> EXAMPLE_com_CA.crt
We will go into much more depth on where and how these Certificates and Keys will be used and stored.
Fedora/Centos/Suse/RedHat:
SSLCertificateFile /etc/httpd/ssl/www_EXAMPLE_com.crt
SSLCertificateKeyFile /etc/httpd/ssl/rsa_EXAMPLE.key
SSLCertificateChainFile /etc/httpd/ssl/EXAMPLE_com_CA.crt
Options for the commands
-days - 365 = year (I issue three year or 1095)
-sha - can be 256, 384 or 512 (I use 384 or 512)
-rsa: - 2048 or 4096 (I use 4096) - a bit more overhead but hey why not :-) anything higher than 4096 - the cost and performance is horrendous for higher
-extensions v3_req - you want the v3 extension for your certificates
-nodes - To nodes or not to nodes that is the question? Remove -nodes and it will ask to password protect the file
-noout - This option inhibits the output of the encoded version of the parameters
Now we need to create and secure the directory where our Certificates and Keys will be stored to be used by Apache. We will also need to create some random DH Parameters for offsetting the Logjam vulnerability and making a better overall security stance.
Change to the Apache Directory
cd /etc/httpd/
Create the SSL Directory
mkdir ssl
Change permissions on the SSL Directory
chown 644 ssl/
Copy the Keys to the SSL directory
cp /etc/pki/tls/private/*.key /etc/httpd/ssl
Change permissions on the Keys
chown 640 ssl/*.key
Copy the Certificates to the SSL directory (Do not forget to move the www_EXAMPLE_com.crt & EXAMPLE_com_CA.crt to the directory if you have a CA Signed Certificate)
cp /etc/pki/tls/private/*.crt /etc/httpd/ssl
Change permissions on the Certificates
chown 644 ssl/*.crt
With Forward Secrecy, if an attacker gets a hold of the server's private key, it will not be able to decrypt past communications. The private key is only used to sign the DH handshake, which does not reveal the pre-master key. Diffie-Hellman ensures that the pre-master keys never leave the client and the server, and cannot be intercepted by a Man in the Middle attack (MiTM).
BTW - This procedure will take some time. Generating the DH Parameters puts a HUGE load on the server, so keep this in mind!
Change to the Apache2 SSL directory
cd /etc/httpd/ssl
Generate the DH Params file (Mandatory - Slow)
openssl dhparam -out dhparam.pem 4096
Set permissions on the DH PEM file (Mandatory)
chown 640 *.pem
Set permissions on the PEM file
chown 640 *.pem
Unfortunately the current version of OpenSSL does not support adding the DH Param file to the SSL config file.
Add the blue lines below(Preferred)
nano /etc/httpd/conf.d/ssl.conf
<IfModule mod_ssl.c>
SSLRandomSeed startup builtin
SSLRandomSeed startup file:/dev/urandom 512
SSLRandomSeed connect builtin
SSLRandomSeed connect file:/dev/urandom 512
SSLOpenSSLConfCmd Options -SessionTicket <--- We do not want clients connecting with older tickets, but instead initiate a full handshake
SSLCompression off <--- Prevents Crime Attack but it should be disabled in Apache2 with the latest version
............................
</IfModule>
SSLOpenSSLConfCmd Options -SessionTicket SSLCompression off
ctrl+o (save)
ctrl+x (exit)
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin host@EXAMPLE.com
ServerName EXAMPLE.com
ServerAlias www.EXAMPLE.com
DocumentRoot /var/www/html/EXAMPLE
DirectoryIndex index.html
LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLOpenSSLConfCmd Options -SessionTicket
SSLCompression off
........................
</VirtualHost>
</IfModule>
ctrl+o (save)
ctrl+x (exit)
There are a number of considerations you will have to account for in the https configuration file. A great guide for options and other considerations
Change the blue EXAMPLE to whatever is appropriate for your needs
nano /etc/httpd/conf.d/EXAMPLE_com.conf
<VirtualHost *:80>
ServerName EXAMPLE.com
ServerAlias www.EXAMPLE.com
DocumentRoot /var/www/html/EXAMPLE
DirectoryIndex index.html
ErrorLog /var/log/httpd/example.err
CustomLog /var/log/httpd/example.log combined
</VirtualHost>
ctrl+o (save)
ctrl+x (exit)
Fedora/Centos/Suse/RedHat: <---Change the blue EXAMPLE to whatever is appropriate for your needs
nano /etc/httpd/conf.d/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin host@EXAMPLE.com <--- Change this to whatever email address for your domain
ServerName EXAMPLE.com <--- Change this to the web site name you want to use
ServerAlias www.EXAMPLE.com <--- Change this to www or add any other alias for the site
DocumentRoot /var/www/html/EXAMPLE <--- Change this to the directory where the web site files are located
DirectoryIndex index.html <--- Change this if you wish to have another name for the default page
LogLevel info ssl:warn
ErrorLog /var/log/httpd/example.err
CustomLog /var/log/httpd/example.log combined
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/www_EXAMPLE_com.crt <--- Change this to the Self Signed or the Certificate Authority Signed Certificate
SSLCertificateKeyFile /etc/httpd/ssl/rsa_EXAMPLE.key or ec_EXAMPLE.key <--- Change this to the key you generated for the site
SSLCertificateChainFile /etc/httpd/ssl/EXAMPLE_CA.crt <--- Change this to the Certificate Authority Chain file you created
SSLCACertificatePath /etc/pki/tls/certs/
#SSLCACertificateFile /etc/httpd/ssl/
#SSLCARevocationPath /etc/httpd/ssl.crl/
#SSLCARevocationFile /etc/httpd/ssl.crl/ca-bundle.crl
#SSLVerifyClient require
#SSLVerifyDepth 10
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
<Directory /> <--- Protect our system files if you do not add this locally, you can add it globally (all sites) in Step2c
Require all denied
AllowOverride None
Options None
</Directory>
<Directory /var/www/html/EXAMPLE/> <--- Change to the directory of where the web sites files are located
Enter options of what to allow to execute or not(Optional permissions for directories below)
<Directory /var/www/html/EXAMPLE>
Options +Includes -Indexes -ExecCGI +FollowSymLink <--- Enables Server Side Includes (SSI), disables Indexing, disable executing CGI scripts and enables Following Symlinks
AllowOverride None
Order allow,deny
IndexIgnore *.mp3 <--- Hide certain files types from public view if allowing listing - Requires Indexes
Allow from all <--- Allow from 10.10.0.0/24 To only allow certain networks
</Directory>
Options All – All options are enabled (except MultiViews). If you don’t specify Options directive, this is the default value. <--- Never use!!!
Options ExecCGI – Execute CGI scripts (uses mod_cgi)
Options FollowSymLinks – If you have symbolic links in this directory, it will be followed.
Options Includes – Allow server side includes (uses mod_include)
Options Includes NOEXEC – Allow server side includes without the ability to execute a command or cgi.
Options Indexes – Disable directory listing
Options MultiViews – Allow content negotiated multiviews (uses mod_negotiation)
Options SymLinksIfOwnerMatch – Similar to FollowSymLinks. But, this will follow only when the owner is same between the link and the original directory to which it is linked.
SSetEnvIf Referer "^https://www\.EXAMPLE\.com/" local_referal <--- Protecting our content from being displayed on someone else's website
SSetEnvIf Referer "^$" local_referal
Protect the directories you desire <--- Protecting the directories of the content you do not want displayed on someone else's website
<Directory "/var/www/html/EXAMPLE/images">
Require env local_referal
</Directory>
<Directory "/var/www/html/EXAMPLE/documents">
Require env local_referal
</Directory>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
......................
</VirtualHost>
</IfModule>
ctrl+o (save)
ctrl+x (exit)
We need to minimize the information we are sharing with everyone. Also, we need to look over what modules are running and interacting with what applications. The bulk of the work is really in this procedure. It does not just involve turning on or off modules; but instead heavy tweaking the modules behavior and function can really harden a system beyond a hackers reach. Over time I will release more documentation on how to modify and alter Apache2 for performance and trapping rogue admins.
How to enable or disable Apache 2.4 modules
Comment/uncomment out the lines for each module listed in /etc/httpd/conf.modules.d/
To list all of the Apache modules running:
httpd -M
Disable ANY Modules not needed for your configuration or turn them all off and re-enable them below
The commands below will install the necessary Modules for now
yum install mod_ssl
yum install mod_sessions
mod_headers is installed and is enabled by default
The newly created sited should be enabled automatically if they were configured correctly and no command is necessary.
Do not forget to handle the IP defaulting to a web page if you disable the defaults. Do not use the Apache2 default page!
Comment out the content of the below mentioned files and if you want you can even rename them after doing so.
nano /etc/httpd/conf.d/welcome.conf
nano /etc/httpd/conf.modules.d/00-ssl.conf
nano /etc/httpd/conf/httpd.conf
Locate and change: <--- Change the lines in blue below
Timeout 30
KeepAliveTimeout 5
<Directory /> <--- Protect our system files - If you did not add this in the prior Step2b, you can add it globally here
Require all denied
AllowOverride None
Options None
</Directory>
ctrl+o (save)
ctrl+x (exit)
We could put all of Security Header settings in this file, but I highly do not recommend it on a Server that hosts numerous sites!
nano /etc/httpd/conf/httpd.conf
Locate and change: <--- Change the lines in blue below
ServerTokens Prod
ServerSignature Off
TraceEnable Off
ctrl+o (save)
ctrl+x (exit)
nano /etc/php.ini
Locate, find and change: <--- Change the line in blue below
expose_php = Off
ctrl+o (save)
ctrl+x (exit)
Each process under event can contain multiple threads and each is capable of more than one task. This results in Apache having the lowest requirements when used with mpm_event.
We are using a configuration that requires us to address the higher load requirements.
nano /etc/httpd/conf.modules.d/00-mpm.conf
Locate, find and change: <--- Change the lines in blue below - Config for a dedicated Web application server. If this a Web server, email, DNS, and so forth, cut everything in half and MaxMemFree minimum of 4096 - Which is 4 megs and alter as necessary.
<IfModule mpm_event_module>
#StartServers 5
#MinSpareServers 5
#MaxSpareServers 10
#MaxRequestWorkers 150
#MaxConnectionsPerChild 0
MaxMemFree 0
StartServers 5
ServerLimit 32
MaxClients 256
MaxRequestWorkers 50
MaxConnectionsPerChild 1000
</IfModule>
systemctl restart httpd
Another option is to remove or add SSL/TLS Protocols - I highly recommend at a minimum to remove -SSLv2 and -SSLv3!!! To remove TLS support just add -TLSv1 -TLSv1.1 -TLSv1.2 as noted below in order to drop support for each protocol. TLSv1.1 is rarely used and is not really that different from TLSv1. It is recommended, if you can at any chance, to use only TLSv1.2, but this change should be evaluated on its overall effect prior to making such a change.
Protocol Support
SSL 2.0 - 0%
SSL 3.0 - 80%
TLS 1.0 - 90%
TLS 1.1 - 95% <--- We will score 90-95% on all tests
TLS 1.2 - 100%
You can alter the cipher suite in order to achieve the preference and order of the ciphers you wish to use. If you desire to make clients follow the preferred order, then SSLHonorCipherOrder will need to be turned to on. When the SSLHonorCipherOrder is on, clients will connect by the following cipher list. Mozilla has a great config generator for this!
You can remove the use of 128 bit ciphers to only use 256 bit, or remove 256 bit ciphers to only use 128 bit ciphers - add at the end of SSLCipherSuite :!AES128 or :!AES256 to remove the respective AES ciphers. You can remove 256 bit ciphers without much issue. Removing 128 bit and only using 256 bit ciphers locks you in to TLSv1.2 and drops support for older clients. Removing the 128 bit ciphers does get a 100% score on the tests. The config presented here does not drop support for either to ensure maximum audience for our site while remaining secure.
If this is for a Top Secret environment, please remove the use of 128 bit ciphers and only use TLSv1.2! This will get you 100% on all areas of the SSLLabs.com test but is very limiting if being used over the Internet for business. This is the preferred setup if possible. Please use it if you do not have to deal with older operating systems and browsers!
SSLCipherSuite "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:........"
The first two entries are Elliptic Curve using GCM (no preference order): EECDH+ECDSA+AESGCM, then RSA using GCM (no preference order): EECDH+aRSA+AESGCM. A client will try to negotiate in order of our preference we list here. The preference is for Elliptic Curve using GCM, followed by RSA using GCM, Elliptic Curve using SHA384 (EECDH+ECDSA+SHA384), Elliptic Curve using SHA256 (EECDH+ECDSA+SHA256), RSA using SHA384 (EECDH+aRSA+SHA384), RSA using SHA256 (EECDH+aRSA+SHA256), and so on down the list of ciphers. BTW the Cipher list has options: + can be used for generalizing the specification of cipher suites, as in the example for the first cipher (EECDH+ECDSA+AESGCM), we do not specify 128 or 256 bit nor sha 256 or 384. You can use the - sign for specifying the exact cipher or spec you want to use ie (ECDHE-RSA-AES256-GCM-SHA384)
Lets see what minor changes can do to this configuration
The options are whatever you desire as long as your intended audience can use those ciphers to connect to your application or site. You can add Camellia, CHACHA20 (ECDHE+ECDSA+CHACHA20+POLY1305: ECDHE+RSA+CHACHA20+POLY1305:), or anything else in the cipher list, but the procedure uses my preference that works with most clients while remaining secure. Lets say we want to know what happens if we remove certain ciphers. If you know you are not supporting older clients (Internal environment or strict security site in the wild), then you can remove EECDH+aRSA+RC4:EECDH:EDH+aRSA (Only TLSv1.2 will be used) in the procedure (Fully mitigate BEAST). If you remove EECDH+aRSA+RC4:EECDH:EDH+aRSA, the results with these removed. Compare the results with these included. It would be a similar result if you are using ECC and the list of ciphers you would accept. Think about what other ciphers you desire to add if you remove these ciphers. Unless you are an admin and understand the implications, I would not recommend it.
nano /etc/httpd/conf.modules.d/ssl.conf
SSLCipherSuite "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:
EECDH+aRSA+RC4:EECDH:EDH+aRSA:!MEDIUM:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA"
SSLHonorCipherOrder on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
"EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!MEDIUM:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA"
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
<--Add the sections in blue to the file
nano /etc/httpd/conf.d/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin host@EXAMPLE.com
ServerName EXAMPLE.com
ServerAlias www.EXAMPLE.com
DocumentRoot /var/www/html/EXAMPLE
DirectoryIndex index.html
LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCipherSuite "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:
EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!MEDIUM:!RC4:
!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SEED:!CAMELLIA"
SSLHonorCipherOrder on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
........................
</VirtualHost>
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
While it may appear that allowing the site operator to control verification responses would allow a fraudulent site to issue false verification for a revoked certificate, the stapled responses can't be forged as they need to be directly signed by the certificate authority, not the server. If the client does not receive a stapled response, it will just contact the OCSP server by itself. However, if the client receives an invalid stapled response, it will abort the connection. The only increased risk of OCSP stapling is that the notification of revocation for a certificate may be delayed until the last-signed OCSP response expires.
As a result, clients continue to have verifiable assurance from the certificate authority that the certificate is presently valid (or was quite recently), but no longer need to individually contact the OCSP server. This means that the brunt of the resource burden is now placed back on the certificate holder. It also means that the client software no longer needs to disclose users' browsing habits to any third party.
Overall performance is also improved: When the client fetches the OCSP response directly from the CA, it usually involves the lookup of the domain name of the CA's OCSP server in the DNS as well as establishing a connection to the OCSP server. When OCSP stapling is used, the certificate status information is delivered to the client through an already established channel, reducing overhead and improving performance - Wikipedia
nano /etc/httpd/conf.modules.d/ssl.conf
Change or uncomment the following three lines in the ssl.conf <--Add the sections in blue to the file - Applies to all Operating Systems
SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
SSLSessionCacheTimeout 60
SSLStaplingCache "shmcb:logs/stapling-cache(512000)"
ctrl+o (save)
ctrl+x (exit)
Add the sections in blue to the file
nano /etc/httpd/conf.d/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin host@EXAMPLE.com
ServerName EXAMPLE.com
ServerAlias www.EXAMPLE.com
DocumentRoot /var/www/html/EXAMPLE
DirectoryIndex index.html
LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/www_EXAMPLE_com.crt
SSLCertificateKeyFile /etc/httpd/ssl/rsa_EXAMPLE.key or ec_EXAMPLE.key
SSLCertificateChainFile /etc/httpd/ssl/EXAMPLE_CA.crt
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLCACertificatePath /etc/pki/tls/certs/
#SSLCACertificateFile /etc/pki/tls/certs/
...............
</VirtualHost>
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
<IfModule mod_ssl.c>
SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
SSLSessionCacheTimeout 60
SSLStaplingCache "shmcb:logs/stapling-cache(512000)"
<VirtualHost *:443>
ServerAdmin host@EXAMPLE.com
ServerName EXAMPLE.com
ServerAlias www.EXAMPLE.com
DocumentRoot /var/www/html/EXAMPLE
DirectoryIndex index.html
LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/www_EXAMPLE_com.crt
SSLCertificateKeyFile /etc/httpd/ssl/rsa_EXAMPLE.key or ec_EXAMPLE.key
SSLCertificateChainFile /etc/httpd/ssl/EXAMPLE_CA.crt
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLCACertificatePath /etc/pki/tls/certs/
#SSLCACertificateFile /etc/pki/tls/certs/
...............
</VirtualHost>
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
Love the Apache foundation when they warn you about their own products - Enabling HTTP/2 on your Apache Server has impact on the resource consumption and if you have a busy site, you may need to consider carefully the implications. The first noticeable thing after enabling HTTP/2 is that your server processes will start additional threads. The reason for this is that HTTP/2 gives all requests that it receives to its own Worker threads for processing, collects the results and streams them out to the client.
H2 Options explained more in depth
As if the Apache Foundations documentation is not horrible enough, their guidance being awful and did they even test H2? Akamai test showing the speed difference despite the Apache Foundation being the Apache Foundation. People still think encryption kills performance! This is an older myth that needs to die a painful death! Straight HTTP is slower than HTTPS!
HTTP 1.1/2 has many wonderful benefits compared to HTTP 1.0/1.1. H2 has DDoS protection, better security, options, and so forth. H2 allows us to use Application-Layer Protocol Negotiation (ALPN) which drops our latency to pretty much zero for requests. Mobile devices are also upping the ante for security. We should use it whenever possible and pretty much every modern browser supports it. Despite the warning, I have not had problems with H2 but still will "tweak" MPM Prefork and other settings to gain some performance.
I am surprised at how many large sites do not have it deployed.
Test performed April 20th, 2016 - Image source keycdn.com
Unfortunately the current version of Apache in RHEL 7.6 does not support HTTP/2. HTTP/2 has been introduced in RHEL 8 Beta. We will be covering it in an updated document once a final version has been released.
Security Headers seems to be one of the most skipped steps in just about every configuration out there. I have listed the minimum security headers config that should be included in every instance of Apache 2.4. Security Headers (to work against sniffing and manipulating our own content) are a whole topic to itself on how to control the connection with clients. Not to mention, what we could possibly to do anyone using header manipulation to injection all sorts of fun. Apache2 module and header manipulation is truly an art form that seemingly very few people understand. This is where the majority of the security work and tweaking comes into play in order to stay ahead of the curve. There are so many lovely options for headers and how to use them.
We are using headers to deal with things like:
Header Syntax usage: Header [condition] add|append|echo|edit|edit*|merge|set|setifempty|unset|note
Header [[expr=]value [replacement] [early|env=[!]varname|expr=expression] <--When we desire to alter our headers behavior
The below chart breaks down the top million requested website's - Scott Helme performed this very interesting study about the lack of Security Header use in the top million requested website's. This also means that only 6% of the 1 Million sites tested actually use HTTPS!!! Scott Helme Security Headers Test- securityheaders.io
I do not recommend using security headers as a global configuration and will not show an alternative way of using them.
nano /etc/httpd/conf/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
..............................
</VirtualHost>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
<IfModule mod_headers.c>
Header unset ETag
FileETag None
Header unset Server
Header always set X-Content-Type-Options "nosniff"
Header always append X-Frame-Options SAMEORIGIN
Header always set X-XSS-Protection "1; mode=block"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header always set Feature-Policy "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none' "
Header set X-Frame-Options DENY
Header set Cache-Control:public, max-age=31536000
Header set MyHeader "Feel safe zombiesecured headers in use!!! It took %D microseconds for Zombiesecured to serve this request on %t"
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
The HTTP Strict Transport Security (HSTS) feature lets a web server inform the browser that it will not load the site using HTTP, and will automatically convert all attempts to access the site using HTTP to HTTPS requests instead. This is one of the most misunderstood subjects for some reason.
You would think every bank, credit card company, and government would want this enabled by default. Right? Most do not!!!
The clients HTTP request will be responded with an encrypted response. An HTTPS acknowledgement over HTTP! Yes! That is bad right? No! You want this! You are redirecting and altering the clients HTTP request, to an encrypted request over HTTPS. Technically, you made the secure request before the client made a non-secure connection. This is the only "secure" information over HTTP you are sharing with the connecting clients. You are noting that this is not desired when it is the standard.
Not adding HSTS is serious mistake!. Any major application/browser works with it and I do not recommend making the headers a global configuration, but rather added in each Web site config file.
Any enterprise internal environment should have this globally.
You must always be in control of the clients, the clients should never have control under their terms.
The following should be included in the website headers section to ensure every client never connects to the application/site unless it is secure and remains connected securely. To have the HTTP request rejected and respond with an HTTPS connection instead, it requires preloading to be enabled. ***Add preload to the configuration once you submit your site here!
Not to be annoying by repeating myself. People still think encryption kills performance! This is an older myth that needs to die a painful death! Straight HTTP is slower than HTTPS! Therefore, HSTS is a must for any environment!
You have to alter the HTTP and HTTPS Web site config files.
nano /etc/httpd/conf.d/EXAMPLE_com.conf
<VirtualHost *:80>
ServerName EXAMPLE.com
ServerAlias www.EXAMPLE.com
Redirect permanent / https://EXAMPLE.com/ <--Will send everyone to our default site https://www.EXAMPLE.com
OR
Redirect permanent / https://EXAMPLE.com <--Requesting http://www.EXAMPLE.com/page - will be sent to https://www.EXAMPLE.com/page
RewriteEngine On
RewriteRule ^(.*)$ https://EXAMPLE.com/$1 [L,R=301]
DocumentRoot /var/www/html/EXAMPLE
DirectoryIndex index.html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
nano /etc/httpd/conf.d/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
..............................
</VirtualHost>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
<IfModule mod_headers.c>
Header unset ETag
FileETag None
Header unset Server
Header always set X-Content-Type-Options "nosniff"
Header always append X-Frame-Options SAMEORIGIN
Header always set X-XSS-Protection "1; mode=block"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header set X-Content-Security-Policy "allow 'self';"
Header set X-Frame-Options DENY
Header set Cache-Control:public, max-age=31536000
Header set MyHeader "Feel safe zombiesecured headers in use!!! It took %D microseconds for Zombiesecured to serve this request on %t"
Header always set Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
If your organization generates and rotate keys more than once a year, then you might consider not implementing a static key pinning. Internet Engineering Task Force (IETF) Request for Comments (RFC) 7459 (Representation of Uncertainty and Confidence in the Presence Information Data Format Location Object) & RFC 7469 (Public Key Pinning Extension for HTTP), states you have to pin two separate certificates in order to maintain confidence and be able to have an immediate backup not being used currently. So, one must be in the certificate chain used for client connections, the other pin(s) must not be present in the certificate chain being pinned. Having four extras CA signed certs minimum in the key store for a huge enterprise would be recommended. Business can afford the extra peace of mind at little cost compared to the risk for blocking customers. The standards for presentation and method are not the best for implementation at this point. Is this why is it used by less than 1% of the entire Internet? Well, make one mistake and you are out of business for months!
Great guide for HPKP
I am a fan of this great technology, but it is at the infancy stage. It really helps our security stance, but it really does not help us enough to make it mandatory either. Why? The people implementing should take heed before implementing HPKP. It works great with HSTS to prevent MiTM attacks, but offers risk for anyone not thoroughly understanding the implementation aspects of it. If you are an Admin, then is IS MANDATORY and you can play with the time variable without issue and get the point I am trying to make. If you are a Novice, this is recommended. If this is your first time with HPKP - then set max-age=1111 (~18.5 minutes)!!!! Once everything is in order and tested, then set max-age=3156000 for pinning the key for one year. What do you do if you/company change the key, or if the CA reissues the pinned certificate? Then you can pin the backup and alter the time variable again.
Hashing also provides three additional benefits. First, hashing allows you to anonymize a certificate or public key. This might be important if you application is concerned about leaking information during decompilation and re-engineering.
Second, a digested certificate fingerprint is often available as a native API for many libraries, so its convenient to use.
Finally, an organization might want to supply a secondary (or back-up) identity in case the primary identity is compromised. Hashing ensures your adversaries do not see the reserved certificate or public key in advance of its use. In fact, Google's IETF draft websec-key-pinning uses the technique.
First choice in pinning is your own certificate, if you have a great internal security infrastructure with a low risk of being compromised, then use this certificate. You can handle your entire domain and subdomains with one certificate. If you issue a certificate for a subdomain and try to pin it, the certificates will overlap and appear to be potentially a problem on he clients end.
Second, you can pin the intermediate CA certificate that issued your cert in use. Pin this one if you are not in a secure environment many have access to the keys and certs.
The other pins (second, third, etc.) are your backup public keys on your extra other CA signed certs in the key store. You can add the Hash fingerprint of a differing CA signed certificate issued for the second, third, and so on. Mozilla has a great article on HPKP and why they got on board with it
Header set Public-Key-Pins "pin-sha256=\"Hash of Pin 1\"; pin-sha256=\"Hash of Pin 2\"; pin-sha256=\"Hash of Pin 3\"; includeSubDomains; max-age=1111"
Scott Helme has a great tool to get the HPKP Hash Decoder.Below are some steps that have been used by Scott Helme in setting up HPKP. The complete guide can be found here.
How to setup HPKP
The first step to creating a HPKP policy is to get the fingerprint of your current certificate. Change certificate name to your own.
openssl x509 -pubkey < EXAMPLE_CA.crt | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
This should produce something like this: Nsj0e1Md7GkYYkVoZWmM= and this goes here: pin-sha256=\place the results of the hash output here between the trailing slashes\ or pin-sha256=\Nsj0e1Md7GkYYkVoZWmM=\
Creating a Backup CSR
In this step we are going to create some backup CSRs and include their fingerprints in the header.
openssl req -nodes -sha384 -days 1095 -newkey rsa:4096 -keyout rsa_EXAMPLE1.key -out rsa_EXAMPLE1.csr -extensions v3_req
Country Name (2 letter code) [US]:
State or Province Name (full name) [DC]:
Locality Name (eg, city) [Washington]:
Organization Name (eg, company) [Company]:
Organizational Unit Name (eg, section) [Tech]:
Common Name (e.g. server FQDN or YOUR name) [www.EXAMPLE.com]:
Email Address [info@EXAMPLE.com]:
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []:
An optional company name []:
Change the information based on your needs. The next step would be getting the fingerprint of the CSR that we just created.
openssl req -pubkey < rsa_EXAMPLE1.csr | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
Now that we got the fingerprint of the CSR. We go through the above steps one more time to create another private key, CSR and fingerprint.
HPKP includes a report-uri directive where you specify a URI to POST a JSON formatted failure report for an unauthorized access attempt. If someone tries to connect to our site against our HPKP policy, it would be nice to know we are under attack.
{ "date-time": date-time,
"hostname": hostname,
"port": port,
"effective-expiration-date": expiration-date,
"include-subdomains": include-subdomains,
"noted-hostname": noted-hostname,
"served-certificate-chain": [ pem1, ... pemN ],
"validated-certificate-chain": [ pem1, ... pemN ],
"known-pins": [ known-pin1, ... known-pinN ]
}
nano /etc/httpd/conf/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
..............................
</VirtualHost>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
<IfModule mod_headers.c>
Header unset ETag
FileETag None
Header unset Server
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header set X-Content-Security-Policy "allow 'self';"
Header set X-Frame-Options DENY<br>
Header always append X-Frame-Options SAMEORIGIN
Header set Cache-Control:public, max-age=31536000
Header always set Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
Header set MyHeader "Feel safe zombiesecured headers in use!!! It took %D microseconds for Zombiesecured to serve this request on %t"
Header always set Public-Key-Pins "pin-sha256=\"Hash of Pin 1\"; pin-sha256=\"Hash of Pin 2\"; pin-sha256=\"Hash of Pin 3\"; includeSubDomains; report-uri="https://report.EXAMPLE.com"; max-age=1111" <--- Change max age to 3156000 (1 Year) once pinning is working
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
Content security policies are enacted by most of the larger content providers to minimize the amount of reloading of information. When if fact, it really is a great security measure to ensure that only our site is providing clients with content from our own sources and not someone else injecting code, malware and a vast array of other possibilities to perform against a site/server/client. It should be noted that less than one percent (1%) of the Internet has such policies and makes it easy to put my own source code in the middle of a communication stream. It is not mandatory since there are situations in which you do not wish to use CSP's at the server level. Unless you are an admin that understands those methods and implementations, use this procedure until you move the CSP to another area.
Scott Helme developed some nifty tools to help you generate a policy, analyses your policy or generate a hash of JS or CSS for your CSP
nano /etc/httpd/conf.d/EXAMPLE_com_ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
..............................
</VirtualHost>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
<IfModule mod_headers.c>
Header unset ETag
FileETag None
Header unset Server
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header set X-Content-Security-Policy "allow 'self';"
Header always append X-Frame-Options SAMEORIGIN
Header set X-Frame-Options DENY
Header set Cache-Control:public, max-age=31536000
Header always set Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
Header set MyHeader "Feel safe zombiesecured headers in use!!! It took %D microseconds for Zombiesecured to serve this request on %t"
Header set Public-Key-Pins "pin-sha256=\"\"; pin-sha256=\"\"; includeSubDomains; report-uri="https://report.EXAMPLE.com"; max-age=1111"
Header always set Content-Security-Policy: "" <--- Put your policy parameters between to the quotes - remove any redundancies
</IfModule>
ctrl+o (save)
ctrl+x (exit)
systemctl restart httpd
Zombie Secured Headers in use:
Header always set Content-Security-Policy: "default-src 'self' 'unsafe-inline' ; script-src 'self' ; style-src 'self' 'unsafe-inline' ; img-src 'self' ; font-src 'self' ; connect-src 'self' ; media-src 'self' ; object-src 'self' ; child-src 'self' ; frame-ancestors 'none' ; form-action 'self' ; upgrade-insecure-requests; block-all-mixed-content; reflected-xss block; base-uri zombiesecured.com; referrer origin;"
Zombie Secured CSP test results