RAID metadaten entfernen

Manchmal soll eine bereits benutzte Festplatte neu verwendet werden.

Dies kann Probleme geben, z.B. bei der Installation des Betriebssystems, wenn die Platte vorher schon einmal in einen Hardware- oder Soware-RAID war. Dann verweigern viele installer nämlich eine Installation.

Eine Möglichkeit wäre es die ganze Festplatte mit NULLEN zu überschreiben, doch das geht bei den heutigen Terrabyte Festplatten stunden. Dabei reicht, es nur die letzten 512 byte auf der Platte zu überschrieben:

MY_DEVICE="/dev/sdx"
dd if=/dev/zero of=$MY_DEVICE bs=512 seek=$(( $(blockdev --getsz $MY_DEVICE) - 1024 )) count=1024

Quellen

Farbiger Bash Prompt

Manchmal macht es Sinn, wenn man in der shell Farben hat, so kann man z.B. produktive Systeme rot und Test-Systeme grün kennzeichnen.

Das folgende Konstrukt in der bashrc macht beispielsweise den promt (user@system) grün:

PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '

Und das hier rot:

PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] '

Quellen

UEFI-Installation von Windows 7

Mittels des neuen UEFI-BIOS, welches mit fast allen neuen PCs kommt started Windows 7 wesentlich schneller.

Damit jedoch die UEFI Installation startet muss einiges beachtet werden:

  • Im BIOS UEFI boot von CD aktivieren
  • Windows 7 64bit DVD verwenden (mittels eines USB-Sticks geht die Windows 7 UEFI Installation nicht ohne hacks!)

Überprüfen kann man die Installation, wenn man die Datenträgerverwaltung öffnet und als Partitionstabelle: „GPT“ steht.

Quellen

Benutzerliste aus LDAP/ActiveDirectory erstellen

Mittels python lassen sich Benutzer aus einem LDAP-Verzeichnis (bzw. ActiveDirectory) einfach auslesen und formatiert ausgeben:

#!/usr/bin/python
 
# import ldap module
import sys, ldap
 
# Define the name to search
searchstring="*"
 
# connection settings
ldap_url = "ldap://localhost"
binddn = "CN=LDAP User,OU=User Accounts,DC=example,DC=org"
pw = "secret"
 
# Search settings
basedn = "OU=User Accounts,DC=ad,DC=example,DC=net"
searchFilter = "(&(cn={searchstring}))".format (searchstring=searchstring)
searchAttribute = ['cn', 'sAMAccountName', 'displayName', 'mail']
searchScope = ldap.SCOPE_SUBTREE
 
# bind to the server
l = ldap.initialize(ldap_url)
try:
  l.simple_bind_s(binddn, pw)
except ldap.INVALID_CREDENTIALS:
  print "Your username or password is incorrect."
  sys.exit(0)
except ldap.LDAPError, e:
  if type(e.message) == dict and e.message.has_key('desc'):
    print e.message['desc']
  else:
    print e
  sys.exit(0)
 
# query LDAP
try:
  resultId = l.search(basedn, searchScope, searchFilter, searchAttribute)
  result_type, result_data = l.result(resultId)
 
  for ldap_dn,ldapuser in result_data:
    print ldap_dn
    #print ('username={ldap_sAMAccountName},)
    print ('username={ldap_sAMAccountName}\ndisplayName={ldap_displayName}\nmail={ldap_mail}\n\n').format (ldap_sAMAccountName = ldapuser['sAMAccountName'][0], ldap_displayName = ldapuser['displayName'][0], ldap_mail = ldapuser['mail'][0],)
 
except ldap.LDAPError, e:
  print e
 
# close connection
l.unbind_s()

Die Parameter unter „connection settings“ sind:

searchstring Der Name nach dem gesucht wird
ldap_url Die Adresse vom LDAP-Server
binddn Die DN vom Benutzer, welcher sich am LDAP-Server anmeldet (i.dR. ein „read-only“ user)
pw Passwort für den oben genannten Benutzer
basedn Fange ab hier mit der Suche an; das kann der root Pfad sein, besser ist es aber aber einen Pfad mit den aktiven Accounts einzuschränken, damit deaktivierte Benutzer nicht drin sind
searchFilter Das LDAP-Suchmuster; anstelle von „givenName“ kann beispielsweise auch „cn“ oder „displayName“ sein
searchScope Hier wird definiert ob nur im aktuellen LDAP-Zweig oder rekursiv gesucht wird

 

OpenVPN: Keine Verbindung unter Windows 7

Unter Windows 7 kommt keine Verbindung mit OpenVPN zustande.

Dies liegt an den Rechte-Einschränkungen, welche ab Windows 7 eingeführt wurden.
Damit OpenVPN weiterhin läuft muss man die folgenden Dinge beachten:

  • Windows UAC abschalten
  • Den OpenVPN installer als Administrator ausführen
  • Das config Verzeichnis muss vom Benutzerverzeichnis in das Installationsverzeichnis kopiert werden. Auf diesem Verzeichnis dem Benutzer Vollzugriff geben.
  • Im openvpn config file müssen diese zwei Zeilen hinzugefügt werden:
