Remote Kommandos auf Server via xinetd ausfuehren / Adminfun

Es gibt Sachen die machen Spass, z.B. diese Spielerei. Es geht darum auf einem Server ein Remotekommando / Shellskript via Webbrowser auszufuehren, ohne das dafuer irgendeine grosse Software-Remotemanagement-Loesung laufen muss. Die Antwort ist der gute alte (x)inetd verbunden mit einem kleinen PHP-Skript. Ich kommentiere das jetzt hier nicht weiter sondern schreibe es einfach mal runter:

Als erstes muessen die Programme installiert werden:

 aptitude install xinetd php5-cli

Danach die folgende Datei unter /etc/xinetd.d/test ablegen

# description: xinetd + php = fun
service test
{
        socket_type     = stream        
        protocol	= tcp
	wait            = no
        user            = root
	server		= /usr/bin/php5
	server_args	= /root/test.php
	disable		= no
}

Anschliessend die /etc/services editieren und die folgende Zeile einfuegen:

test		44444/tcp			# test

und nun noch diese PHP-Datei unter /root/test.php ablegen:

<?php
echo "+++ xinetd + php = fun +++
 
";
 
## read parameter
$handle = fopen('php://stdin','r');
$input = fgets($handle);
fclose($handle);
 
## split get parameter 
$out1=str_replace("GET /", "", $input);
$out2=str_replace(" HTTP/1.1", "", $out1);
$parameter=explode("/", $out2);
 
## check if we shall do sth. and if we know it
if (trim($parameter[0]) == "doStuff") {
 
  if (empty($parameter[1])) {
    echo "no job start requested...
    ";
  }
 
  elseif (! trim(empty($parameter[1])) AND trim($parameter[1]) == "psaux") {
    $out = shell_exec('ps aux');
    echo "$out";
  }
 
}
else {
  echo "no job start requested...
";
}
?>

Ich denke die PHP-Datei erklaert sich von selber und kann beliebig erweitert werden. Ein Aufruf von http://example.net:44444/doStuff/psaux gibt dann die Ausgabe des Befehls „ps aux“ wieder. Nun sind bei dem shell_exec keine Grenzen gesetzt… ;-) Wichtig daran ist, dass wir die GET Parameter via stdin auslesen, da der xinetd das Zeugs ja nicht per GET an das php-Skript weiterleitet. Aber was solls… Der Kreativitaet sind da keine Grenzen gesetzt.

Ich wuerde natuerlich noch den Zugriff ueber irgendeine iptables Regel beschraenken ala:

iptables -A INPUT -p tcp -m tcp --dport 44444 -s 1.2.3.4 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 44444 -j REJECT

Und ueber Security von wegen das Skript als root laufen zu lassen usw. reden wir hier nicht weiter, es geht ja auch nicht darum das als Superloesung zu verkaufen, sondern einfach als simple kleine Adminspielerei ;-)

Howto: Convert Ext2 to Ext3 to Ext4

Wie schoen ist es doch, dass man sein vor 15 Jahren angelegtes Dateisystem relativ einfach aktualisieren kann.
Interessant ist das ganze wenn man an die Grenzen des jeweiligen Dateisystems stoesst, wie z.B. die Dateigroessengrenze von 2Tebibyte bei ext2, oder die bei ext2 und ext3 gleiche Begrenzung von ~32000 Unterordnern pro Verzeichnis.
Die Konvertierung ist hier anhand eines simplen Beispiels einmal durchgespielt. Dafuer legen wir uns eine 50MB grosse Containerdatei an, in der ein Dateisystem erzeugt wird und wir dann die Konvertierung vornehmen.

Als erstes legen wir die Containerdatei an und binden diese unter /dev/loop0 als loop device ein:

$ dd if=/dev/urandom of=testfile bs=1M count=50
$ losetup /dev/loop0 testfile

Nun muss eine Partition in dem Container angelegt werden, z.B. mit fdisk:

$ fdisk /dev/loop0
n p 1 enter w

Danach legen wir ein Ext2 Dateisystem darin an, mounten dieses, erstellen darin eine Datei gucken das wir sie lesen koennen und haengen es wieder aus:

$ mkfs.ext2 /dev/loop0
$ echo foo >> /mnt/bar
$ cat /mnt/bar 
bar
$ mount | grep loop0
/dev/loop0 on /mnt type ext2 (rw)
$ umount /mnt

Jetzt konvertieren wir das Dateisystem zu einem Ext3, haengen es ein, gucken ob wir die Datei noch lesen koennen und haengen es wieder aus:

$ tune2fs -j /dev/loop0
$ mount /dev/loop0 /mnt/
$ cat /mnt/bar
foo
$ mount | grep loop0
/dev/loop0 on /mnt type ext3 (rw)
$ umount /mnt

Hat geklappt! Zuletzt bringen wir das Dateisystem auf Ext4 und probieren das gleiche nochmal wie bei den vorherigen Schritten:

$ tune2fs -O extents,uninit_bg,dir_index /dev/loop0
$ e2fsck -fDC0 /dev/loop0
$ mount /dev/loop0 /mnt
$ cat /mnt/bar
foo
$ mount | grep loop0
/dev/loop0 on /mnt type ext4 (rw)
$ umount /mnt

Und aufraeumarbeiten:

$ losetup -d /dev/loop0
$ rm testfile

Bei Kopiervorgaengen IO beschraenken

Um bei Kopiervorgaengen den IO zu beschraenken kann man das z.B. machen, indem man rsync nutzt und die Option –bwlimit in KB/s uebergibt, z.B.

rsync -avh --progress -bwlimit=5000 /my/source /my/destination

wobei die Bandwith auf 5MB/s beschraenkt wird.

Eine andere alternative ist mit dem Programm ionice zu arbeiten. Mehr dazu in diesem Blogeintrag:
How To Avoid Sudden Outburst Of Backup Shell Script / Program Disk I/O

SSH ProxyCommand

Mal wieder SSH … Wie nervig ist es immer wegen Firewalls und Serverhopping erst auf den einen Server gehen zu muessen, bevor man sich auf dem gewuenschten einloggen kann. Die Loesung lautet ProxyCommand. Ein Beispiel fuer eine .ssh/config:

Host *
Compression		yes
CompressionLevel	9
 
Host			bar
User			username
Port			22
ProxyCommand 		ssh foo nc %h %p
Ciphers 		arcfour
ClearAllForwardings	yes
 
Host			foo
HostName		192.168.1.1
User			username
Port			22

Wenn man nun noch eine Key-Authentifizierung hat, (und auf foo in der .ssh/config auch bar definiert ist) kann man sich Schwupps mit

ssh bar

auf dem gewuenschten Rechner einloggen ohne laestiges zwischendrin :-) Ciphers und ClearAllForwardings sind Performancesachen, denn die eine Verbindung muss nicht soo stark verschluesselt sein, wenn es der Tunnel bereits ist.