Print this page

News

2012-05-02 11:43:12

5107R & 5108R more SSL certificate issues


Fixing the remaining SSL certificate handling issues on BlueOnyx 5107R and 5108R.

Category: Development
Posted by: mstauber

In a recent devel blog entry I had already summarized the work that had been done to address the problems with SSL certificates that we have had on BlueOnyx 5107R and 5108R.

The work done there was already a good step into the right direction. The import of SSL certificates seemed to work fine and additionally the weird redirect issue that we did run into on SSL enabled sites was also tackled. So it seemed.

But there were some remaining issues that eventually got mentioned on the BlueOnyx mailing list:

  • If you have more than one site with SSL enabled, only the last site works.
  • Inability to import intermediate certificates through the GUI.

The first item had me a bit puzzled, but Randy Smith had the right idea that set me off onto the right track.

Our Apache Vhost containers contain several Rewrite conditions. The actual rewrite conditions differ a little depending on if you have "Web alias redirects (to main site)" enabled or not. For non-SSL sites this works fine. When you enable SSL for a site, a Perl script located at /etc/httpd/conf.d/ssl_perl.conf uses the Perl module "Apache2::PerlSections" to dynamically create Apache Vhost containers for all SSL enabled virtual sites and populates them with all the information from the regular non-SSL Vhost container and everything you need for SSL.

This used to work fine on 5106R, but there the older Apache made it necessary to use the older "Apache::PerlSections" instead.

The problem here is that "Apache2::PerlSections" is not 1:1 compatible to the older "Apache::PerlSections".  In fact
"Apache2::PerlSections" has problems with hashes that have the same keys and it doesn't keep the sort order of hashes or arrays.

So when we read in the Apache config, we end up with a generated output that has the lines from the config all over the place and not in the right sort order. Which is fine for most of the config items, but NOT for the Rewrite lines.

Typically our Rewrite lines would look like this:

RewriteEngine on
RewriteCond %{HTTP_HOST}                !^192.168.8.129(:80)?$
RewriteCond %{HTTP_HOST}                !^www.site.com(:80)?$ [NC]
RewriteRule ^/(.*)                      http://www.site.com/$1 [L,R=301]
RewriteOptions inherit

But our /etc/httpd/conf.d/ssl_perl.conf would jumble it to something like this if multiple sites have SSL enabled:

RewriteRule ^/(.*)                      http://www.site.com/$1 [L,R=301]
RewriteEngine on
RewriteOptions inherit
RewriteCond %{HTTP_HOST}                !^192.168.8.129(:80)?$
RewriteCond %{HTTP_HOST}                !^www.site.com(:80)?$ [NC]

You can see how that's not going to work, right?

The fix is to use  the "Tie::DxHash" Perl module from CPAN. Tie::DxHash - keeps insertion order; allows duplicate keys [...] This module was written to allow the use of rewrite rules in Apache configuration files written with Perl Sections.

This then did lead to a more or less detailed rewrite of /etc/httpd/conf.d/ssl_perl.conf. The coding of it was a bit of a challenge and I think at one time I had like 20 browser pages open where I was looking up information about coding examples (there are few and far in between for "Tie::DxHash") or Perl or Apache related stuff that I wasn't really entirely sure about. After starting over three or four times from scratch I eventually got some heavily bloated code assembled that started to work. It was nitpicking small stuff that complicated things. Like having to code using Strict, joining hashes in the right order, using Tie::DxHash which was alien to me and finally the small problem of turning the data from the vsite Vhost container into tied hash.

Like said, the initial code was rather bloated. I think at one time I even manually assembled the Vhost container by parsing the CODB data of the Vsite(s) and assembling them one line at a time - covering all the eventialities of enabled or disabled features.

But then I fell back to simply parsing the siteX Apache config files in question, dropping comments and unwanted lines and pushed them into an Array after fixing some of them up with search and replace. From there it was just one line to turn that Array into a Hash. Of course a Hash needs keys (which the array did not have), so I simply used split to split up each line in the array after the first whitespace to use the first element as the key and the second element as the value:

    # Turn array into a hash:
    %dir_spec = map { split(/\s+/, $_, 2) } @ssl_conf;

The beauty here is that a hash protected with "Tie::DxHash" doesn't mind the duplicate keys and we now have plenty of duplicates. And the stuff now stays in the Hash in the right sort order. The dynamically generated SSL related Vhost container for a Vsite then looks like this:

$VAR4 = {
          'SSLEngine' => 'on',
          'SSLCertificateFile' => '/home/.sites/106/site3/certs/certificate',
          'SSLCertificateKeyFile' => '/home/.sites/106/site3/certs/key',
          'ServerRoot' => '/etc/httpd',
          'ServerName' => 'www.site.com',
          'ServerAlias' => 'site.com',
          'ServerAdmin' => 'admin',
          'DocumentRoot' => '/home/.sites/106/site3/web',
          'ErrorDocument' => '401 /error/401-authorization.html',
          'ErrorDocument' => '403 /error/403-forbidden.html',
          'ErrorDocument' => '404 /error/404-file-not-found.html',
          'ErrorDocument' => '500 /error/500-internal-server-error.html',
          'RewriteEngine' => 'on',
          'RewriteCond' => '%{HTTP_HOST}                !^192.168.8.129(:443)?$',
          'RewriteCond' => '%{HTTP_HOST}                !^www.site.com(:443)?$ [NC]',
          'RewriteRule' => '^/(.*)                      https://www.site.com:443/$1 [L,R=301]',
          'RewriteOptions' => 'inherit',
          'Include' => '/etc/httpd/conf/vhosts/site3.include',
          'AddHandler' => 'cgi-wrapper .cgi',
          'AddHandler' => 'cgi-wrapper .pl',
          'AddHandler' => 'server-parsed .shtml',
          'AddType' => 'text/html .shtml',
          'suPHP_Engine' => 'on',
          'suPHP_ConfigPath' => '/home/sites/www.site.com',
          'suPHP_AddHandler' => 'x-httpd-suphp',
          'AddHandler' => 'x-httpd-suphp .php',
          'php_admin_flag' => 'register_globals Off',
          'php_admin_flag' => 'allow_url_fopen Off',
          'php_admin_flag' => 'allow_url_include Off',
          'php_admin_value' => 'open_basedir /var/lib/php/session/:/var/:/hello/:/usr/sausalito/configs/php/:/tmp/:/home/.sites/106/site3/',
          'php_admin_value' => 'post_max_size 8M',
          'php_admin_value' => 'upload_max_filesize 5M',
          'php_admin_value' => 'max_execution_time 30',
          'php_admin_value' => 'max_input_time 60',
          'php_admin_value' => 'memory_limit 64M',
          'php_admin_flag' => 'mail.add_x_header On',
          'php_admin_value' => 'sendmail_path /usr/sausalito/sbin/phpsendmail',
          'php_admin_value' => 'auto_prepend_file /usr/sausalito/configs/php/set_php_headers.php'
        };

Well, this is of course not the container itself, but the "meat" of it. The contends of the Hash before it is written off to Apache inside a matching <VirtualHost> container. But you get the idea.

The code for that is now in SVN.

Lastly, there was the problem with uploading intermediate SSL certificates through the GUI. That was rather trivial to fix.

Both updates have been submitted to the [BlueOnyx-Testing] YUM repository for release sometime tonight.

All in all I'm pleased that this is finally fixed, so SSL enabled sites are no longer a problem on BlueOnyx 5107R and 5108R.


Previous page: API Documentation
Next page: Downloads