From c5911bdb40fb4b91810ab13a48c0ae5681435b51 Mon Sep 17 00:00:00 2001 From: Dimitris Kamenopoulos Date: Sun, 27 Dec 2015 16:01:43 +1300 Subject: [PATCH] Bug 15427 : Enable TLS support for MySQL 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 , , and are added in koha-conf.xml 2) If yes 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 --- C4/Installer.pm | 12 +++++++++++- Koha/Database.pm | 12 +++++++++++- Makefile.PL | 26 ++++++++++++++++++++++++++ etc/koha-conf.xml | 4 ++++ installer/install.pl | 15 +++++++++++++-- rewrite-config.PL | 6 +++++- 6 files changed, 70 insertions(+), 5 deletions(-) diff --git a/C4/Installer.pm b/C4/Installer.pm index 5fe2e16..615e657 100644 --- a/C4/Installer.pm +++ b/C4/Installer.pm @@ -69,8 +69,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; @@ -446,6 +455,7 @@ sub load_sql { . ( $self->{port} ? " -P $self->{port} " : "" ) . ( $self->{user} ? " -u $self->{user} " : "" ) . ( $self->{password} ? " -p'$self->{password}'" : "" ) + . ( $self->{tlscmdline} ? $self->{tlscmdline} : "" ) . " $self->{dbname} "; $error = qx($strcmd --default-character-set=utf8 <$filename 2>&1 1>/dev/null); } elsif ( $self->{dbms} eq 'Pg' ) { diff --git a/Koha/Database.pm b/Koha/Database.pm index 82d831f..17d8a0e 100644 --- a/Koha/Database.pm +++ b/Koha/Database.pm @@ -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, diff --git a/Makefile.PL b/Makefile.PL index 96d2fb7..f98dadb 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -420,6 +420,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', @@ -465,6 +469,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 }, @@ -900,6 +905,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 diff --git a/etc/koha-conf.xml b/etc/koha-conf.xml index 74a5720..a29ceff 100644 --- a/etc/koha-conf.xml +++ b/etc/koha-conf.xml @@ -82,6 +82,10 @@ __PAZPAR2_TOGGLE_XML_POST__ __DB_PORT__ __DB_USER__ __DB_PASS__ + __DB_USE_TLS__ + __DB_TLS_CA_CERTIFICATE__ + __DB_TLS_CLIENT_CERTIFICATE__ + __DB_TLS_CLIENT_KEY__ biblios 1 authorities diff --git a/installer/install.pl b/installer/install.pl index cc67557..7128111 100755 --- a/installer/install.pl +++ b/installer/install.pl @@ -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'} ); @@ -368,7 +378,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; diff --git a/rewrite-config.PL b/rewrite-config.PL index 91f74cb..636b313 100644 --- a/rewrite-config.PL +++ b/rewrite-config.PL @@ -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, -- 2.6.4