Enabling HTTP Secure (HTTPS)
This documentation needs work. See "Help improve this page" in the sidebar.
HTTPS is a protocol which encrypts HTTP requests and their responses. This ensures that if someone were able to compromise the network between your computer and the server you are requesting from, they would not be able to listen in or tamper with the communications.
When you visit a site via HTTPS, the URL looks like this: https://drupal.org/user/login. When you visit a site via plain (unencrypted) HTTP, it looks like this: http://drupal.org/user/login.
Why is it important to you
Nowadays, implementing HTTPS has almost become a no-brainer; with offerings like Let's Encrypt, who issue free certificates, anyone can afford to secure their website, and with improved SSL/TLS efficiency and faster hardware, the overhead has become negligible. There are very few reason, if any, to not have all traffic to your site protected with HTTPS.
One could easily argue that any web traffic is privacy-sensitive, but there are situations where it becomes especially important that the traffic is protected from eavesdropping. This is typically when a user would send sensitive information to a website and interception of that information would be a problem. Commonly, this information includes:
- Credit cards
- Sensitive cookies such as PHP session cookies
- Passwords and user names
- Identifiable information (Social Security number, State ID numbers, etc)
- Confidential content
Notably, this includes any administrator accessing the site by logging into it to make changes to the content or configuration, so in short, this applies to any Drupal site.
Moreover, HTTPS is now required for HTML5 Geolocation to work in nearly all modern browsers for privacy reasons! This is at the JavaScript implementation level, so the module used to supply this (e.g. GeoField [“Lat/Long” Widget] or IP Geolocation Views & Maps [“Set my location” Block] among others) cannot override it. If you attempt to use this over HTTP in any such browser (the only exceptions these days are dangerously outdated browsers such as on old Android devices and maybe some computers still running Windows XP or a PowerPC version of Mac OS X), it will not work and you will not get an error message explaining why (except perhaps in the browser’s Developer Tools Error Console) — the underlying JavaScript function calls simply won’t execute over HTTP. So if your web application needs to know where the visitor is without requiring typing in an address or manual Lat/Long coordinates, you must use HTTPS.
HTTPS can also prevent eavesdroppers from obtaining your authenticated session key, which is a cookie sent from your browser with each request to the site, and using it to impersonate you. For example, an attacker may gain administrative access to the site if you are a site administrator accessing the site via HTTP rather than HTTPS. This is known as session hijacking and can be accomplished with tools such as Firesheep.
How to enable HTTPS support in Drupal
Web server configuration
- Get a certificate. Many hosting providers set these up for you — either automatically or for a fee. You can also use Let’s Encrypt which is free, automated, and open Certificate Authority. If you want to secure a test site, you could instead generate a self-signed certificate.
- Configure your web server. A few helpful links:
Chances are, your webhost can do this for you if you are using shared or managed hosting.
Note: Clean URLs If you're using Apache for HTTP and HTTPS:
You will probably have two different VirtualHost buckets.
- A bucket for port :80 http
- A bucket for port :443 https
Each of these VirtualHost containers or buckets require that a specific Apache directive be added within them if you're using Clean URLs. This is because Drupal makes extensive use of .htaccess and mod_rewrite to provide friendly URLs.
Ensure you have the following within the directive, which is a child under the VirtualHost container: See Apache Documentation for AllowOverride
<Directory "/path/to/yoursite">
AllowOverride All
</Directory>This means that your .htaccess takes precedence and that the Apache configuration will allow it to run as you would expect for Drupal.
Troubleshooting:
If you enabled HTTPS and it only works on the homepage and your sub links are broken, it's because the VirtualHost:443 bucket needs AllowOverride All enabled so URLs can be rewritten while in HTTPS mode.
Drupal configuration
- For better security, send all authenticated traffic through HTTPS and use HTTP for anonymous sessions. You can use teh Secure Login module which resolves mixed-content warnings. Drupal automatically enables the
session.cookie_securePHP configuration on HTTPS sites, which causes SSL-only secure session cookies to be issued to the browser. -
For best possible security, set up your site to only use HTTPS, and respond to all HTTP requests with a redirect to your HTTPS site. Note that, HTTPS is vulnerable to man-in-the-middle attacks if the connection starts out as a HTTP connection before being redirected to HTTPS. Use Security Kit module to enable HSTS, or manually set the Strict-Transport-Security header in your webserver, and add your domain to the browser HSTS preload list, to help prevent users from accessing the site without HTTPS.
You may want to redirect all traffic from http://example.com and http://www.example.com to https://example.com. You can do this by adding the code below to your server configuration file, i.e., the VirtualHost definitions:
<VirtualHost *:80> ServerName www.example.com Redirect "/" "https://www.example.com/" </VirtualHost> <VirtualHost *:443> ServerName www.example.com # ... SSL configuration goes here </VirtualHost>The use of RewriteRule would be appropriate if you don't have access to the main server configuration file, and are obliged to perform this task in a .htaccess file instead:
RewriteCond %{HTTPS} off [OR] RewriteCond %{HTTP_HOST} ^www\.example\.com* RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]There are existing comments in .htaccess that explain how to redirect http://example.com to http://www.example.com (and vice versa), but this code here redirects both of those to https://example.com.
Recipes
Redirect all requests to https://www.url.de
I was adding https to a drupal multisite installation. https should be forced on all urls and http is not possible no more. You get this with:
# uncomment the following:
#1
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# 2 Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#1 is a modified version of the standard htaccess directive and #2 is taken from drupal 8 htaccess
This redirects al old http urls with a 301 to https://www.url.de
Remember that http access is not possible correctly no more with this because i removed {ENV:protossl}
Most of the time Drupal Developers face this problem while installing new modules and themes, They encountered with problem like "ERROR : You are not using an encrypted connection, so your password will be sent in plain text." . So I recommend all of them first give permission to your drupal_directory and sites and themes,Run few command that may help you before going through the whole technical part..
In linux
sudo chown www-data:www-data -R /var/www/html/drupal_directory/sites
In mac
sudo chown -R www:www /Library/WebServer/Documents/drupal_directory/sites
Redirect to HTTPS with settings.php
You can also force SSL and redirect to a domain with or without www in settings.php, the benefit is that it won't get overwritten after updating Drupal. Insert this at the top of settings.php, right after <?php, like this:
<?php
// Force HTTPS
// PHP_SAPI command line (cli) check prevents drush commands from giving a
// "Drush command terminated abnormally due to an unrecoverable error"
if ( (!array_key_exists('HTTPS', $_SERVER)) && (PHP_SAPI !== 'cli') ) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://example.org'. $_SERVER['REQUEST_URI']);
exit();
}
// Remove www
if ($_SERVER['HTTP_HOST'] == 'www.example.org') {
header('HTTP/1.0 301 Moved Permanently');
header('Location: https://example.org'. $_SERVER['REQUEST_URI']);
exit();
}
For generic domain you can use:
<?php
if ( (!array_key_exists('HTTPS', $_SERVER)) && (PHP_SAPI !== 'cli') ) {
if (substr($_SERVER['HTTP_HOST'], 0, 4) <> 'www.') {
$new_url = 'www.' . $_SERVER['HTTP_HOST'];
} else {
$new_url = $_SERVER['HTTP_HOST'];
}
$new_url .= $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: https://'. $new_url);
exit();
}
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion