Subversion Repositories zfs_utils

Rev

Rev 18 | Rev 21 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 18 Rev 20
Line 43... Line 43...
43
 
43
 
44
 
44
 
45
# this calls gshred which will overwrite the file 3 times, then
45
# this calls gshred which will overwrite the file 3 times, then
46
# remove it.
46
# remove it.
47
# NOTE: this will not work on ZFS, since ZFS is CopyOnWrite (COW)
47
# NOTE: this will not work on ZFS, since ZFS is CopyOnWrite (COW)
48
# so assuming /tmp is a ramdisk
48
# so assuming file is on a ramdisk
49
sub shredFile {
49
sub shredFile {
50
   my $filename = shift;
50
   my $filename = shift;
51
   `/usr/local/bin/gshred -u -f -s 32 $filename`;
51
   `/usr/local/bin/gshred -u -f -s 32 $filename`;
52
}
52
}
53
 
53
 
Line 67... Line 67...
67
   } else {
67
   } else {
68
      return ( $?>>8, sprintf "child exited with value %d", $? >> 8 ) if $? >> 8;
68
      return ( $?>>8, sprintf "child exited with value %d", $? >> 8 ) if $? >> 8;
69
   }
69
   }
70
   return (0, $output);
70
   return (0, $output);
71
}
71
}
72
   
72
 
73
# grabs the encryption key from the remote server, and uses it to unlock the 
73
# Checks if a zpool is available. If not, retrieves the geli key from a remote server,
74
# datasets, then mount the drives.
74
# decrypts the drives, and mounts the zpool.
-
 
75
# Params:
-
 
76
#   $zpool         - Name of the zpool
-
 
77
#   $local_key     - Local path to store the geli key
-
 
78
#   $remote_server - Remote server to fetch the key from (user@host)
75
# a return of '' is success, anything else is an error
79
#   $remote_key    - Path to the geli key on the remote server
-
 
80
#   $drives_ref    - Arrayref of drives to decrypt (e.g., ['/dev/ada0p3', '/dev/ada1p3'])
76
sub mountDrives {
81
sub mountGeliZpool {
-
 
82
    my ($zpool, $local_key, $remote_server, $remote_key, $drives_ref) = @_;
-
 
83
 
77
   my $configuration = shift;
84
    # Check if the zpool is available
78
   return (0, 'No encrypted target found' ) unless defined( $configuration->{'target'}->{'encryptionKeyPath'} ) && $configuration->{'target'}->{'encryptionKeyPath'};
85
    my ($error, $output) = runCommand("zpool list $zpool");
-
 
86
    return 0 unless $error; # zpool is available
-
 
87
 
79
   # try to grab the file from the remote machine
88
    # Retrieve geli key from remote server
-
 
89
    ($error, $output) = runCommand("scp $remote_server:$remote_key $local_key");
80
   &runCommand( "scp $configuration->{remoteMachine}->{ip}:$configuration->{remoteMachine}->{encryptionKeyPath} $configuration->{localMachine}->{encryptionKeyPath}" );
90
    return ($error, "Failed to retrieve geli key from $remote_server:$remote_key" ) if $error;
-
 
91
 
81
   # If we do not have the encryption key, we need to abort
92
    # Attach geli key to each drive
-
 
93
    foreach my $drive (@$drives_ref) {
82
   return "Could not copy file $configuration->{remoteMachine}->{ip}:$configuration->{remoteMachine}->{encryptionKeyPath}, aborting" 
94
        ($error, $output) = runCommand("geli attach -k $local_key $drive");
83
      unless -f $configuration->{'target'}->{'encryptionKeyPath'};
95
         return ($error, "Failed to attach geli key to $drive: $output" ) if $error;
84
   my $error = '';
96
    }
-
 
97
 
85
   my $output = '';
98
    # Import the zpool
86
   # load the key into zfs and unlock all volumes
99
    ($error, $output) = runCommand("zpool import $zpool");
87
   ($error,$output) = &runCommand( "zfs load-key -a" );
100
    return ( $error, "Failed to import zpool $zpool: $output" ) if $error;
-
 
101
 
88
   # finally, remount all of the zfs shares which need the key
102
    # Optionally, mount all datasets in the zpool
89
   ($error,$output) = &runCommand( "zfs mount -a" ) unless $error;
103
    ($error, $output) = runCommand("zfs mount -a");
-
 
104
     return( $error,"Failed to mount datasets in zpool $zpool: $output" ) if $error;
-
 
105
 
90
   # if we succeeded, we want to shred the keyfile
106
    # Shred the key file after use
91
   &shredFile( $configuration->{localMachine}->{encryptionKeyPath} ) if -f $configuration->{localMachine}->{encryptionKeyPath};
107
    shredFile($local_key) if -f $local_key;
-
 
108
 
92
   return $error;
109
    return 1;
93
}
110
}
94
 
111
 
95
# a very simple mailer, just send information to sendmail
112
# a very simple mailer, just send information to sendmail
96
sub sendMail {
113
sub sendMail {
97
   my ($message, $configuration, $subject ) = @_;
114
   my ($message, $configuration, $subject ) = @_;
Line 214... Line 231...
214
 
231
 
215
# check for maintenance flags, exit if we should go into mainteance mode
232
# check for maintenance flags, exit if we should go into mainteance mode
216
if ( my $result = &checkMaintenance( $configuration ) ) {
233
if ( my $result = &checkMaintenance( $configuration ) ) {
217
   push @status,$result;
234
   push @status,$result;
218
   &sendMail( join( "\n", @status), $configuration, "Maintenance Mode" );
235
   &sendMail( join( "\n", @status), $configuration, "Maintenance Mode" );
219
   die;
236
   exit 1;
220
}
237
}
221
 
238
 
222
# try to mount the datasets if they are encrypted
239
# if the zpool is encrypted with geli, make sure it is available
223
($error,$output) = &mountDrives( $configuration );
240
($error, $output) = &mountGeliZpool {(
-
 
241
   $configuration->{'geli'}->{'zpool'},
-
 
242
   $configuration->{'geli'}->{'localKey'},
-
 
243
   $configuration->{'geli'}->{'server'},
-
 
244
   $configuration->{'geli'}->{'remoteKey'},
-
 
245
   split( ' ', $configuration->{'geli'}->{'drives'} ) )
-
 
246
   if exists ( $configuration->{'geli'} );
-
 
247
   
224
if ( $error ) { # could not mount datasets
248
if ( $error) { # could not mount datasets
225
   push @status, $output;
249
   push @status, $output;
226
   &sendMail( join( "\n", @status ), $configuration, "Mount Drive Error: [$output]" );
250
   &sendMail( join( "\n", @status ), $configuration, "Mount Drive Error: [$output]" );
227
   &shutdownMachine( $configuration );
251
   &shutdownMachine( $configuration );
228
}
252
}
229
 
253