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

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 Volumes haben sich als praktischen Standard für das Volume Management etabliert.
Doch irgendwann ist die zugrunde liegende Disk voll und muss vergrössert werden, was in virtuellen Umgebungen ganz einfach ist.

Für die nachfolgende Vergrösserung der Physical Volumes gibt es verschiedene Vorgehensweisen, welche hier beleuchtet werden.

Continue reading LVM: Physical Volume vergössern

LVM: Physical Volume entfernen

Manchmal merkt man, dass man eine Disk „zu viel“ in der VG hat und diese anderweitig verwenden möchte.

Mittels pvmove kann man die Daten von einer Disk (physical volume) auf andere in der gleichen volume group (VG) verschieben, danach kann man mittels vgreduce die Disk aus der VG entfernen und schliesslich mit pvremove das physical volume komplett entfernen.

Das ganze sieht so aus:

pvmove /dev/sdX
vgreduce <volume_group> /dev/sdX
pvremove /dev/sdX

Achtung: Möchte man danach die Festplatte im laufenden Betrieb „physisch“ aus dem System entfernen, muss man vorher ebenfalls die System-Referenzen entfernen!

Gewaltsamer Reset

In gewissen Situation muss man ein system mit einem hängenden Prozess neu starten, weiss aber, dass es mit dem normalen "reboot" Kommando beim herunterfahren hängen bleiben wird. Dies passiert z.B. besonders häufig bei Filesystem-Prozessen, die vom Kernel ausgeführt werden und sich somit nicht "killen" lassen, wie copy, rsync, nfs, usw.

Somit hilft dann nur noch der "Hard Reset", bei dem man jedoch physischen Zugang zum Server haben muss.

Hat man diesen gerade nicht gibt es noch eine andere Möglichkeit, das System sofort neu zu starten, ohne durch den Prozess des "herunterfahrens" zu gehen: Über das in den Linux-Kernel integrierte sysrq-Interface.

Dies schaltet man zuerst mittels:

echo s > /proc/sysrq-trigger

an und löst dann den "brutalen" reset über:

echo b > /proc/sysrq-trigger

aus.

Quellen:

c’t: [http://www.heise.de/ct/hotline/Gewaltsamer-Reset-unter-Linux-321064.html|Gewaltsamer Reset unter Linux]

Gebräuchliche OpenSSL Befehle

Allgmeine OpenSSL Befehle

Diese Kommandos dienen zum erstellen von CSRs, Zetifikaten, PrivateKeys und anderen verschiedenen Dingen.

PrivateKey erstellen

openssl genrsa -out example.com.key 4096

Zertifikat erstellen

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt

CSR erstellen

openssl req -out CSR.csr -key privateKey.key -new

Siehe dazu auch: SSL CSR erstellen für weitere Optionen, wie z.B: ein CSR für ein SAN Zertifikat.

CSR aus bestehendem Zertifikat erstellen

Hat man keinen CSR zum ursprünglich angelegten Zertifikat mehr, lässt sich das einfach aus dem bisherigen Zertifikat und Key erstellen:

openssl x509 -x509toreq -in certificate.crt -signkey privateKey.key -out $CSR.csr 

Neuer PrivateKey aus altem erstellen

openssl rsa -in privateKey.pem -out newPrivateKey.pem

Neuer CSR inklusive key erstellen

openssl req -new -newkey rsa:4096 -nodes -keyout www.example.com.key -out www.example.com.csr -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"

Neues selbst signiertes Zertifikat inklusive key erstellen

openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout www.example.com.key -out www.example.com.crt

Überprüfen mit OpenSSL

Zertifikate, CSRs oder PrivateKeys überpüfen:

Certificate Request (CSR) prüfen

openssl req -text -noout -verify -in CSR.csr

PrivateKey prüfen

openssl rsa -check -in privateKey.key

Zertifikat anschauen

openssl x509 -text -noout -in certificate.crt

Einzelne Felder aus dem Zertifikat ausgeben

openssl x509 -enddate -noout -in certificate.crt
openssl x509 -subject -noout -in certificate.crt

PKCs12 file prüfen

openssl pkcs12 -info -in keyStore.p12

Debuggen mit OpenSSL

Falls man einen Fehler bekommt wie: „private doesn’t match the certificate“ oder einem installierten Zertifikat wird nicht vertraut, dann kann man das mit diesem Kommandos herausfinden.

Prüfen ob ein Zetifikat (.crt) zu einem Schlüssel (.key) passt

openssl x509 -noout -modulus -in certificate.crt | openssl md5; openssl rsa -noout -modulus -in privateKey.key | openssl md5; openssl req -noout -modulus -in CSR.csr | openssl md5

(alle md5-summen müssen gleich sein)

Mit der Website verbinden und Zertifikat sehen

openssl s_client -connect www.paypal.com:443

Hinweis: Bei der Verwendung von name based virtualhosts mittels SNI muss zusätzlich noch der Parameter -servername angefügt werden:

openssl s_client -servername www.paypal.com -connect www.paypal.com:443

Konvertieren mit OpenSSL

Mit den folgenden Kommandos kann man Zertifikate und Schlüssel in andere Format konvertieren um diese mit spezifischen Server- und Software- typen kompatibel zu machen.
z.B. eine normale PEM Datei, welche mit apache funktionieren würde in eine PFX (PKCS#12) Datei umwandeln und mit Tomcat oder IIS zu benutzen.

DER nach PEM

openssl x509 -inform der -in certificate.cer -out certificate.pem

PEM nach DER

openssl x509 -outform der -in certificate.pem -out certificate.der

PKCS12/PFX (.p12/.pfx) nach PEM

openssl pkcs12 -in keyStore.pfx -out keyStore.pem -nodes

(You can add -nocerts to only output the private key or add -nokeys to only output the certificates)

PEM nach PKCS12/PFX (.p12/.pfx)

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

Quelle: SSLShopper: The Most Common OpenSSL Commands

CA erstellen und mit dieser ein Zertifikat erstellen

Mit den nachfolgenden Befehlen kann man schnell eine CA erstellen udn damit ein Zertifikat signieren:

# Key erstellen
openssl genrsa -out ca.key 2048
# Root-CA Zertifikat mit diesem key erstellen
openssl req -x509 -new -nodes -key ca.key -sha256 -days 1024 -out ca.crt

## Zertifikat für domain: "example.org" erstellen
# Key für cert erstellen:
openssl genrsa -out example.org.key 2048
# CSR mit diesem key erstellen
openssl req -new -key example.org.key -out example.org.csr
# Zertifikat erstellen und mit der Root-CA signieren:
openssl x509 -req -in example.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out example.org.crt -days 500 -sha256

Nützliche aliase für bash

Wenn man in bash aliase anlegt kannt man die, doch recht schwierig zu merkenden Kommandos abkürzen:

alias csrview='openssl req -text -noout -verify -in'
alias crtview='openssl x509 -text -noout -in'
alias sslkeygen='openssl genrsa 4096 -out'

Nützliche Shell Scripts

Diese Scripts kann man im ~/bin/ Verzeichnis ablegen zum einfachen aufrufen.

checkcert
Zeigt die Checksummen von KEY, CRT und CSR an, damit man sofort sieht ob diese zusammenpassen.

#!/bin/bash

DOMAIN=$1
if [ -z "$DOMAIN" ]; then
  echo "usage: $0 <domain.tld>"
  exit 1
fi

if [ "$DOMAIN" != "" ]; then
  if [ -f  $DOMAIN.crt ]; then
    echo -n "CRT: "; openssl x509 -noout -modulus -in $DOMAIN.crt | openssl md5
  fi
  if [ -f  $DOMAIN.key ]; then
    echo -n "KEY: "; openssl  rsa -noout -modulus -in $DOMAIN.key | openssl md5
  fi
  if [ -f  $DOMAIN.csr ]; then
    echo -n "CSR: "; openssl  req -noout -modulus -in $DOMAIN.csr | openssl md5
  fi
fi

Festplatten im laufenden Betrieb entfernen („hot-remove“)

Will man unter Linux eine Disk „hot removen“, also im laufenden Betrieb herausziehen, muss man danach auch die Referenzen auf das Device entfernen.

Macht man dies nicht und „reisst die Disk einfach heraus“, erhält man solche unschönen Fehler im messages log, bzw. mit dmesg:

end_request: I/O error, dev sdd, sector 209715192
sd 0:0:3:0: SCSI error: return code = 0x00010000
end_request: I/O error, dev sdd, sector 0
sd 0:0:3:0: SCSI error: return code = 0x00010000
end_request: I/O error, dev sdd, sector 0

oder im LVM:

[root@server ~]# vgs
  /dev/sdd: read failed after 0 of 4096 at 0: Input/output error
  VG     #PV #LV #SN Attr   VSize   VFree
  [...]

Um die Festplatte im laufenden Betrieb richtig entfernen zu können, muss man nebst dem obligatorischen korrektem unmounten / aus der VG removen / pvremove / usw. folgendes tun um die System-Referenz auf das Device entfernen:

echo 1 > /sys/block/<DEVICE>/device/delete

Wobei <DEVICE> hier mit dem Device-Namen ersetzt werden muss, in unserem Fall z.b. „sdd“.

Man kann diese Prozedur im übrigen auch machen, wenn man die Festplatte schon heraus gezogen hat, um diese Meldungen verschwinden zu lassen. (:wink:)

Quellen

Mehrere Linux Konsolenfenster mit screen

Auch in einem Linux Terminal kann man mehrere "Fenster" haben – Und das praktische dabei ist: Diese laufen automatisch weiter, wenn man sich aus der aktuellen SSH Session ausloggt! (:wink:)

Möglich wird dies mit dem Programm "screen", einem sogenannten "Terminal-multiplexer".

[stextbox id=“note“ caption=“Hinweis“]screen gilt mittlerweile als veraltet und ausserdem ist die Entwicklung tot.
Als bessere alternative wird tmux angesehen, welches jedoch sehr ähnlich funktioniert und die Bedienung von dieser Seite abgeleitet werden kann.[/stextbox]

Zum Benutzen gibt man in der Linux Session einfach "screen" ein.

Hier kann man dann ganz normal Programme laufen lassen. Will man sich nun aus dieser screen-session ausloggen, drückt man CTRL+A und gibt dann: "d" (für dettach) ein. Und schon ist man wieder in der normalen Linux shell, wo man sich nun aus- und nach dem einloggen das laufende Programm einfach mit "screen -r" (re-attach) zurückholen kann.

Die Bedienung von screen erfolgt im allgemeinen immer mittels: [[CTRL]+a, gefolgt von einem Buchstaben als Befehl; also ähnlich wie ESC beim vi.

Die folgenden Befehle sind in einer screen session sehr nützlich:

  • [[CTRL]+a c

[c]reate, erzeugt ein neues screen Fenster.

  • [[CTRL]+a n

[n]ext, springt zum nächsten screen Fenster.

  • [[CTRL]+a p

[p]revious, springt zum vorherigen screen Fenster

  • [[CTRL]+a #

Das # steht für eine Nummer, mit der man direkt zum entsprechenden Terminal springen kann. Das erste Fenster startet ab 0, welches also mittels CTRL+a 0 erreicht werden kann.

  • [[CTRL]+a A

Damit kann man dem Fesnter einen Namen geben

  • [[CTRL]+a "

Eine Übersicht aller screen Fenster anzeigen

  • [[CTRL]+a K

[K]ill, schliesst das screen Fenster und beendet die darin laufenden Programme.

  • [[CTRL]+a S

[S]plit, erzeugt einen horizontalen splitscreen (im neuen screen muss noch mit [CTRL]+a c ein neues Fenster erzeugt werden)

  • [[CTRL]+a |

Wie oben, aber mit einem horizontalem splitscreen

  • [[CTRL]+a [[TAB]

Wechselt zwischen den splitscreens

  • [[CTRL]+a X

Schliesst den aktuellen splitscreen

  • [[CTRL]+a Q

Schliesst alle splitscreens

Quellen

linux screen terminal
Screen auf wiki.archlinux.de