Anleitung+Script => Fernwartung des Servers per Email

conym18

Member
Hallo zusammen,

ich wollt der allgemeinheit mal was gutes tun und habe eine Anleitung und ein Script für die Fernwartung per Email für einen Server geschrieben.

Ich weiß zwar nicht ob dass das richtige Forum ist, aber naja :)


[Vorgeschichte]
Ich habe einen vServer mit PLESK.
Da ich bei mir auf Arbeit nicht Privat im Internet surfen darf, kann ich demzufolge auch nicht auf meinen Server zugreifen um z.B. Dienste neu zu starten.
Dies ist immer dann ärgerlich, wenn es ein Produktivsystem mit Apache und MySQL ist.

Da ich aber nicht immer bis zu Hause warten will, habe ich mir ein kleines Script geschrieben.


[Kurzanleitung]
Ich schicke an eine spezielle Email auf meinen Server, welche einen speziellen Betreff hat.
Anhand dieses Betreffs wird dann eine Aktion auf dem Server ausgeführt.
Da auf meinem Server(SuSE) PLESK läuft, ist das Script sehr PLESK lastig.


[Vorarbeit]
Über das PLESK bei einer Domain eine neue Email mit MAILBOX hinzufügen.
Ich nenne sie jetzt einfach mal: meinserver@meinedomain.de
Wenn ich jetzt eine Email an meinserver@meinedomain.de schreibe, dann landet diese Email in folgendem Pfad.
/var/qmail/mailnames/meinedomain.de/meinserver/Maildir/new/

Dieses Verzeichnis hat gehört einer bestimmten Gruppe und Benutzer, in meinem Fall ist es popuser.popuser (Brauchen wir später noch einmal!)


[Anpassungen]
Man kopiert folgendes Script auf seinen Server, z.B. nach /root/EIGENES/inbound_mail_script.sh
Dieses Script muß nun genau in der gleichen Gruppe/Benutzer sein, wie der Emailpfad, z.B. popuser.popuser (Habe ich oben ja geschrieben, dass wir den nochmal brauchen)
Zusätzlich gibt man der Datei noch 500 Rechte.


[Was macht das Script]
Die Email an meinserver@meinedomain.de landet in diesem Verzeichnis.
Nun läuft das Script (weiter unten dazu mehr) über das Verzeichnis und führt anhand des Betreffs bestimmte Aktionen durch.

Ist der Betreff z.B. "stat", dann bekommt man die wichtigsten Dienste und Statistiken direkt an die Sender-Email zurückgeschickt.

Ist der Betreff z.B. "mysql start", dann wird der MySQL Datenbankserver neu gestartet und man erhält eine Email mit dem Ergebnis.

Anschließend wird die Email gelöscht.


[Cronjob einrichten]
Als root folgendes eingeben:
crontab -e

Folgende Zeile einfügen:
*/1 * * * * /root/EIGENES/inbound_mail_script.sh
(Jetzt prüft das Script jede Minute, ob neue Emails vorhanden sind und führt sie ggf. aus)


Das Script muß natürlich noch an die eigenen Pfade angepasst werden.
Bestimmte teile im Script können ergänzt werden oder, jenachdem wie man es braucht, auch gelöscht werden.


