Generate random root password during installation, encrypt and send by mail

From FAIWiki
Jump to navigation Jump to search

Motivation

Your security policy may demand to implement random root passwords on your servers. Here we provide a script to accomplish that in a reasonable secure and convenient way with FAI.

Implementation

We have adapted a script of Michal Svamberg to send the encrypted root password by email:

#!/usr/bin/perl
# BEGIN LICENCE BLOCK
#
# Copyright (C) 2004 Michal Svamberg <svamberg_at_civ.zcu.cz>
#               2006 Thomas Gebhardt <gebhardt_at_hrz.uni-marburg.de>
#               2007 Andreas Gabriel <gabriel_at_hrz.uni-marburg.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
# END LICENCE BLOCK

use strict;
use Env qw(FAI_ROOT FAI_ACTION ROOTCMD GNUPGHOME);
use String::Random;
use Crypt::GPG;
use Mail::Sender;


# ---------------------------------- START:CONF ---
my @SEND_TO = (
        'John.Doe@example.com', 'Jane.Foo@example.com'
);

my $SEND_FROM   = 'fai@example.com';
my $SMTP_SERVER = "smtp.example.com";
my $GPG_KEY_ID  = "0x.. your gpg key id goes here";

$GNUPGHOME = "$FAI_ROOT/etc/fai/gnupg";   # no "my" here! (tied to ENV variable)


# ---------------------------------- END:CONF ---

# ---------------------------------------------------------------- send_mail ---
sub send_mail {

        my ( $encrypted ) = @_;

        foreach my $admin (@SEND_TO) {


          
          # make mail
          my $sender = new Mail::Sender({
                                         #debug => "/tmp/smtp.txt",
                                         smtp => $SMTP_SERVER,
                                         from => $SEND_FROM
                                        });

          
          $sender->OpenMultipart({
                                  to => $admin,
                                  subject => "FAI: Random root password for " .`hostname`,
                                  multipart => "encrypted;\nprotocol=\"application/pgp-encrypted\"",
                                  boundary => '--------------rootpwIUZODMVABJDLBHFVEEEVJF',
                                 })

            ->Part({ ctype => 'application/pgp-encrypted',
                     description => 'PGP/MIME version identification',
                     disposition => 'NONE',
                     msg =>"Version: 1\n"})
              ->Part({
                        description => 'OpenPGP encrypted message',
                        ctype => 'application/octet-stream; name="encrypted.asc"',
                        encoding => '7BIT',
                        disposition => 'inline; filename="encrypted.asc"',
                        msg => "$encrypted\n"
                       })
                ->Close() or die "Cannot send mail: $Mail::Sender::Error\n";
        }

        return 0;
}

# ==============================================================================

exit unless ($FAI_ACTION eq 'install');

my $rand = new String::Random;
my $rootpw = $rand->randregex('\w\w\w\w\w\w\w\w');  # 8 random printable characters
system ("/bin/echo \"root:$rootpw\" | $ROOTCMD chpasswd --md5");

$rootpw .= "\n";

my $gpg = new Crypt::GPG;
$gpg->gpgopts("--armor");

#pack the new pw into an mime entity
my $entity = << '*END*';
Content-Type: text/plain
Content-Disposition: inline
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0

*END*

$entity .= "$rootpw\n" ;


my $encrypted = $gpg->encrypt ($entity, $GPG_KEY_ID);

print "Send encrypted root password via SMTP to " .(join ', ', @SEND_TO) ."\n";

# send emails
send_mail($encrypted);

exit 0;

The perl modules String::Random, Crypt::GPG, and Mail::Sender, that are used by that script, have to be installed on the NFSROOT file system on the install server. GPG is used to encrypt the randomly choosen root password. A gpg key pair has to be generated beforehand. Copy all the files from your gpg home directory to /etc/fai/gnupg/ on the NFSROOT file system, but be shure to omit the secret keyring. For encrypting of the root password we use the same gpg key pair as for encrypting sensitive information on the install server.