Blog

Any website developer may face a situation, at times, when both - HTTP and HTTPS - protocols have to be used to increase the protection level of the whole site or of its selected  pages. HTTPS application is preferable for the pages that contain user private details or other sensitive information, like payment system details etc. The above protocol provides for an additional layer of encoding/authentication as inserted in between HTTP and TCP. As a matter of fact, HTTPS is rather a combination of the robust interaction with HTTP via SSL, than a separate protocol, in that SSL, effectively, is a protocol utilized to secure privacy of data exchange between a user and the server. Thus, a kind of a 'moderate protection' is enstablished against phone tapping and the cases of man-in-the-middle attacks.

To implement the above, you have to fix the server settings, and in terms of this article we deal with the instances of Nginx and Apache severs configuration. The standard settings configuration procedure having done, one proceeds to configuring the host files, so as HTTP and HTTPS protocol usage location could be indicated (by default, they are located in /etc/nginx/sites-availabe/ folder). SSL key and the certificates will come handy, too, and they can either be purchased or generated on your own.

Terminal commands for the key and certificates generation are as follows:

openssl genrsa -des3 -outexamplekey 1024
openssl req -new -key xample.key -out .crt

In Common name you should input domain for which you generate keys.

Here is an example of “drupal7” host configuration done with mixed protocol http + https on the Nginx server (with the relevant file path: /etc/nginx/sites-available/drupal7):

server {
    ## HTTP protocol port.
    listen *:80;
 
    ## HTTPS protocol port.
    listen *:443 ssl;
    
    server_name example.com www.example.com;
    
    ## Server certificate and key.
    ssl_certificate /etc/nginx/ssl/example.crt;
    ssl_certificate_key /etc/nginx/ssl/example.key;
    
    root /var/www/example.com/htdocs;
    index index.html index.htm index.php index.cgi index.pl index.xhtml;
    
    error_log /var/log/nginx/drupal.error.log;
    access_log /var/log/nginx/drupal.access.log combined;
    
    server_tokens off;
    client_max_body_size 15M;
    
    # host_without_www
    if ($host ~* www\.(.*)) {
          set $host_without_www $1;
          rewrite ^(.*)$ http://$host_without_www$1 permanent;
    }



    ## Disable .htaccess and other hidden files
    location ~ /\. {
          deny all;
          access_log off;
          log_not_found off;
    }
 
    location = /favicon.ico {
          log_not_found off;
          access_log off;
    }
 
    location = /robots.txt {
          allow all;
          log_not_found off;
          access_log off;
    }
 
    location ~* ^(?:.+\.(?:htaccess|make|txt|engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(?:\.php)?|xtmpl)|code-style\.pl|/Entries.*|/Repository|/Root|/Tag|/Template)$ {
          rewrite  ^/(.*)$  /index.php?q=$1  last;
    }


    ## Factcgi configuration
    location ~ \.php$ {
          fastcgi_pass   127.0.0.1:9000;
          fastcgi_index  index.php;
          fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
          include fastcgi_params;
          fastcgi_ignore_client_abort     off;
          fastcgi_connect_timeout 60;
          fastcgi_read_timeout 240;
          fastcgi_buffer_size 16M;
          fastcgi_buffers 4 32M;
          fastcgi_busy_buffers_size 64M;
          fastcgi_temp_file_write_size 64M;
    }

 
    ## Serve static files directly
    location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico)$ {
          access_log off;
          expires max;
    }
 
    ## Imagecache needs to have php read any files that it's planning to manipulate
    location ^~ /files/imagecache/ {
          index index.php;
    }
 
    ## Assume a clean URL is requested, and rewrite to index.php
    if (!-e $request_filename) {
          rewrite ^/(.*)$ /index.php?q=$1 last;
          break;
    }
 
    location ^~ /files/ {
          allow all;
          log_not_found off;
          access_log off;
    }
 
    location ^~ /sites/default/files/ {
          allow all;
          log_not_found off;
          access_log off;
    }
   
}

  In the case of Apache server the settings will read as follows:

