Bug 15427 : Enable TLS support for MySQL
authorDimitris Kamenopoulos <dkamen@gmail.com>
Sun, 27 Dec 2015 03:01:43 +0000 (16:01 +1300)
committerKyle M Hall <kyle@bywatersolutions.com>
Fri, 3 Mar 2017 18:33:07 +0000 (18:33 +0000)
In summary, changes are:
1) If you have chosen MySQL, Makefile.PL will ask you if you want TLS (default:
"no"), and then the locations for CA cert, client cert and client key
(reasonable defaults are provided). Settings <tls>, <ca>, <cert> and <key> are
added in koha-conf.xml
2) If <tls>yes</tls> in koha-conf.xml, the installer and database connection
scripts add the TLS options in both DBI connection strings and mysql command
line

To test
1/ Apply patch
2/ Check everything still works and db connections are the same as before
3/ Either run Makefile.PL and step through the options or edit your koha-conf.xml to
enable TLS
4/ Check db connections are still working

Patch provided to me by Dimitris Kamenopoulos and I reformatted it into a git patch,
any errors are probably mine

Signed-off-by: Mirko Tietgen <mirko@abunchofthings.net>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

C4/Installer.pm
Koha/Database.pm
Makefile.PL
etc/koha-conf.xml
installer/install.pl
rewrite-config.PL

