| 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 |
|