netcat, dd und ganz viel Spaß

Diesen Beitrag schrieb ich 13 Jahre und 11 Monate zuvor; die nachfolgenden Ausführungen müssen heute weder genau so nach wie vor funktionieren, noch meiner heutigen Meinung entsprechen. Behalte das beim Lesen (und vor allem: beim Nachmachen!) bitte stets im Hinterkopf.

Geschätzte Lesezeit: 4 Minuten

Die Problemstellung

Da ist ein Server, der einen kritischen Dienst bedient; leider ist dieser Server restlos veraltet (sowohl aus Hard- als auch aus Software-Sicht), und ein Update des kritischen Dienstes nicht so ohne weiteres möglich. Am liebsten möchten wir den Datenbestand 1:1 auf eine andere Maschine ziehen und auf dieser, ganz in Ruhe, einige Testläufe starten, Dinge probieren und einen Workflow zur Lösung dieses Problems entwickeln. Allerdings ist auf dem laufenden Server viel zu wenig Platz, als dass dort ein Image erstellt und anschließend auf die neue Maschine übertragen werden könnte.

Ein möglicher Lösungsansatz

Ein guter Einsatzzweck für virtuelle Maschinen – das zugrundeliegende System ist hier ein MacOS 10.6.3 mit Parallels 5; natürlich lässt sich das jedoch auf nahezu jedes beliebige Hostsystem und nahezu jede beliebige Virtualisierungssoftware übertragen. Der erste Schritt besteht darin, eine Standardinstallation eines Betriebssystems nach Wahl durchzuführen – ich entscheide mich für Ubuntu. Diese Prozedur ist in keiner Form außergewöhnlich und wird deshalb an dieser Stelle auch nicht weiter erläutert. Dieser virtuellen Maschine wird eine zweite virtuelle Festplatte untergeschoben – deren Größe orientiert sich an der Größe des Quellsystems, in meinem Fall 10GB. Übers Netz wird aus dem virtuellen Ubuntu heraus ein vollständiger Dump des laufenden Quellsystems auf die zweite virtuelle Platte heraus vorgenommen. Schlussendlich wird über einen grub-Eintrag sichergestellt, dass das virtuelle System Dual-Boot-fähig ist und wahlweise nun entweder das ursprünglich installierte (Ziel-)Ubuntu oder aber der virtuelle (Quell-)Server gestartet werden kann. In diesem virtuellen Server können dann die benötigten Testläufe initiiert werden, und wenn man etwas schrottet, ist das gar nicht schlimm – die virtuelle Maschine lässt sich ja leicht wiederherstellen…

Die zweite virtuelle Platte einrichten

Nachdem dem System in der Parallels-Konfiguration eine zweite virtuelle Platte definiert wurde (vgl. Screenshot) und das virtualisierte Ubuntu gestartet ist, muss diese zweite Platte eingerichtet werden; wurde sie nachträglich definiert, wird sie naturgemäß beim Booten des Systems natürlich nicht erkannt. Also erst einmal schauen, ob er sie überhaupt hat:

$ dmesg | grep sd
[    0.936360] sd 0:0:0:0: Attached scsi generic sg0 type 0
[    0.936780] sd 1:0:1:0: Attached scsi generic sg1 type 0
[    0.936837] sd 0:0:0:0: [sda] 20972448 512-byte logical blocks: (10.7 GB/10.0 GiB)
...
[    0.936946] sd 1:0:1:0: [sdb] 20972448 512-byte logical blocks: (10.7 GB/10.0 GiB)
...

Sieht schwer danach aus; sda ist ja unsere erste Festplatte, also die, auf der das Ubuntu liegt; sdb ist noch jungfräulich und leer, da wird nun das Serversystem draufgezogen…

Das System portieren – dd und netcat

  • Auf dem Zielrechner, also in der Ubuntu-VM, wird ein Port geöffnet, über den die Daten hereinmarschieren und direkt auf die Platte /dev/sdb geschrieben werden; im Beispiel läuft der Transfer über Port 443, da die restriktiven Firewall-Regeln einen Extra-Eintrag für einen anderen Port erfordern würden. Nun kann der Transfer gestartet werden.
root@ziel$ netcat -l 443 | dd of=/dev/sdb
  • Vom Quellsystem aus wollen wir den gesamten Inhalt der Platte (in diesem Falle heißt sie /dev/sda1) übertragen; und damit können wir nun beginnen:
root@quelle$ dd if=/dev/sda1 | netcat ziel 443

Während der Übertragung, die – je nach Netzauslastung und Datenmenge – durchaus eine ganze Weile dauern kann, lungern nun zwei offene Shells auf dem Desktop herum, doch eine Statusanzeige gibt keine von beiden. Es gibt jedoch eine Möglichkeit, Statusinformationen zu erhalten, nämlich dem dd-Prozess auf dem Zielhost ein USR1 zu schicken:

root@ziel$ ps aux | grep dd
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
...
root      1563  0.0  0.0   3396   772 pts/0    S+   15:38   0:00 dd of=/dev/sdb
...
root@ziel$ kill -USR1 1563

Das ergibt dann in der Shell des Zielsystems (in der der dd-Aufruf aktiv ist) eine Ausgabe in der Form:

2+1 records in
2+0 records out
1024 bytes (1.0kB) copied, 54.0942s, 24.2 kB/s

Entweder man entwirft sich einen Aufruf, der das automatisch alle paar Sekunden ausführt, oder man führt es manuell von Zeit zu Zeit aus – so sieht man jedenfalls, wieviele Daten bereits übertragen wurden. Die Übertragung ist beendet, wenn auch auf dem Quellrechner eine Ausgabe der Form „1196 bytes transferred in 0.000089 seconds (13431951 bytes/sec)“ erscheint.

grub installieren

In meinem Fall war das mit einem simplen Aufruf erledigt:

root@ziel$ grub-install --force /dev/sdb

Hierdurch wurde meine grub-Konfig um folgende Zeilen erweitert:

## /boot/grub/grub.cfg
menuentry "Debian GNU/Linux, kernel 2.6.x (on /dev/sdb)" {
        recordfail
        insmod xfs
        set root='(hd1,1)'
        search --no-floppy --fs-uuid --set fb0a4e3a-0457-454d-8650-0bf853d17530
        linux /boot/vmlinuz-2.6.x root=/dev/sdb root=/dev/hdd ro

Damit funktioniert das Booten noch nicht wirklich. Betrachten wir uns einmal die Parallels-Screenshots: die zweite Platte wurde als „Location IDE 1:1“ definiert, sprich als zweites Gerät am zweiten Controller, also hdd (die erste Platte ist auf „Location IDE 0:0“ definiert und somit das erste Gerät am ersten Controller, also hda). Es muss also das oben stehende root=/dev/sdb durch root=/dev/hdd ersetzt werden. Und das ist auch schon alles – nun kann das portierte System virtuell gestartet werden!

Vorsicht!

Vor dem ersten Start des portierten Systems solltest du unbedingt sicherstellen, dass beim Booten nichts getötet werden kann; prüfe beispielsweise sorgfältig, dass es nicht zu IP- oder DNS-Konflikten kommen kann, wenn zu dem ursprünglichen Server und auch die virtualisierte Version parallel ins Netz gehängt wird! Sorge weiterhin dafür, dass Dienste, die alle User im Netz betreffen können – DHCP beispielsweise – nicht das gesamte Netzwerk verwirren oder gar lahmlegen! Überlege sorgfältig, um welche Dienste es sich in deinem Falle konkret handeln könnte, und handle mit Bedacht. Im laufenden Ubuntu-System können Sie die zweite Platte leicht mounten:

root@ziel$ mount /dev/sdb /mnt

Wenn nötig, kannst du nun ein chroot /mnt ausführen und das System (am besten schon vor dem ersten Booten) auf Dinge durchforsten, die den laufenden Betrieb stören könnten. Starte das System nur dann, wenn du dir ganz sicher sein kannst, dass nichts explodieren wird. Und wenn du auf „Nummer Sicher“ gehen möchtest: starte das System im ersten Anlauf ohne Netzwerkinterface. Dann kann nicht viel schief gehen :-)

Alle Bilder dieser Seite: © Marianne Spiller – Alle Rechte vorbehalten
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten

Eure Gedanken zu „netcat, dd und ganz viel Spaß“

Ich freue mich über jeden Kommentar, es sei denn, er ist blöd. Deshalb behalte ich mir auch vor, die richtig blöden kurzerhand wieder zu löschen. Die Kommentarfunktion ist über GitHub realisiert, weshalb ihr euch zunächst dort einloggen und „utterances“ bestätigen müsst. Die Kommentare selbst werden im Issue-Tracker und mit dem Label „✨💬✨ comment“ erfasst – jeder Blogartikel ist ein eigenes Issue. Über GitHub könnt ihr eure Kommentare somit jederzeit bearbeiten oder löschen.