index bd1b150..e8692a1 100644 (file)
@@ -75,8 +75,17 @@ sub new {
     $self->{'port'}     = C4::Context->config("port");
     $self->{'user'}     = C4::Context->config("user");
     $self->{'password'} = C4::Context->config("pass");
+    $self->{'tls'} = C4::Context->config("tls");
+    if ($self->{'tls'} eq 'yes'){
+        $self->{'ca'} = C4::Context->config('ca');
+        $self->{'cert'} = C4::Context->config('cert');
+        $self->{'key'} = C4::Context->config('key');
+        $self->{'tlsoptions'} = ";mysql_ssl=1;mysql_ssl_client_key=".$self->{key}.";mysql_ssl_client_cert=".$self->{cert}.";mysql_ssl_ca_file=".$self->{ca};
+        $self->{'tlscmdline'} =  " --ssl-cert ". $self->{cert} . " --ssl-key " . $self->{key} . " --ssl-ca ".$self->{ca}." "
+    }
     $self->{'dbh'} = DBI->connect("DBI:$self->{dbms}:dbname=$self->{dbname};host=$self->{hostname}" .
-                                  ( $self->{port} ? ";port=$self->{port}" : "" ),
+                                  ( $self->{port} ? ";port=$self->{port}" : "" ).
+                                  ( $self->{tlsoptions} ? $self->{tlsoptions} : ""),
                                   $self->{'user'}, $self->{'password'});
     $self->{'language'} = undef;
     $self->{'marcflavour'} = undef;
@@ -454,7 +463,6 @@ sub load_sql {
     if( $dup_stderr ) {
         warn "C4::Installer::load_sql returned the following errors while attempting to load $filename:\n";
         $error = $dup_stderr;
-
     }
 
     return $error;
index 6f72559..c5b2b73 100644 (file)
@@ -58,6 +58,16 @@ sub _new_schema {
     my $db_port   = $context->config("port") || '';
     my $db_user   = $context->config("user");
     my $db_passwd = $context->config("pass");
+    my $tls = $context->config("tls");
+    my $tls_options;
+    if ($tls eq 'yes'){
+        my $ca = $context->config('ca');
+        my $cert = $context->config('cert');
+        my $key = $context->config('key');
+        $tls_options = ";mysql_ssl=1;mysql_ssl_client_key=".$key.";mysql_ssl_client_cert=".$cert.";mysql_ssl_ca_file=".$ca;
+    }
+
+
 
     my ( %encoding_attr, $encoding_query, $tz_query );
     my $tz = $ENV{TZ};
@@ -72,7 +82,7 @@ sub _new_schema {
     }
     my $schema = Koha::Schema->connect(
         {
-            dsn => "dbi:$db_driver:database=$db_name;host=$db_host;port=$db_port",
+            dsn => "dbi:$db_driver:database=$db_name;host=$db_host;port=$db_port".($tls_options? $tls_options : ""),
             user => $db_user,
             password => $db_passwd,
             %encoding_attr,
index 594b691..b9b4918 100644 (file)
@@ -456,6 +456,10 @@ my %config_defaults = (
   'DB_NAME'           => 'koha',
   'DB_USER'           => 'kohaadmin',
   'DB_PASS'           => 'katikoan',
+  'DB_USE_TLS'       => 'no',
+  'DB_TLS_CA_CERTIFICATE'  => '/etc/mysql-ssl/server-ca.pem',
+  'DB_TLS_CLIENT_CERTIFICATE'  => '/etc/mysql-ssl/client-cert.pem',
+  'DB_TLS_CLIENT_KEY' => '/etc/mysql-ssl/client-key.pem',
   'INSTALL_SRU'       => 'yes',
   'INSTALL_PAZPAR2'   => 'no',
   'AUTH_INDEX_MODE'   => 'dom',
@@ -502,6 +506,7 @@ else {
 my %valid_config_values = (
   'INSTALL_MODE'  => { 'standard' => 1, 'single' => 1, 'dev' => 1 },
   'DB_TYPE' => { 'mysql' => 1, 'Pg' => 1 },
+  'DB_USE_TLS' => {'yes', 'no'},
   'INSTALL_SRU' => { 'yes' => 1, 'no' => 1 },
   'AUTH_INDEX_MODE' => { 'grs1' => 1, 'dom' => 1 },
   'BIB_INDEX_MODE'  => { 'grs1' => 1, 'dom' => 1 },
@@ -1032,6 +1037,27 @@ DMBS);
 Please specify the name of the database to be
 used by Koha);
     $config{'DB_NAME'} = _get_value('DB_NAME', $msg, $defaults->{'DB_NAME'}, $valid_values, $install_log_values);
+    if ($config{'DB_TYPE'} eq 'mysql'){
+        $msg = q(
+Please specify whether the connection to MySQL will use TLS
+        );
+        $config{'DB_USE_TLS'} = _get_value('DB_USE_TLS', $msg, $defaults->{'DB_USE_TLS'}, $valid_values, $install_log_values);
+    }
+    if ($config{'DB_USE_TLS'} eq 'yes'){
+        $msg = q(
+Please enter the path to the CA certificate for TLS
+        );
+        $config{'DB_TLS_CA_CERTIFICATE'} = _get_value('DB_TLS_CA_CERTIFICATE', $msg, $defaults->{'DB_TLS_CA_CERTIFICATE'}, $valid_values, $install_log_values);
+
+        $msg = q(
+Please enter the path to the client certificate for TLS
+        );
+        $config{'DB_TLS_CLIENT_CERTIFICATE'} = _get_value('DB_TLS_CLIENT_CERTIFICATE', $msg, $defaults->{'DB_TLS_CLIENT_CERTIFICATE'}, $valid_values, $install_log_values);
+        $msg = q(
+Please enter the path to the client key for TLS
+        );
+        $config{'DB_TLS_CLIENT_KEY'} = _get_value('DB_TLS_CLIENT_KEY', $msg, $defaults->{'DB_TLS_CLIENT_KEY'}, $valid_values, $install_log_values);
+    }
 
     $msg = q(
 Please specify the user that owns the database to be
index 1e5c799..4ccee3a 100644 (file)
@@ -82,6 +82,10 @@ __PAZPAR2_TOGGLE_XML_POST__
  <port>__DB_PORT__</port>
  <user>__DB_USER__</user>
  <pass>__DB_PASS__</pass>
+ <tls>__DB_USE_TLS__</tls>
+ <ca>__DB_TLS_CA_CERTIFICATE__</ca>
+ <cert>__DB_TLS_CLIENT_CERTIFICATE__</cert>
+ <key>__DB_TLS_CLIENT_KEY__</key>
  <biblioserver>biblios</biblioserver>
  <biblioservershadow>1</biblioservershadow>
  <authorityserver>authorities</authorityserver>
index 10b6422..fdeef0c 100755 (executable)
@@ -48,9 +48,19 @@ $info{'hostname'} = C4::Context->config("hostname");
 $info{'port'}     = C4::Context->config("port");
 $info{'user'}     = C4::Context->config("user");
 $info{'password'} = C4::Context->config("pass");
+$info{'tls'} = C4::Context->config("tls");
+    if ($info{'tls'} eq 'yes'){
+        $info{'ca'} = C4::Context->config('ca');
+        $info{'cert'} = C4::Context->config('cert');
+        $info{'key'} = C4::Context->config('key');
+        $info{'tlsoptions'} = ";mysql_ssl=1;mysql_ssl_client_key=".$info{key}.";mysql_ssl_client_cert=".$info{cert}.";mysql_ssl_ca_file=".$info{ca};
+        $info{'tlscmdline'} =  " --ssl-cert ". $info{cert} . " --ssl-key " . $info{key} . " --ssl-ca ".$info{ca}." "
+    }
+
 my $dbh = DBI->connect(
     "DBI:$info{dbms}:dbname=$info{dbname};host=$info{hostname}"
-      . ( $info{port} ? ";port=$info{port}" : "" ),
+      . ( $info{port} ? ";port=$info{port}" : "" )
+      . ( $info{tlsoptions} ? $info{tlsoptions} : "" ),
     $info{'user'}, $info{'password'}
 );
 
@@ -370,7 +380,8 @@ elsif ( $step && $step == 3 ) {
         #I put it there because it implied a data import if condition was not satisfied.
         my $dbh = DBI->connect(
                "DBI:$info{dbms}:dbname=$info{dbname};host=$info{hostname}"
-               . ( $info{port} ? ";port=$info{port}" : "" ),
+               . ( $info{port} ? ";port=$info{port}" : "" )
+                . ( $info{tlsoptions} ? $info{tlsoptions} : "" ),
                $info{'user'}, $info{'password'}
         );
        my $rq;
index a66b119..d827106 100644 (file)
@@ -44,7 +44,7 @@ The following configuration keywords are available:
 
 PREFIX,
 BASE_DIR, CGI_DIR, LOG_DIR, PLUGINS_DIR, INSTALL_BASE,
-DB_TYPE, DB_HOST, DB_PORT, DB_NAME, DB_PASS, DB_USER, WEBMASTER_EMAIL, WEBSERVER_DOMAIN,
+DB_TYPE, DB_HOST, DB_PORT, DB_NAME, DB_PASS, DB_USER, DB_USE_TLS, DB_TLS_CA_CERT, DB_TLS_CLIENT_KEY, DB_TLS_CLIENT_CERT, WEBMASTER_EMAIL, WEBSERVER_DOMAIN,
 WEBSERVER_HOST, WEBSERVER_IP, WEBSERVER_PORT, WEBSERVER_PORT_LIBRARIAN, ZEBRA_PASS, ZEBRA_USER
 
 =head1 EXAMPLES
@@ -89,6 +89,10 @@ $prefix = $ENV{'INSTALL_BASE'} || "/usr";
   "__DB_PORT__" => "3306",
   "__DB_USER__" => "kohaadmin",
   "__DB_PASS__" => "katikoan",
+  "__DB_USE_TLS__" => "no",
+  "__DB_TLS_CA_CERTIFICATE__" => "",
+  "__DB_TLS_CLIENT_CERTIFICATE__" => "",
+  "__DB_TLS_CLIENT_KEY__"=>"",
   "__WEBMASTER_EMAIL__" => 'webmaster@'.$mydomain,
   "__WEBSERVER_DOMAIN__" => $mydomain,
   "__WEBSERVER_HOST__" => $myhost,