route-method exe
route-delay 2
  • Das Programm OpenVPN-Gui.exe muss mittels Rechtsklick angewählt werden, dann „als Administrator starten“ anklicken (sollte nur notwendig sein, falls UAC nicht abgeschaltet wurde)

Eigener DynamicDNS (ddns) Dienst

Kürzlich ärgerte ich mich wieder einmal über die monatliche Reaktivierung, die man bei seinem kostenlosen DyDNS-Hoster wie z.B. dyndns.com oder noip.com vornehmen muss.

Deshalb recherchierte ich ein bisschen über Lösungen und kam dann darauf, dass, wenn man bereits einen eigenen Nameserver und Webserver mit statischer IP hat, man daraus ganz einfach seinen eigenen „DynDns-Dienst“ machen kann! 😉
Hier die Beschreibung wie das geht.

Continue reading Eigener DynamicDNS (ddns) Dienst

apache: Authentifizierung wahlweise über IP oder HTTP-Auth

Bei sensiblen Web-Applikation wie die für das Verwalten des Mailservers (z.B. postfixadmin) oder welche die Zugriff auf die Datenbanken haben (z.B. phpmyadmin) sollte man sich nicht nur auf die Sicherheit der Applikation verlassen und stattdessen zusätzlich eine Authentifizierung über den Webserver (.htaccess) vornehmen.

Hierzu gibt es grundsätzlich zwei Möglichkeiten: Authentifizierung über die IP-Adresse und über eine HTTP-Passwortabfrage.

Doch während die erstere den Nachteil hat unflexibel zu sein (z.B. kein Zugriff mehr wenn man mal von einem Internet-Cafe dringend darauf zugreifen muss), müsste man bei zweitem immer zweimal einloggen: Einmal über die HTTP-Authentifizierung und einmal über die Web-Applikation selbst.

Doch zum Glück lassen sich diese zwei Mechanismen kombinieren, so dass man bei bekannten IPs ohne vorgängige Passwort-Abfrage direkt zum Web-Login kommt und bei „fremden“ IPs die Möglichkeit hat nach einer zusätzlichen HTTP-Authentifizierung die Web-Applikation zu erreichen.

Continue reading apache: Authentifizierung wahlweise über IP oder HTTP-Auth

mysql: Datenbank-Replikation einrichten

Mittels der mysql Datenbank-Replizierung kann man eine automatisch aktualisierende Kopie einer oder mehreren Datenbanken auf einem anderen Server haben.

Dies hat zwei grosse Vorteile:

  • Man hat eine failover-Datenbank, falls die Haupt-DB down ist
  • Man kann die SELECT Abfragen auf mehren Hosts verteilen und hat so einen Lastausgleich.

Grundsätzliches

mysql sieht vor, dass es einen sog. "Master" Server gibt auf dem die Datenbanken verwaltet werden und ein- oder mehrere "Slave"-Server die immer eine aktuelle Kopie tragen. Allerdings ist es normalerweise nicht möglich updates auch auf dem slave-server zu machen, d.H. die slave server sind eigentlich nur für LESE-, nicht aber für Schreibzugriffe da.

Die Funktionsweise geht so, dass der MASTER-Server sämtliche Anweisungen in ein sog. binlog (mysql-bin) schreibt und an die SLAVES sendet. Der SLAVE schliesslich entscheidet mittels des Parameters "replicate-do-db", welche Datenbanken er repliziert.

Konfiguration

Master

Zuerst setzen wir in der my.cnf des Master-Hosts die folgenden Optionen:

[mysqld]
max_allowed_packet              = 16M
server-id                       = 1
log-bin                         = mysql-bin
expire_logs_days                = 7
max_binlog_size                 = 100M
innodb_flush_log_at_trx_commit  = 1
sync_binlog                     = 1
auto_increment_increment        = 1
auto_increment_offset           = 1

Und startet diesen (neu).

[stextbox id=“note“ caption=“Hinweis: server-id“]Die server-id kann eine beliebige Zahl sein, sie muss aber bei jedem Server unterschiedlich sein.
Damit man also nicht ausversehen zwei hosts die gleiche server-id zuweist, nimmt man am besten dessen IP-Adresse, entfernt die Punkte und nimmt das als server-id.

Wenn also z.B. ein Server die IP-Adresse: 192.168.1.100 hat, dann wäre dessen server-id: 1921681100[/stextbox]

Nun wird ein Benutzer für den slave angelegt:

[root@MASTER ~]# mysql -uroot -p
mysql> GRANT REPLICATION SLAVE ON . TO 'slave'@'%' IDENTIFIED BY 'topsecret';

Slave

Auf dem slave müssen die folgenden Optionen gesetzt werden:

[mysqld]
server-id                       = 2
relay-log                       = mysqld-relay-bin
report-host                     = slave-server01
auto_increment_increment        = 2
auto_increment_offset           = 2
replicate-do-db                 = DB1
replicate-do-db                 = DB2
slave_max_allowed_packet        = 16M
read_only                       = 1

[stextbox id=“note“ caption=“Hinweise“]
auto_increment_increment und auto_increment_offset
Diese Parameter sollten idealerweise einen anderen Wert haben als alle anderen Server, da es sonst Probleme bei den AUTO-INCREMENT Werten geben könnte.

replicate-do-db
Hier wird angeben welche Datenbanken repliziert werden.
ACHTUNG: Für jede Datenbank muss zwingend eine neue Zeile verwendet werden! So etwas wie: „replicate-do-db = DB1, DB2“ würde nicht funktionieren!

slave_max_allowed_packet
Dieser Wert darf beim slave nicht kleiner sein als die Einstellung: read_buffer_size auf dem Server, sonst kann es zu Problemen kommen[/stextbox]

Nun kann man auch den slave starten.

Allerdings müssen nun zuerst die Initial-Daten auf den SLAVE geladen werden.
Dazu erstellen wir auf dem master ein mysqldump:

[root@MASTER ~] mysqldump -uroot -p --master-data --databases DB1 DB2 > slave.sql

Dieses slave.sql wird nun auf den SLAVE Server kopiert und eingespielt, nachdem zuvor die SLAVE-Replikation gestoppt wurde:

[root@SLAVE ~] mysql -uroot -p
mysql> SLAVE STOP;
mysql> quit
 
[root@SLAVE ~] mysql -uroot -p < slave.sql
[root@SLAVE ~] mysql -uroot -p
mysql> CHANGE MASTER TO MASTER_HOST='master-server', MASTER_USER='slave', MASTER_PASSWORD='topsecret';
mysql> SLAVE START;
mysql> SHOW SLAVE STATUS \G;
mysql> quit

Im SLAVE STAUS kann man nun sehen ob die Replikation läuft:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

[stextbox id=“note“ caption=“Slave-Replikation kaputt?“]Es kann ab und zu vorkommen, dass die Replikation auf den slave nicht mehr funktioniert.

Dann reicht es aber, den letzten Schritt (mysqldump auf master laden und auf slave einspielen) zu wiederholen und alles sollte wieder laufen.

Falls das nicht funktioniert muss man auf dem master vor dem dump die Tabellen locken:

[root@SLAVE ~] mysql -e 'slave stop;'
 
[root@MASTER ~] mysql -uroot -p
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS \G
mysql> SYSTEM mysqldump -uroot -p --master-data --databases DB1 DB2 > slave.sql
mysql> UNLOCK TABLES;
mysql> quit

Danach auf dem slave einfügen und MASTER_LOG_FILE / MASTER_LOG_POS mit den Werten aus der Ausgabe vom master füllen:

[root@SLAVE ~] mysql -uroot -p < slave.sql
[root@SLAVE ~] mysql -uroot -p
mysql> CHANGE MASTER TO MASTER_HOST='master-server', MASTER_USER='slave', MASTER_PASSWORD='topsecret', MASTER_LOG_FILE='mysql-bin.000000', MASTER_LOG_POS='00000000';
mysql> SLAVE START;
mysql> SHOW SLAVE STATUS \G
mysql> quit
[root@SLAVE ~] mysql -e 'show slave status\G'

[/stextbox]

Troubleshooting

Slaves klonen

Hat man mehrere slaves und einer fällt aus der Synchronisation (etwa weil ausersehenen auf den slave geschrieben wurde), kann man diesen von einem anderen klonen:

[root@SLAVE1 ~] systemctl stop mysql
[root@SLAVE1 ~] cp -pvR /var/lib/mysql /var/lib/mysql.bak
[root@SLAVE1 ~] rsync -ahv --delere slave2:/var/lib/mysql/ /var/lib/mysql/
[root@SLAVE1 ~] cp -v /var/lib/mysql.bak/data/auto.cnf /var/lib/mysql.bak/data/auto.cnf
[root@SLAVE1 ~] systemctl start mysql

[stextbox id=“warning“ caption=“Achtung gleiche UUID“]
Nebst der server_id, welche einen slave eindeutig kennzeichnet, generiert mysql noch eine UUID für jeden slave, welche in der Datei: auto.cnf im mysql Datenverzeichnis abgelegt wird.
Diese darf beim synchronisieren nicht mit kopiert-, bzw. muss danach entweder gelöscht (danngeneriert mysql eine neue) oder vom Backup rüber kopiert werden.
Ansonsten bekommt man die Meldung: „Slave I/O thread: Failed reading log event“.
[/stextbox]

Quellen