Open Source im professionellen Einsatz

Statisches Perl

Nutzt ein Perl-Skript CPAN-Module, läuft es nicht auf Anhieb auf einer Fremdumgebung wie im Fall der Clonezilla-Distribution. Das CPAN hält zur Abhilfe aber einige Lösungen zur Bündelung von Modul-Sets und Skripten parat, zum Beispiel »PAR« [5]. Kürzlich kam mit »App::staticperl« ein weiteres Framework hinzu. Es kompiliert erstaunlich kompakte, statische, von der Laufzeitumgebung relativ unabhängige Perl-Executables, die die verwendeten CPAN-Module bereits enthalten.

Listing 1 zeigt das Shellkommando, das aus dem Perl-Skript »run-me« das Executable »run-me-clonezilla« erzeugt. Das Tool filzt die verwendeten CPAN-Module nach Abhängigkeiten und fügt sie hinzu. Beim Erkennen der im Applikationsskript benutzten Module hapert es, der Entwickler muss sie rausfieseln und mit »-M« -Optionen manuell angeben.

Listing 1

build.sh

1 staticperl mkapp run-me-clonezilla --boot \
2  run-me -MFile::Basename -MFile::Temp \
3  -MFile::Glob -MSysadm::Install \
4  -MLog::Log4perl \
5  -MLog::Log4perl::Appender::Screen

Gleiches gilt für dynamisch geladene Module. So holt Log::Log4perl zum Beispiel zur Laufzeit ein Modul mit dem Screen-Appender, sobald seine Konfiguration dies verlangt. App::staticperl kann dies durch rein statische Analyse allein unmöglich herausfinden und benötigt deswegen manuelle Unterstützung. Außerdem verlangt Staticperl, dass der User alle später einkompilierten Module mit dem Aufruf »staticperl instcpan [Modulname]« über eine CPAN-Shell in Staticperls lokalem Repository installiert.

Die CD als Schlüssel

Zur passwortlosen Authentisierung auf dem Backupserver enthält das Skript einen Private Key ohne Passphrase, den »ssh-keygen -t rsa« in einer Datei »id_rsa« generiert hat. Ab Zeile 137 steht ein Here-Document mit allen Zeilen des Private Key (in Listing 2 aus Sicherheitsgründen ausge-xt). Der zugehörige Public Key (in »id_rsa.pub« ) wandert in die Datei »~/.ssh/authorized_keys« auf dem Server unter der User-ID des Backup-Users. Wer also die CD (oder das ISO-Image) in Händen hält, besitzt den Schlüssel zum Backupserver und braucht weder Passwort noch Passphrase.

Beim ersten Verbinden mit dem Server von der Kommandozeile fragt »ssh« , ob dies der richtige Host ist, und fügt dessen Signatur in die Datei »~/.ssh/known_hosts« ein. Der Eintrag wandert ab Zeile 130 in das Here-Document im Perl-Skript, damit die automatische Verbindungsaufnahme später keine Bestätigung fordert.

Listing 2

run-me

001 #!/usr/local/bin/perl -w
002 use strict;
003 use File::Temp qw( tempfile );
004 use File::Basename;
005 use Log::Log4perl qw(:easy);
006 use Sysadm::Install qw( :all );
007
008 Log::Log4perl->easy_init($DEBUG);
009
010 my $ip      = "192.168.0.111";
011 my $user    = "mschilli";
012 my $mnt_dir = "/home/partimag";
013
014 if( ! -d $mnt_dir ) {
015   mkdir $mnt_dir;
016 }
017
018 network();
019 mount();
020 backup_all();
021 unmount();
022
023 1;
024
025 ###########################################
026 sub network {
027 ###########################################
028   sysrun "sudo", "dhclient", "eth0";
029 }
030
031 ###########################################
032 sub unmount {
033 ###########################################
034   sysrun "fusermount", "-u", $mnt_dir;
035 }
036
037 ###########################################
038 sub mount {
039 ###########################################
040   DEBUG "Writing private key";
041   my $privkey_file = (tempfile())[1];
042   blurt privkey(), $privkey_file;
043
044   DEBUG "Writing known hosts";
045   my $kh_file = (tempfile())[1];
046   blurt known_hosts(), $kh_file;
047
048   my $rc = sysrun( "sudo", "sshfs",
049     "$user\@$ip:/backup/clonezilla",
050     $mnt_dir, "-o",
051     "ssh_command=ssh -i $privkey_file " .
052     "-o BatchMode=yes " .
053     "-o GlobalKnownHostsFile=$kh_file" );
054
055   if( $rc ) {
056     die "sshfs failed (backup host down?)";
057   }
058 }
059
060 ###########################################
061 sub backup_all {
062 ###########################################
063   my $last_backup_path =
064     ( reverse sort <$mnt_dir/[0-9]*> )[0];
065
066   my $continue_with;
067
068   my @drives = < /dev/sda[0-9]* >;
069
070   if( defined $last_backup_path and
071       ! -f "$last_backup_path/DONE" ) {
072     $continue_with = (
073       sort { -M $a <=> -M $b }
074       < $last_backup_path/*gz* > )[0];
075     $continue_with =
076       basename $continue_with;
077     $continue_with =~ s/\..*//;
078     DEBUG "Continue: $continue_with";
079   }
080
081   my $not_yet;
082
083   if( defined $continue_with ) {
084     $not_yet = 1;
085   }
086
087   my ( $sec, $min, $hour, $mday, $mon,
088        $year ) = localtime( time );
089
090   my $date =
091    sprintf "%04d-%02d-%02d-%02d-%02d-%02d",
092     $year + 1900, $mon+1, $mday, $hour,
093     $min, $sec;
094
095   my @parts = ();
096
097   for my $part ( sort @drives ) {
098
099     my $base = basename $part;
100
101     if( $base eq $continue_with ) {
102       $not_yet = 0;
103     }
104
105     next if $not_yet;
106
107     push @parts, basename $part;
108   }
109
110   backup( $date, @parts );
111 }
112
113 ###########################################
114 sub backup {
115 ###########################################
116     my( $date, @parts ) = @_;
117
118     DEBUG "Backing up @parts";
119     sysrun qw( sudo /opt/drbl/sbin/ocs-sr
120       -b -q2 -c -j2 -z1 -i 2000 -sc -p true
121       savedisk ), "$date-img", @parts;
122
123     blurt "", "$mnt_dir/$date-img/DONE";
124 }
125
126 ###########################################
127 sub known_hosts {
128 ###########################################
129     return <<'EOT'
130 XXX
131 EOT
132 }
133
134 ###########################################
135 sub privkey {
136 ###########################################
137     return <<'EOT'
138 -----BEGIN RSA PRIVATE KEY-----
139 YYY
140 -----END RSA PRIVATE KEY-----
141 EOT
142 }

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook