Teil 3: Advanced Routing

https://marius.bloggt-in-braunschweig.de/2025/04/26/teil-2-einen-ganzen-server-rsyncen/

Bei Hetzner seine Server hinstellen, ist echt eine Herausforderung für den Admin, da kommen wir ohne Advanced Routing gar nicht hin.

Teil 3: Advanced Routing

Wir haben einen Hotstand-By Server, der muß 2 IPs haben, damit er genau so funktioniert wie der Originalserver. Wenn man jetzt bei Hetzner einen Server mietet oder hinstellt, dann gibt es eine Hürde man braucht für eine VM min. eine Zusatz IP, in dem Fall 2, und die kommen aus dem gleichen Netzwerksegment, haben aber andere MAC-Adressen, weil Hetzner es nicht erlaubt, zwei (oder alle) IPs auf der gleichen MAC zu haben. Die drohen einem glatt mit Sperren, wenn man sich nicht daran hält. Dazu habe ich noch einen bösen Kommentar am Ende für Euch 😉

„Mehr als ein Interface, aber gleiche Netze? WTF??“

Ja, das geht… ist aber nicht so einfach. Erstmal muß man dazu wissen, wie VMs auf einem Host i.d.R. ans Netz angeschlossen werden: per Bridgeinterface.

Das Bridgeinterface ist eine Art virtueller Switch, bei dem das echte Netzwerkinterface des Hosts mit
dem der VM verbunden wird, so daß da Daten langgehen können. Beispiel:

vmbr0		8000.a8a159c0d0c0	no		enp41s0
							fwpr104p0
							fwpr104p1

Die Brücke heißt „vmbr0“ und das echte Interface ist „enp41s0„. Die zwei Interface der VM sind p0 und p1.

In der VM sieht das dann so aus:

# ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 00:50:56:00:da:8b brd ff:ff:ff:ff:ff:ff
    altname enp0s18
3: ens19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 00:50:56:00:98:bd brd ff:ff:ff:ff:ff:ff
    altname enp0s19

Die IPs sollen mal „1.1.100.4/26“ und „1.1.100.39/26“ sein, beide fiktiv, sonst kommt noch wer auf dumme Ideen 😉

Was wir jetzt brauchen ist eine priorisierte Route für das zweite Interface, weil sonst der Traffic des zweiten Interfaces ens19 durchs erste Interface ens18 geht, aber wegen der „falschen“ MAC, nicht geroutet oder beachtet wird!

Dazu brauchen wir ip_route2

Wer noch kein Verzeichnis hat, legt es einfach an:

mkdir /etc/iproute2
echo 100 if2 > /etc/iproute2/rt_tables

Dann priorisieren wir alles, was von IP2 kommt, über das Interface 2, damit es nicht durch die Defaultroute über Interface 1 geht:

ip rule add from 1.1.100.39 table if2 prio 1
ip route add 1.1.100.0/26 dev ens19 src 1.1.100.39 prio 1
ip route add default via 1.1.100.1 dev ens19 table if2

Dann können wir eine zweite Defaultroute anlegen, was vorher nicht ging. Das sieht dann so aus:

# ip r
default via 1.1.100.1 dev ens18
1.1.100.0/26 dev ens18 proto kernel scope link src 1.1.100.4
1.1.100.0/26 dev ens19 proto kernel scope link src 1.1.100.39
1.1.100.0/26 dev ens19 scope link src 1.1.100.39 metric 1
169.254.0.0/16 dev ens18 scope link metric 1002
169.254.0.0/16 dev ens19 scope link metric 1003

Damit das permanent so bleibt, was es einfach so nicht möchte, kann man es in ein Script schreiben und das nach dem Start des Netzwerkes aufrufen. Wie Ihr das macht, bleibt Euch überlassen.

Der Kommentar

Hetzner legt nicht ganz zu unrecht Wert auf einen MAC Filter und besteht darauf, daß jede IP eine eigene, von denen vorgegebene MAC hat. Das ist nötig, weil Jeder Jeden im Netz sehen kann, so bekam unsere VM da 3,5Mb/s Broadcasttraffic ab, weil andere Leute keinen Plan von Netzwerken haben und wie man die richtig konfiguriert. Natürlich könnten wir auch Macs als Kunden vorgeben und die akzeptieren die, aber das wäre denen zu viel Aufwand, was Schade ist, weil der Beitrag hier dann überflüssig gewesen wäre 😀

Kann Jeder Jeden sehen, kann man dem seine IPs hochfahren und kapern, deswegen der MAC Filter. Wenn man da aber drauf besteht, anstatt die ganzen Server in VLans zu isolieren, so daß das die sich eben nicht mit Fake ARPs beglücken können, dann muß man das auch überwachen und den Verursacher des Datenmülls stoppen. Das haben die Kollegen bei Hetzner erst gemacht, nachdem ich denen mitgeteilt hatte, daß es wohl ein DDOS Angriff sein könnte ( weil es auch so aussah ) 😀 Jetzt sind wir über Ostern bei 400Kb/s, das klingt schon normaler.

 

Linux am Dienstag – Programm für den 29.4.2025

Diesmal bei Linux am Dienstag schauen wir uns mal Nvidia Treiberprobleme an und klappen das nächste Kapitel Advanced SSH auf.

Linux am Dienstag – Programm für den 29.4.2025

u.a. im Programm am 29.4.2025, ab 19 Uhr :

Linux – Advanced SSH – Restriktiver Zugriff (Marius)
Linux – Manjaro Update bringt neue Desktopversionen
Linux – Kritische Lücke in Tails
KI – Google zahlt Unsummen um seine KI Bots zu plazieren
KI – ChatGPT baut Exploit, was explizit nicht gehen sollte

und andere IT-Newsbeiträge aus aller Welt. Wie jede Woche per Videokonferenz auf https://meet.cloud-foo.de/Linux .
Hinweis: Die bisherigen Vorträge findet man unter https://linux-am-dienstag.de/archiv/ .

Teil 2: einen ganzen Server Rsyncen

https://marius.bloggt-in-braunschweig.de/2025/04/23/teil-1-wie-man-partitionen-neue-alte-uuids-gibt/

Ihr hat den ersten Teil gelesen und wollt mehr erfahren? Syncen wir doch mal einen ganzen Server.

Teil 2: einen ganzen Server Rsyncen

Ihr habt sicher schon mal etwas von einem Clusterfilesystem gehört. Dabei mounten man auf zwei Servern ein gemeinsames Filesystem, daß sich dann über das Netzwerk abgleicht, in dem alle Blöcke mit Änderungen einzeln von A nach B transportiert werden, das GlusterFS macht(e) sowas z.b.  Problem hier,  das geht nur für ganze Mountpoints, also Verzeichnisse oder Partitionen. Wer Teil 1 gelesen hat, weiß das in dem aktuellen Fall so ein ClusterFS nicht geht, weil es Abweichungen im Netzwerk gibt, die dann jedes mal überschrieben würden.

Natürlich gibt es auch andere ClusterFilesysteme die nach Dateien , statt Blöcken gehen, und da kann man dann Dateien excluden, aber in dem Fall haben wir einen Liveserver den wir nicht stoppen dürfen um dem „umzuformatieren“, so daß er so ein ClusterFS benutzen kann, dazu sind da auch zu viele Daten drauf um den „mal eben“ umzukopieren.

Zum Glück brauchen wir das nicht, weil wir Rsync nehmen können.

Ok, Ich habe gelogen, wir syncen gar nicht den ganzen Server 😉

Wir Syncen /etc/ /home/ /var/lib/mysql und alle anderen Plätze wo Userdaten liegen. Das Prinzip erläutere ich mal bei /etc/ und wo man da aufpassen muß. Das hier führen wir auf dem Hotstand-By-Server aus:

rsync -a –delete -v -e „ssh -C -i /root/.ssh/synckey“ root@$ZIELSERVER:/etc –exclude=/etc/sysconfig –exclude=/etc/fstab –exclude=/etc/systemd –exclude=/etc/iproute2 –exclude=/etc/cron.d /

Wir verbinden uns also zum Live-System und syncen ZU UNS!  Nennen wir das mal PULL-Verfahren. Das würde auch in die andere Richtung gehen, dann wäre ein PUSH-Verfahren. Liegt bei Euch was Ihr machen möchtet. Eines möchte ich aber zu bedenken geben:

Wenn man schon einen anderen Server hinstellt, dann so, daß wenn der aktive Server gehackt wird, der Hacker nicht auf den Reserveserver drauf kommt. Ein PULL hat also einen gewissen Vorteil. Der nicht ausgelastete Reserveserver kann auch das Datenbackup machen und so den Liveserver entlasten. Denkt über solche Sachen vorher nach, es lohnt sich 😉

Der Rsync erklärt

rsync -a –delete -v -e „ssh -C -i /root/.ssh/synckey“

„-a –delete -v „ archiviert und löscht Daten rekursiv auf dem Empfängerserver, wo mit der Hotstand-By im Sync bleibt mit allen Änderungen auf dem Quellserver, aber auf dem Quellserver nichts verändert wird. Das ist ganz wichtig, weil ein Master-Master-Setup beim Sync birgt richtig Potenzial für Datenverluste.

Damit sich unser Rsync überhaupt auf den anderen Server verbinden kann ohne das wir ein Passwort eingeben müssen, nehmen wir einen passwortlosen sshkey ‚-e „ssh -C -i /root/.ssh/synckey“ ‚ , denn einen SSH-Agenten gibt es dort nicht, bzw. der würde es auch nicht sicherer machen, weil der KeyStore nie ablaufen darf, sonst geht der Sync nicht mehr. Wer will da schon jeden Tag rein und den KeyStore verlängern?

Zuerst geben wir an, was wir syncen wollen, also /etc/ , dann die ganzen Excludes, die wir NICHT syncen wollen, dann wohin es gesynct werden muß -> „/“:

root@$ZIELSERVER:/etc –exclude=/etc/sysconfig –exclude=/etc/fstab –exclude=/etc/systemd –exclude=/etc/iproute2 –exclude=/etc/cron.d /

Tip: Wieso „/“ als Ziel? Weil /etc/ in / liegt! Würde man hier /etc als Ziel angeben, dann ergäbe das /etc/etc .

In /etc/sysconfig sind z.b. die Netzwerkkonfigurationen, in /etc/systemd können z.b. lokale Anpassungen im Hotstand-By sein, so daß die nicht gelöscht werden dürfen, nur weil es die auf dem Quellserver nicht gibt. IProute2 ist ein Sonderfall, auf den wir im nächsten Teil eingehen werden und im cron vom Quellserver laufen Dinge die nicht auf dem Hotstand-By laufen sollen.

Kleines Konfigproblem

Wir haben jede Menge Konfigurationsdateien von Netzwerkbasierten Diensten wie Apache HTTPD, Proftp usw. gesynct, die aber alle auf dem Quellserver konfiguriert wurden, sprich: die IPs da drin stimmen nicht! Das können wir aber leicht nach dem Sync beheben. Ein unvollständiges Beispiel:

$ replace „1.2.3.4“ „5.68.7.85“ — /etc/sysconfig/iptables /etc/sysconfig/network-scripts/ifcfg-* /etc/sysconfig/network /etc/httpd/conf/httpd.conf /etc/httpd/conf.d/ssl.conf /etc/named/* /etc/hosts

Da Ihr clever wart und Eure Dienste auf dem Reserveserver erst gestartet habt, nachdem Ihr den IP Replace gemacht habt, brauchen die Dienst deswegen nicht nach jedem Sync neu gestartet werden. Die laufen ja schon auf der richtigen IP.

Jetzt hatte ich eingangs gesagt, einiges wie Netzwerkkonfiguration soll nicht gesynct werden, kann man aber machen, wenn man die IPs / Macs usw. passend ersetzt. Und deswegen sollte das auch ein PULL sein, weil der Hotstand-By weiß, welche IPs er hat, der Quellserver muß das nicht wissen und muß es dann auch nicht fixen, wozu er mehr als nur Rsync Zugang bräuchte.

Wenn man / syncen will

Wenn man wirklich dumme Sachen machen will:

rsync -a –delete -v -e „ssh -C -i /root/.ssh/synckey“ root@$ZIELSERVER:/ –exclude=/{dev,proc,run,sys,tmp} /

dann klammert wenigstens /dev /proc /sys und /run aus, wenn Euch schon nicht anders zu helfen ist 😉  Denkt dran, das bei dem Sync jeder CRON, egal ob per crond oder systemd, sofort gelöscht wird. Ein nachträglicher Fix oder weiteren Sync wird es nicht geben, wenn Ihr die nicht auch excluded!  Außerdem denkt dran, Ihr synct auch die Syncbefehle, libs und /bin usw.. das kann böse ins Auge gehen, deswegen sagte ich, daß das eine Dummheit wäre. Wenn so ein Sync während es Updates passiert, ist das Update weg und nur noch halb vorhanden oder nur halb gesynct. Tut es nicht, wenn es nicht absolut sein muß, oder tut es in ein Unterverzeichnis.