[Jetzt das Script]
PHP:
#!/usr/bin/php
<?
if ($handle = opendir('/var/qmail/mailnames/DOMAIN.TLD/EMAILADRESSE-VOR-DEM-AT-ZEICHEN/Maildir/new/')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$lines = file("/var/qmail/mailnames/DOMAIN.TLD/EMAILADRESSE-VOR-DEM-AT-ZEICHEN/Maildir/new/".$file."");
foreach($lines as $line)
{
if(eregi("Subject:", $line))
{
$subject = preg_split("'Subject:'",$line);
$subject = trim($subject['1']);
}
if(eregi("From:", $line))
{
$from = preg_split("'<'", $line);
$from = trim($from['1']);
$from = substr($from, 0, -1);
}
}


if($subject == "help")
{
    $mailinhalt = "Folgende Funktionen stehen derzeit zur Verfuegung:\n\n";
    $mailinhalt .= "Emailbetreff - Aktion\n\n\n";
    $mailinhalt .= "help - Zeigt die diese Hilfe an\n\n";
    $mailinhalt .= "plesk start - PLESK Administrationsoberflaeche starten\n";
    $mailinhalt .= "plesk stop - PLESK Administrationsoberflaeche stoppen\n";
    $mailinhalt .= "plesk status - PLESK Status anzeigen\n\n";
    $mailinhalt .= "apache2 status - Webserver Status anzeigen\n";
    $mailinhalt .= "apache2 stop - Webserver beenden\n";
    $mailinhalt .= "apache2 start - Webserver starten\n\n";
    $mailinhalt .= "stat - Aktuelle Statistik und Dienste des Servers\n\n";
    $mailinhalt .= "mysql status - Datenbankserver Status anzeigen\n";
    $mailinhalt .= "mysql stop - Datenbankserver beenden\n";
    $mailinhalt .= "mysql start - Datenbankserver starten\n\n";
    $mailinhalt .= "email starten - Emailserver starten\n\n";
    $mailinhalt .= "log - Die wichtigsten Log Files anzeigen\n\n\n";
    $maininhalt .= "Es kann bis zu einer Minute dauern, bis deine Anfrage bearbeitet wird!";
    mail($from,"Serverantwort",$mailinhalt);
}
elseif($subject == "log")
{
    #apache error_log
    $return = exec("tail -n 40 /var/log/apache2/error_log",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 1/5 - apache2 error_log 40 Zeilen",$return);
    $return = "";
    $output = "";
    
    
    #access_log DOMAIN1.TLD
    $return = exec("tail -n 50 /srv/www/vhosts/DOMAIN1.TLD/statistics/logs/access_log",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 2/5 - DOMAIN1.TLD access_log 50 Zeilen",$return);
    $return = "";
    $output = "";
    
    
    #access_log DOMAIN2.TLD
    $return = exec("tail -n 50 /srv/www/vhosts/DOMAIN2.TLD/statistics/logs/access_log",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 3/5 - DOMAIN2.TLD access_log 50 Zeilen",$return);
    $return = "";
    $output = "";
    
    
    #access_log DOMAIN3.TLD
    $return = exec("tail -n 50 /srv/www/vhosts/DOMAIN3.TLD/statistics/logs/access_log",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 4/5 - DOMAIN3.TLD access_log 50 Zeilen",$return);
    $return = "";
    $output = "";
    
    
    #access_log DOMAIN4.TLD
    $return = exec("tail -n 50 /srv/www/vhosts/DOMAIN4.TLD/statistics/logs/access_log",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 5/5 - DOMAIN4.TLD access_log 50 Zeilen",$return);
    $return = "";
    $output = "";
    
}
elseif($subject == "email starten")
{
    #mailmng -start-smtpd
    $return = exec("/usr/local/psa/admin/bin/mailmng --start-smtpd",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
    
    
    #mailmng -start-maild
    $return = exec("/usr/local/psa/admin/bin/mailmng --start-maild",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    $return = "";
    $output = "";
}
elseif($subject == "mysql start")
{
    #mysql start
    $return = exec("/etc/init.d/mysql start",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "mysql stop")
{
    #mysql stop
    $return = exec("/etc/init.d/mysql stop",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "mysql status")
{
    #mysql status
    $return = exec("/etc/init.d/mysql status",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "stat")
{
    #df -h -m
    $return = exec("df -h -m",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 1/9",$return);
    $return = "";
    $output = "";
    
    
    #ps faux
    $return = exec("ps faux",$output);
    foreach($output as $zeile)
    {
        $return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 2/9",$return);
    $return = "";
    $output = "";
    
    
    #top -b -n 1
    $return = exec("top -b -n 1",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 3/9",$return);
    $return = "";
    $output = "";
    
    
    #mysqld status
    $return = exec("/etc/init.d/mysql status",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 4/9",$return);
    $return = "";
    $output = "";
    
    
    #apache2 status
    $return = exec("/etc/init.d/apache2 status",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 5/9",$return);
    $return = "";
    $output = "";


    #vmstat
    $return = exec("vmstat",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 6/9",$return);
    $return = "";
    $output = "";
    
    
    #netstat -all
    $return = exec("netstat -all",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 7/9",$return);
    $return = "";
    $output = "";
    
    
    
    #mysql status
    $return = exec("mysql -u USERNAME -pKENNWORT -e status",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 8/9",$return);
    $return = "";
    $output = "";
    
    
    #mysql show prozesslist
    $return = exec("mysql -u USERNAME -pKENNWORT -e 'show processlist'",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort 9/9",$return);
    $return = "";
    $output = "";
    
    
}
elseif($subject == "apache2 stop")
{
    $return = exec("/etc/init.d/apache2 stop",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "apache2 start")
{
    $return = exec("/etc/init.d/apache2 start",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "apache2 status")
{
    $return = exec("/etc/init.d/apache2 status",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "plesk start")
{
    $return = exec("/etc/init.d/psa start",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "plesk stop")
{
    $return = exec("/etc/init.d/psa stop",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "plesk status")
{
    $return = exec("/etc/init.d/psa status",$output);
    foreach($output as $zeile)
    {
	$return .= "".$zeile."\n";
    }
    mail($from,"Serverantwort",$return);
    $return = "";
    $output = "";
}
elseif($subject == "")
{
    $mailinhalt = "Nichts angegeben?";
    mail("".$from."","Serverantwort","".$mailinhalt."");
}
$mailloeschen = system("rm /var/qmail/mailnames/DOMAIN.TLD/EMAILADRESSE-VOR-DEM-AT-ZEICHEN/Maildir/new/".$file."");
}
}
closedir($handle);
}
?>

Vielen Dank für Feedback :)
 
Last edited by a moderator:

elias5000

Site Reliability Engineer
Mich als Admin stört ja an der vorgestellten Lösung, dass das jeder machen kann. Blanke Mails enthalten ja keine Möglichkeit der Absender-Verifikation.

Meine Empfehlung wäre, den Steuerbefehl in einem PGP-signierten Mail-Body unterzubringen und die Signatur vor der Bearbeitung zu checken. Dann kannst du dich auch trauen, sensiblere Geschichten per Mail zu machen. (Wobei zumindest ein DoS schon jetzt drin ist.)
 

Ben.

Registered User
Zusätzlich gibt man der Datei noch 755 Rechte.
Welche 755 Rechte sind das? :D

Ernsthaft, ich würde noch - da es sich um ein Tutorial handelt - einen genaueren Blick auf die Rechtschreibung und Formatierung werfen.

Ansonsten finde ich es super wenn Skripte und Hinweise öffentlich zur Verfügung gestellt werden. Weiter so!!
 

conym18

Member
Ok, man könnte zusätzlich noch eine Abfrage einbauen, die folgendes prüft:

PHP:
if(($from == "irgendwas@gmx.de") OR ($from == "nocheine@meinedomain.de") OR ($from == "blaaaablubb@web.de"))
{
//HIER DAS OBIGE SCRIPT REIN
}
else
{
exit();
}

So kann man nur von den bestimmten Emails das Script starten lassen.
 

elias5000

Site Reliability Engineer
Du weißt, dass sich Absender im Header und Envelope beliebig fälschen lassen? Sicher, man muss erstmal wissen, wer da was darf. Aber wirkliche IT-Sicherheit sieht anders aus.
 

conym18

Member
775 Rechte sind, für alle die es nicht wissen, keine Anzahl :)

also:

Code:
chmod 500 /root/EIGENES/inbound_mail_script.sh
:)
 
Last edited by a moderator:
Top