## Settigns for HTTP protocol
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        ServerName drupal

        ## Folder with drupal site
        DocumentRoot /var/www/drupal
        <Directory />
              Options FollowSymLinks
              AllowOverride All
        </Directory>

        ## Clean URLs for drupal site
        <Directory /var/www/drupal/>
              RewriteEngine On
              RewriteBase /
              RewriteCond %{REQUEST_FILENAME} !-f
              RewriteCond %{REQUEST_FILENAME} !-d
              RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              Allow from all
        </Directory>

        ## File for error logging
        ErrorLog ${APACHE_LOG_DIR}/error.log
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

## Settigns for HTTPS protocol
<VirtualHost *:443>
        SSLEngine on
        ServerAdmin webmaster@localhost
        ServerName drupal

        ## Folder with drupal site
        DocumentRoot /var/www/drupal
        SSLCertificateFile /etc/apache2/ssl/apache.crt
        SSLCertificateKeyFile /etc/apache2/ssl/apache.key
        <Directory />
              Options FollowSymLinks
              AllowOverride All
        </Directory>

        ## Clean URLs for drupal site
        <Directory /var/www/drupal/>
              RewriteEngine On
              RewriteBase /
              RewriteCond %{REQUEST_FILENAME} !-f
              RewriteCond %{REQUEST_FILENAME} !-d
              RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              Allow from all
        </Directory>

        ## File for error logging
        ErrorLog ${APACHE_LOG_DIR}/error.log
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

We should also attend to logging the host into the host configuration file - its default location is here: /etc/hosts. At this point, HTTPS can actually be applied within the Drupal environment. Below, an instance of page readdressing is described /user/%uid/edit на "https://":

/**
 * Implements hook_boot().
 */ 
function example_boot() {
  global $base_root;
  if (isset($_POST)) {
  // If something has been posted to here then ignore the rules.
  return;
  }
  // Redirect all pages from https to http, ignore only user edit profile.
  // Function current_path is not available in hook_boot() so use $_GET['q'] instead.
  if (isset($_GET['q']) && !empty($_GET['q'])) {
    if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != 443) {
      $args = explode('/', $_GET['q']);
      // if URL is user/uid/edit page
      if (!empty($args[0]) && $args[0] == 'user' && !empty($args[2]) && $args[2] == 'edit' && variable_get('action_http') == 1) {
        header('Location: https://' . $_SERVER['HTTP_HOST'] . '/' . $_GET['q']);
        cache_clear_all($base_root . request_uri(), 'cache_page');
        exit();
      }
    }
  }
  // Redirect user edit profile from http to https.
  if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
    $args = explode('/', $_GET['q']);
    if (!(!empty($args[0]) && $args[0] == 'user' && !empty($args[2]) && $args[2] == 'edit')) {
      header('Location: http://' . $_SERVER['HTTP_HOST'] . '/' . $_GET['q']);
      cache_clear_all($base_root . request_uri(), 'cache_page');
      exit();
    }
  }
}

Hence, here was illustrated the instance of redirection to a selected page as supported by the protected HTTPS protocol. By the way of illustrating, the user/%uid/edit  has been selected, as for the rest of them, the standard HTTP protocol is applicable. Thus, the 'occurs check' should designate the exact page the secure protocol redirection should be affected at.

There are ready-to-use modules for SSL interaction in Drupal 6 та 7 like Secure Pages and Ubercart SSL. The former makes it possible to designate the pages at which the redirection will be performed via HTTPS, or else, it will simply let the mentioned protocol be accessible over the whole site (the relevant module can be downloaded from drupal.org, yet its stable version is unreachable). Ubercart SSL offers the similar function, too. Unlike Secure PagesUbercart SSL does not require any patches. 

So, this article has dealt with configuring the settings for Apache and Nginx as performed with support of both HTTP and HTTPS, illustrated the instance of HTTPS security certificates generation, and what is more important, shown implementing of these features in Drupal.

Join the conversation
0 Comments