blob: 6bd2639236ee61b2520a95e63d577632cd7dcb77 [file] [log] [blame]
#!/usr/bin/perl
#
# Copyright 2015 Comcast Cable Communications Management, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use strict;
use lib qw(/opt/traffic_ops/install/lib /opt/traffic_ops/lib/perl5 /opt/traffic_ops/app/lib);
use JSON;
use InstallUtils;
use File::Temp;
use Data::Dumper;
use File::Copy;
my $ca = "/etc/pki/tls/certs/localhost.ca";
my $csr = "/etc/pki/tls/certs/localhost.csr";
my $cert = "/etc/pki/tls/certs/localhost.crt";
my $cdn_conf = "/opt/traffic_ops/app/conf/cdn.conf";
my $key = "/etc/pki/tls/private/localhost.key";
my $msg = << 'EOF';
We're now running a script to generate a self signed X509 SSL certificate.
When prompted to enter a pass phrase, just enter 'pass' each time. The
pass phrase will be stripped from the private key before installation.
When prompted to enter a 'challenge password', just hit the ENTER key.
The remaining enformation Country, State, Locality, etc... are required to
generate a properly formatted SSL certificate.
EOF
sub writeCdn_conf {
my $cdn_conf = shift;
# listen param to be inserted
my $listen_str = "https://[::]:443?cert=${cert}&key=${key}&ca=${ca}&verify=0x00&ciphers=AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH:!ED";
# load as perl hash to find string to be replaced
my $cdnh = do $cdn_conf;
if ( exists $cdnh->{hypnotoad} ) {
$cdnh->{hypnotoad}{listen} = [$listen_str];
}
else {
# add the whole hypnotoad config without affecting anything else in the config
$cdnh->{hypnotoad} = {
listen => [$listen_str],
user => 'trafops',
group => 'trafops',
pid_file => '/var/run/traffic_ops.pid',
workers => 48,
};
}
# dump conf data in compact but readable form
my $dumper = Data::Dumper->new( [$cdnh] );
$dumper->Indent(1)->Terse(1)->Quotekeys(0);
# write whole config to temp file in pwd (keeps in same filesystem)
my $tmpfile = File::Temp->new(DIR => '.');
print $tmpfile $dumper->Dump();
close $tmpfile;
# make backup of current file
my $backup_num = 0;
my $backup_name;
do {
$backup_num++;
$backup_name = "$cdn_conf.backup$backup_num";
} while ( -e $backup_name );
rename( $cdn_conf, $backup_name ) or die("rename(): $!");
# rename temp file to cdn.conf and set ownership/permissions same as backup
my @stats = stat($backup_name);
my ( $uid, $gid, $perm ) = @stats[ 4, 5, 2 ];
move( "$tmpfile", $cdn_conf ) or die("move(): $!");
chown $uid, $gid, $cdn_conf;
chmod $perm, $cdn_conf;
}
InstallUtils::execCommand( "/usr/bin/tput", "clear" );
print $msg;
InstallUtils::promptUser( "Hit Enter when you are ready to continue", "" );
print "Postinstall SSL Certificate Creation.\n\n";
# execOpenssl takes a description of the command being done, and an array of arguments to OpenSSL,
# and tries to execute the command, on failure prompting the user to retry.
# The description should be capitalized, but not terminated with punctuation.
# Returns the OpenSSL exit code.
sub execOpenssl {
my ( $description, @args ) = @_;
print $description . ".\n\n";
my $result = 1;
while ( $result != 0 ) {
$result = InstallUtils::execCommand( "openssl", @args );
if ( $result != 0 ) {
my $ans = "";
while ( $ans !~ /^[yY]/ && $ans !~ /^[nN]/) {
$ans = InstallUtils::promptUser( $description . " failed. Try again (y/n)", "y" );
}
if ( $ans =~ /^[nN]/ ) {
return $result
}
}
}
return $result;
}
if ( execOpenssl( "Generating an RSA Private Server Key", "genrsa", "-des3", "-out", "server.key", "1024" ) != 0 ) {
exit 1;
}
print "\nThe server key has been generated.\n\n";
if ( execOpenssl( "Creating a Certificate Signing Request (CSR)", "req", "-new", "-key", "server.key", "-out", "server.csr" ) != 0 ) {
exit 1;
}
print "\nThe Certificate Signing Request has been generated.\n";
InstallUtils::execCommand( "/bin/mv", "server.key", "server.key.orig" );
if ( execOpenssl( "Removing the pass phrase from the server key", "rsa", "-in", "server.key.orig", "-out", "server.key" ) != 0 ) {
exit 1;
}
print "\nThe pass phrase has been removed from the server key.\n";
if ( execOpenssl( "Generating a Self-signed certificate", "x509", "-req", "-days", "365", "-in", "server.csr", "-signkey", "server.key", "-out", "server.crt" ) != 0 ) {
exit 1;
}
print "\nA server key and self signed certificate has been generated.\n";
print "\nInstalling the server key and server certificate.\n";
my $result = InstallUtils::execCommand( "/bin/cp", "server.key", "$key" );
if ( $result != 0 ) {
print "Failed to install the private server key.\n";
exit 3;
}
$result = InstallUtils::execCommand( "/bin/chmod", "600", "$key" );
$result = InstallUtils::execCommand( "/bin/chown", "trafops:trafops", "$key" );
if ( $result != 0 ) {
print "Failed to install the private server key.\n";
exit 4;
}
print "\nThe private key has been installed.\n";
print "\nInstalling the self signed certificate.\n";
$result = InstallUtils::execCommand( "/bin/cp", "server.crt", "$cert" );
if ( $result != 0 ) {
print "Failed to install the self signed certificate.\n";
exit 5;
}
$result = InstallUtils::execCommand( "/bin/chmod", "600", "$cert" );
$result = InstallUtils::execCommand( "/bin/chown", "trafops:trafops", "$cert" );
if ( $result != 0 ) {
print "Failed to install the self signed certificate.\n";
exit 6;
}
print "\nSaving the self signed csr.\n";
$result = InstallUtils::execCommand( "/bin/cp", "server.csr", "$csr" );
if ( $result != 0 ) {
print "Failed to save the self signed csr.\n";
exit 7;
}
$result = InstallUtils::execCommand( "/bin/chmod", "664", "$csr" );
$result = InstallUtils::execCommand( "/bin/chown", "trafops:trafops", "$csr" );
writeCdn_conf($cdn_conf);
my $msg = << 'EOF';
The self signed certificate has now been installed.
You may obtain a certificate signed by a Certificate Authority using the
server.csr file saved in the current directory. Once you have obtained
a signed certificate, copy it to /etc/pki/tls/certs/localhost.crt and
restart Traffic Ops.
EOF
print $msg, "\n";
exit 0;