Mit column File-Tabellen sauber halten

Wenn man wieder mal "unsortierte" files, wie beispielsweise /etc/fstab hat, kann man diese mit dem Programm "column" ganz einfach sortieren:

column -t /etc/fstab

Weitere Infos: [http://unix.stackexchange.com/questions/96037/how-to-align-fstab-entries-easily|How to align fstab entries easily]

iptables: Regeln dynamisch einfügen und löschen

iptables Regeln werden normalerweise in einem file (z.B. /etc/sysconfig/iptables-rules) konfiguriert.

Was aber, wenn man im laufenden Betrieb eine Regel temporär hinzufügen und wieder löschen möchte?

Denn mit der Standardmässigen "append-option" (iptables -A) klappt das nicht immer, da die Regeln der Reihe nach abgearbeitet werden.

Man kann jedoch mittels -I und -D die Regeln [I]nserten oder [D]eleten. Dazu kann man noch eine Zeilennummer eingeben, z.B.:

iptables -I INPUT 5 -i eth0 -p tcp --dport 443 -j ACCEPT

Diese Regel kann man nun entweder wieder löschen indem man dieselbe wieder aufruft mit -D anstatt -I und ohne Zeilennummer:

iptables -D INPUT -i eth0 -p tcp --dport 443 -j ACCEPT

oder mittels der Zeilennummer:

iptables -D INPUT 5

Die Zeilennummern kann man sich mit dem Parameter –line-numbers anzeigen lassen:

iptables -L --line-numbers
iptables -L INPUT --line-numbers

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 zweiteren 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.

Eine entsprechende .htaccess könnte z.B. so aussehen:

# Access is either granted if the hostname is trusted, OR
# if password authentication succeeds (Satisfy Any)
#
# SYNTAX:
# "Allow from" can be single- or multi line, i.ex.:
# Allow from <host1> <host2>
# or:
# Allow from <host1>
# Allow from <host2>
 
Order deny,allow
Deny from all
Allow from  myhost.example.org
Allow from  192.168.0.50
AuthType Basic
AuthName "Untrusted source IP access"
AuthUserFile /path/to/.htpasswd
AuthGroupFile /dev/null
#Require group staff
require valid-user
Satisfy Any

Kommt man nun entweder mit dem Hostnamen "myhost.example.org" oder der IP: "192.168.0.50" daher, erreicht man direkt die Webseite; bei allen anderen Quell-IPs kommt stattdessen der HTTP-Password Dialog, wo man nach erfolgreicher Anmeldung weiter kommt.

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).

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

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
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

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
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'

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
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“.

Quellen

Boot-Laufwerk auf andere Festplatte verschieben

Die Partition der /boot Festplatte wird häufig relativ klein gemacht, häufig auch etwas "zu"-klein, denn neuere Linux Distributionen brauchen für die Kernel-History gerne mal über 200MB.

Doch was tun, wenn die /boot Partition zu klein wird? – Neue erstellen und das boot Laufwerk verschieben!

Hier wird beschrieben wies geht.

Wir gehen her davon aus, dass:
/dev/sda1 die alte und
/dev/sdb1 die neue Platte/Partition ist.
Die neue boot Partition sollte ausserdem bereits mit fdisk/cfdisk formatiert und mit dem "bootable" flag markiert sein.

Zur Sicherheit ändern wir erst nur das label der alten boot Platte (/boot wird in fstab meist nach label gemountet) und passen den fstab Eintrag ggf. an.
Erst wenn die neue Partition in Betrieb ist, kann die alte gelöscht werden:

tune2fs -L/oldboot /dev/sda1
# ggf. Eintrag in /etc/fstab anpassen

Nun erstellen wir das filesystem der neuen Partition:

mke2fs -j -L /boot /dev/sdb1

Als nächstes werden die beiden Partition gemountet und synchronisiert:

umount /boot
mkdir -pv /mnt/{sda1,sdb1}
mount /dev/sda1 /mnt/sda1
mount /dev/sdb1 /mnt/sdb1
rsync -ahv --numeric-ids --delete /mnt/sda1/ /mnt/sdb1/

Zum Schluss muss man noch mittels grub den boot Sektor auf die neue Disk schreiben:

grub
grub> device (hd1) /dev/sdb
device (hd1) /dev/sdb
grub> root (hd1,0)
root (hd1,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd1)
setup (hd1)
 Checking if "/boot/grub/stage1" exists... no
 Checking if "/grub/stage1" exists... yes
 Checking if "/grub/stage2" exists... yes
 Checking if "/grub/e2fs_stage1_5" exists... yes
 Running "embed /grub/e2fs_stage1_5 (hd1)"...  15 sectors are embedded.
succeeded
 Running "install /grub/stage1 (hd1) (hd1)1+15 p (hd1,0)/grub/stage2 /grub/grub.conf"... succeeded
Done.
grub> quit

Nach einem Reboot sollte die neue boot Partition aktiv sein!

Ressourcen

LVM: Physical Volume vergössern

Physical volume als ganze Disk

Hat man eine Virtualisierte Maschine (z.B. VMware) und im LVM die Physical Volumes als ganze Disks hinzugefügt (z.B. /dev/sdb/, anstatt /deb/sdb1), kann man diese einfach vergrössern, indem man in der VM die Festplatte vergrössert, diese dann mit dem blockdev Kommando in Linux einliesst und mit pvresize vom LVM erkennen lässt:

blockdev --rereadpt /dev/sdX
pvresize /dev/sdX

Physical voume als Partition

Besteht das Physical Volume hingegen aus einer Partition (z.B. /dev/sdb1) und es ist die letzte in der Reihenfolge, so gibt es einen einfachen Trick: Die Partition entfernen und danach neu erstellen. Das klingt zwar etwas beängstigend, funktioniert aber: 😉

Achtung: Bevor man an der Partitionstabelle manipuliert ist es anzuraten vorher einen snapshot der VM zu machen und oder die Schritte vorher auf einer Test-VM auszuprobieren!

fdisk /dev/sdX
 
Command (m for help): p
 
Disk /dev/sdX: 8589 MB, 8589934592 bytes, 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00015b7c
 
    Device Boot      Start         End      Blocks   Id  System
/dev/sdX1   *        2048     1026047      512000   83  Linux
/dev/sdX2         1026048    10485759     4729856   8e  Linux LVM
 
 
Command (m for help): d
Partition number (1,2, default 2): 
Partition 2 is deleted
 
 
Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
 
Partition number (2-4, default 2): 2
First sector (1026048-16777215, default 1026048): 
Using default value 1026048
Last sector, +sectors or +size{K,M,G} (1026048-16777215, default 16777215): 
Using default value 16777215
Partition 2 of type Linux and of size 7.5 GiB is set
 
 
Command (m for help): t
Partition number (1,2, default 2): 2
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'
 
 
Command (m for help): w
The partition table has been altered!
 
Calling ioctl() to re-read partition table.
 
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

Nun muss noch die Partitionstabelle neu eingelesen werden, dies geht nur mit partx:

partx -u /dev/sdX

Nun kann man mit pvscan und pvresize das Volume vergrössern:

pvscan
pvresize /dev/sdX

Pysical volume als Partition (alternative)

Alternativ kann man auch eine neue Festplatte hinzufügen, die grösser oder gleichgross ist als die andere, die Daten auf der alten dann mit pvmove auf die neue/grössere verschiebt und danach die alte entfernen.

Quellen