# cat /etc/udev/rules.d/local-interfaces.rules
KERNEL="eth*", SYSFS{address}="00:48:54:55:00:00", NAME="heimnetz"
Jetzt überall eth0 durch heimnetz ersetzen:
find /etc/ -type f -exec grep -He 'eth0' '{}' ';'
Und das Netzwerkinterface hat ab jetzt einen statischen Namen.
Echtzeitanwendungen wie z.B. VOIP werden davon ungemein profitieren:
Skript um Prioritäten für den Datenverkehr festzulegen.
Wenn man zwei Rechner (oder zwei Netzwerke (oder einen Rechner mit einem Netzwerk)) über eine unsichere Strecke verbinden möchte bietet sich der Einsatz eines
VPN an. Die Ausgangssituation sieht dann etwas so aus:
( NET_1 )-[IP__1]~~~~~~~~~[IP__2]-( NET_2 )
- Wo liegt setkey (aus den ipsec-tools Tools)
SK="/usr/sbin/setkey"
- Welches Passwort soll benutzt werden:
PASS1="aaaaaaaaaaaaaaaaaaaaaaaa"
PASS2="bbbbbbbbbbbbbbbbbbbbbbbb"
Unbedingt ein eigenes ausdenken oder
pwgen -s 24 2
benutzen.
- IP Adressen der Gateways und dahinterliegendes Netzwerk angeben. Hier ist 1 ein Gateway zu ganzen Welt und 2 nur ein einzelner Rechner ohne dahinterliegendes Netzwerk.
IP__1="10.0.0.1"
NET_1="0.0.0.0/0"
IP__2="10.0.1.1"
NET_2="10.0.1.1/32"
- Jetzt die beiden Passwörter den beiden IP Adressen zuweisen, den Tunnel aufbauen und alle nicht verschlüsselten Pakete ab jetzt ablehnen (das ist Gateway 1):
echo "
flush;
spdflush;
add $IP__1 $IP__2 esp 12340 -m tunnel -E 3des-cbc \"$PASS1\";
add $IP__2 $IP__1 esp 12341 -m tunnel -E 3des-cbc \"$PASS2\";
spdadd $IP__2 $NET_1 any -P in ipsec esp/tunnel/$IP__2-$IP__1/require;
spdadd $NET_1 $IP__2 any -P out ipsec esp/tunnel/$IP__1-$IP__2/require;
" | "$SK" -c
Auf Gateway 2 ist nur "in" und "out" vertauscht:
echo "
flush;
spdflush;
add $IP__1 $IP__2 esp 12340 -m tunnel -E 3des-cbc \"$PASS1\";
add $IP__2 $IP__1 esp 12341 -m tunnel -E 3des-cbc \"$PASS2\";
spdadd $IP__2 $NET_1 any -P out ipsec esp/tunnel/$IP__2-$IP__1/require;
spdadd $NET_1 $IP__2 any -P in ipsec esp/tunnel/$IP__1-$IP__2/require;
" | "$SK" -c
IPsec HOWTO
/etc/fstab: /dev/foo /mnt/bar ext3 defaults,usrquota 0 2
mount /dev/foo /mnt/bar -o remount
quotacheck -acguvm
quotacheck -cguvm /mnt/bar
edquota -u USERNAME
edquota -u USERNAME -f /dev/foo
edquota -p USERNAME -u USERNAME2 -f /dev/foo
edquota -t
quotaon -avug
quotaoff -avug
repquota -a
su USERNAME -c 'quota -v'
Als erstes Partitionen mit dem Dateisystemtyp fd anlegen, z.B. /dev/sda1 und /dev/hda1
mdadm --create /dev/md0 --verbose --level=raid1 --raid-devices=2 /dev/hda1 /dev/sda1
mdadm --create /dev/md1 --verbose --level=raid5 --raid-devices=3 /dev/hda5 /dev/sda5 /dev/sdb5
mdadm --create /dev/md1 --verbose --level=raid5 --chunk=128 --raid-devices=3 /dev/hda5 /dev/sda5 /dev/sdb5
Wenn man noch nicht alle Platte zur Verfügung hat, die in das Raid sollen, kann man statt der Partitionen auf der noch fehlenden Platte auch missing angeben.
mdadm --create /dev/md0 -vv --level=raid1 --raid-devices=2 /dev/sda1 missing
Falls dieser Fehler kommt
mdadm: error opening /dev/md0: No such device or address
und das Device wirklich vorhanden ist, wurde vermutlich das Modul md noch nicht geladen.
Wichtig, die Ausgabe von
mdadm --detail --scan
muss in die Datei /etc/mdadm/mdadm.conf eingepflegt werden.
Kommt es zum Ausfall einer Platte, kann man so sehen, welche Partitionen noch aktiv sind
cat /proc/mdstat
mdadm --detail /dev/md0
So kann man Partitionen auf Ihre (ehemalige) Raidzugehörigkeit überprüfen
mdadm -Q /dev/hda1 /dev/hda1: device 0 in 2 device mismatch raid1 /dev/md0. Use mdadm --examine for more detail.
Hat man wieder eine funktionierende Platte, kann man so wieder eine Partition hinzufügen
mdadm --manage --add /dev/md0 /dev/hda1
Kommt es dabei zu einem dieser Fehler
mdadm: add new device failed for /dev/hda1 as 2: No space left on device
mdadm: add new device failed for /dev/hda1 as 2: Invalid argument
ist die Partition möglicherweise zu klein für das Raid. Kann man aber leicht selbst überprüfen
cat /proc/partitions
Ein Raid kann auch in der Größe verändert werden (Anzahl genutzten Partitionen / genutzte Größe der beteiligten Partitionen)
mdadm /dev/md1 --grow --raid-devices=4
mdadm /dev/md1 --grow --size=max
Nach einem temporären Ausfall einer Platte aus einem Raid5 Verbund, hatte ich mal das Problem, dass das Raid nicht mehr automatisch gestartet wurde. Das Vorgehen war (aus der Erinnerung):
- Bei Bedarf von CD booten (z.B. Knoppix)
/etc/init.d/mdadm start
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
/etc/init.d/mdadm-raid restart
- Mit
dmesg
mdadm --detail /dev/mdX
nachsehen, wo das Problem ist
- Obwohl nur eine Platte ausgefallen war, ließ sich das Raid nicht starten
raid5: cannot start dirty degraded array for md1
- Geholfen hat schließlich, das Array mit Gewalt erneut zusammen bauen zu lassen
mdadm --assemble --scan --run --force
So kann man den Fortschritt beim Abgleich verfolgen
watch -n5 cat /proc/mdstat
Wenn der Vorgang zu lange dauert kann man die Rate erhöhen, mit der der Abgleich mindestens stattfindet, z.B. auf 50MB/s erhöhen
echo 50000 >/proc/sys/dev/raid/speed_limit_min
So kann man eine Partition aus einem Raid herausnehmen (z.B. wenn man eine Platte tauschen möchte)
mdadm --fail /dev/md0 /dev/hda1
mdadm --remove /dev/md0 /dev/hda1
So hält man ein laufendes Raid an
mdadm --stop /dev/md1
So entfernt man das Raid dauerhaft von einer Partition
mdadm --zero /dev/hda5
Wenn man von einen Raid1 bootet, ist es wichtig, den Bootmanager auf beiden Platten zu installieren. Für den Bootmanager tun wir so, als wären die beiden Platten kein Raid, sondern normale Partitionen.
Zuerst beide Platten in die Datei
/boot/grub/device.map
eintragen. Eine als hd0, die andere als hd1. Dann grub starten, das Device angeben aufdem /boot liegt (,0 bedeutet 1. Partition) und den Bootsektor auf die beiden Platten schreiben
root (hd0,0) setup (hd0)
root (hd1,0) setup (hd1)
Nacheinandern versuchen nur mit jeweils eine der beiden Platten zu booten. Dazwischen aber wieder einen intakten Zustand des Raids herstellen.
LVM Howto
PV PV PV (e.g., /dev/hda, /dev/hdb5, /dev/sdb3)
\ | /
\|/
VG (e.g., MYLVMVOLUME1)
/|\
/ | \
LV LV LV (e.g., /mnt/mydata, /mnt/moredate)
# pvcreate /dev/sdb1
# pvdisplay -m /dev/sdb1
--- Physical volume ---
PV Name /dev/sdb1
...
Allocated PE 54206
# vgcreate MYLVMVOLUME1 /dev/hda /dev/hdb5
# vgchange -a y MYLVMVOLUME1
# vgchange -a n MYLVMVOLUME1
# vgremove MYLVMVOLUME1
# vgextend my_volume_group /dev/sdb3
(z.B. wenn man eine alte Platte entfernen möchte)
Reicht der Platz auch ohne das PV?
# pvscan
# pvdisplay /dev/hda
Ansonsten vorher (wie oben beschrieben) erst ein neues PV hinzufügen
- Festplatte / Partition vorbereiten
- Ein neues PV zum VG hinzufügen
Jetzt
Backups der Daten erstellen!
Man braucht folgende Kerneloption
CONFIG_DM_MIRROR
Jetzt kann man alles von der alten Platte auf die anderen PV verschieben lassen
# pvmove /dev/hda
Man kann auch gezielt eine Ziel PV angeben
# pvmove /dev/hda /dev/hde3
Schließlich kann man die PV entfernen
# vgreduce MYLVMVOLUME1 /dev/sdb3
# pvremove /dev/sdb3
Der Befehl pvmove erfordert natürlich, dass insgesamt genügend Platz auf der VG noch nicht durch LV belegt ist. Allerdings kann er ohne Hilfe auch dann nicht den Inhalt eines PV verschieben, wenn es keine andere einzelne PV gibt, die es komplett aufnehmen kann.
Will man z.B. dieses sdb1
# pvcreate /dev/sdb1
# pvdisplay -m /dev/sdb1
--- Physical volume ---
PV Name /dev/sdb1
...
Allocated PE 54206
verschieben, es gibt aber kein anderes PV, welches es komplett aufnehmen könnte, geht das schief
# pvmove /dev/sdb1
Insufficient suitable contiguous allocatable extents for logical volume pvmove0: 43955 more required
Man kann ihm aber helfen. Mit pvdisplay das PV aus dem VG mit dem größten Wert für Free PE aussuchen. Hier ist das z.B. sda6
# pvdisplay
--- Physical volume ---
PV Name /dev/sda6
...
Free PE 33267
Allocated PE 0
Jetzt kann man pvmove anweisen 33267 PE dorthin zu verschieben
# pvmove /dev/sdb1:0-33267 /dev/sda6
Falls auf dem Ziel danach noch Platz ist, einfach den Befehl mit einer neueren oberen Grenze wiederholen. Sobald das Ziel dann wirklich voll ist verschiebt man den nächsten Block
# pvmove /dev/sdb1:33268-40000 /dev/hda6
auf ein anderes PV auf dem noch Platz ist. Sollte Teile aus dem Bereich bereits verschoben sein, werden sie ignoriert, das hier
# pvmove /dev/sdb1:0-40000 /dev/hda6
würde also jetzt das gleiche erreichen, weil der Bereich davor sowieso schon komplett verschoben ist.
Durch dieses Verschieben kann es dazu kommen, dass die LV fragmentieren. Eine bessere Variante funktioniert so, dass man eine Sicherung der LVM Struktur erstellt
vgcfgbackup
und sich unter
/etc/lvm/backup
die Struktur des LV ansieht. Hat man z.B. folgendes
segment2 {
start_extent = 1
extent_count = 250 # 1000 Megabytes
type = "striped"
stripe_count = 1 # linear
stripes = [
"pv2", 25346
]
}
Unter stripes kann man das Quelldevice und den Startpunkt entnehmen
pv2
25346
Das hier gibt die Länge an
extent_count = 250
Jetzt sucht man in der Datei welches Device sich unter pv2 verbirgt (in diesem Beispiel sda6) und kann das Segment dann komplett auf ein anderes Device verschieben.
pvmove -v /dev/sda6:25346-`echo 25346 - 1 + 250 | bc` /dev/sdb6
verschiebt man sie in der richtigen Reihenfolge hintereinander auf das gleiche Device, verschmelzen zwei Segmente eines LV automatisch wieder zu einem.
Wieviel Platz steht noch zur Verfügung?
# vgdisplay MYLVMVOLUME1
LV mit 1,5GB erstellen, linear
# lvcreate -L1500 -n MYDATA MYLVMVOLUME1
LV mit 1,5GB erstellen, stripped
# lvcreate -i2 -I4 -L500 -n MOREDATA MYLVMVOLUME1
LV mit 1,5GB erstellen, linear und nur /dev/hdb5 benutzen
# lvcreate -L1500 -n FASTDATA MYLVMVOLUME1 /dev/hdb5
Dateisystem darauf erstellen
# mkfs.ext3 /dev/MYLVMVOLUME1/FILESYSTEM1
-L NAME
-O dir_index
-T news
-T largefile
-m 0
-N 250000
tune2fs -c 31
# lvremove /dev/MYLVMVOLUME1/FASTDATA
Wieviel Platz ist noch verfügbar?
# vgdisplay MYLVMVOLUME1
Um +1 GB vergrößern (negative Zahlen werden weiter unten diskutiert, Vorsicht!)
# lvextend -L+1G /dev/MYLVMVOLUME1/MYDATA
Jetzt das Dateisystem vergrößern (ext2 / ext3)
# umount /dev/MYLVMVOLUME1/MYDATA
# resize2fs -p /dev/MYLVMVOLUME1/MYDATA
# mount /dev/MYLVMVOLUME1/MYDATA
Jetzt das Dateisystem vergrößern (reiserfs, unmount kann weggelassen werden)
# umount /dev/MYLVMVOLUME1/MYDATA
# resize_reiserfs /dev/MYLVMVOLUME1/MYDATA
# mount -treiserfs /dev/MYLVMVOLUME1/MYDATA
Vor dem Verkleinern des LV das Dateisystem verkleinern!
Das hier verkleinert das Dateisystem auf (auf, nicht um!) 20GB
resize2fs -p /dev/MYLVMVOLUME1/MYDATA 20G
Dann das LV verkleinern (sicherheitshalber etwas größer auf 21GB)
lvreduce -L21G /dev/MYLVMVOLUME1/MYDATA
Falls das mit folgendem Fehler scheitert
Volume group mapper doesn't exist
hat man vermutlich das /dev/mapper/... statt dem eigentlichen dev Device benutzt.
Und jetzt das Dateisystem wieder bis an die Grenzen der Partition aufblähen um die Lücke zu füllen, die wir sicherheitshalber gelassen hatten
resize2fs -p /dev/MYLVMVOLUME1/MYDATA
Wenn man mit pvmove den Inhalt einer PV verschoben hat, die Partition dann aber löscht, bevor man sie mit vgreduce vom VG entfernt hat, scheitert der nächste Start des LVM mit unschönen Fehlermeldungen
Couldn't find device with uuid ...
Couldn't find all physical volumes for volume group ...
Wenn man sich sicher ist, dass der Inhalt der fehlenden PV nicht mehr relevant ist kann man sie auch auslassen und entfernen
vgchange -ay --partial
vgchange --removemissing
unmount
VG deaktivieren
# vgchange -an MYLVMVOLUME1
Export
# vgexport MYLVMVOLUME1
Auf dem anderen System
# vgimport MYLVMVOLUME1
# vgchange -ay MYLVMVOLUME1
mounten
Software installieren, hier Debian
# apt-get install cryptsetup
Eine Testdatei, über loopback mounten
# dd if=/dev/urandom of=testfile bs=1M count=100
# losetup /dev/loop/0 testfile
Jetzt mit LUKS verschlüsseln
# cryptsetup luksFormat /dev/loop/0
WARNING!
========
This will overwrite data on /dev/loop/0 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: GEHEIM
Verify passphrase: GEHEIM
Command successful.
# cryptsetup luksOpen /dev/loop/0 mytestfs
Enter LUKS passphrase: GEHEIM
key slot 0 unlocked.
Command successful.
# mkfs.ext3 /dev/mapper/mytestfs
# mount /dev/mapper/mytestfs /mnt/mnt/
# umount /dev/mapper/mytestfs
# cryptsetup luksClose /dev/mapper/mytestfs
Man kann auch statt einem Passwort das Geheimnis in eine Datei schreiben
# pwgen -s 500 > /mnt/usbstick/mykeyfile
# cryptsetup luksFormat /dev/loop/0 /mnt/usbstick/mykeyfile
WARNING!
========
This will overwrite data on /dev/loop/0 irrevocably.
Are you sure? (Type uppercase yes): YES
Command successful.
# cryptsetup -d /mnt/usbstick/mykeyfile luksOpen /dev/loop/0 mytestfs
# mkfs.ext3 /dev/mapper/mytestfs
# mount /dev/mapper/mytestfs /mnt/mnt/
# umount /dev/mapper/mytestfs
# cryptsetup luksClose /dev/mapper/mytestfs
Selbst wenn man das macht kann man nachträglich ein Passwort hinzufügen
# cryptsetup -d /mnt/usbstick/mykeyfile luksAddKey /dev/loop0
key slot 0 unlocked.
Enter new passphrase for key slot: FOOBAR
Verify passphrase: FOOBAR
Command successful.
Auch sonst kann man immer Passwörter hinzufügen (z.B. für andere Benutzer)
# cryptsetup luksAddKey /dev/loop0
Enter any LUKS passphrase: FOOBAR
key slot 1 unlocked.
Enter new passphrase for key slot: SECRET
Verify passphrase: SECRET
Command successful.
Jetzt muss man zum Lesen die Daten freigeben (hier mit Datei)
# cryptsetup -d /mnt/usbstick/mykeyfile luksOpen /dev/loop/0 mytestfs
key slot 0 unlocked.
Command successful.
oder mit Password
# cryptsetup luksOpen /dev/loop/0 mytestfs
Enter LUKS passphrase: SECRET
key slot 1 unlocked.
Command successful.
Jetzt kann es jeder lesen oder mounten
# mount /dev/mapper/mytestfs /mnt/mnt/
bis man es wieder verschließt
# umount /dev/mapper/mytestfs
# cryptsetup luksClose /dev/mapper/mytestfs
Man wird normalerweise richtige Devices benutzten wollen, hier eins für Swap und eins für die Datenpartition
swap: /dev/hdz6
crypt: /dev/hdz7
Die Datenpartition verschlüsseln (vorher mit zufälligen Daten füllen ist sicher sinnvoll)
cryptsetup luksFormat /dev/hdz7 /mnt/usbstick/mykeyfile
Optional ein verschlüsselte Swap Partition einrichten, wird bei jedem Reboot automatisch formatiert
/etc/crypttab
# <target device> <source device> <key file> <options>
myswap /dev/hdz6 /dev/random swap
mycrypt /dev/hdz7 /mnt/usbstick/mykeyfile luks
Nach einem Reboot sollte das Device entschlüsselt zur Verfügung stehen und muss einmalig formatiert werden
mkfs.ext3 /dev/mapper/mycrypt
Jetzt kann man es normal über die fstab mounten
/etc/fstab
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/mapper/mycrypt /mnt/mycrypt1 ext3 defaults 0 2
/dev/mapper/myswap none swap sw 0 0
Nur nicht die Schlüsseldatei verschlampen ;-)
26-01-2010 00.03
Seit einiger Zeit habe ich fast alle Dienste die auf meinem Server liefen in
Linux VServer ausgegliedert. Damit läuft fast jeder der hier aufgeführten Dienste in einer eigenen Linuxinstallation. Das hat für mich nur Vorteile:
- Die jeweiligen VServer haben nur das absolute Minimum an Paketen installiert die sie benötigen um diesen Dienst anbieten zu können. Mit debfoster und deborphan wird dieser Zustand erhalten.
- Der Zugriff auf die VServer wird durch einen Paketfilter auf dem Host beschränkt.
- Hat einer der Dienste eine Sicherheitslücke und es gelingt jemand darüber in das System einzudringen hat er nur Zugriff auf einen der VServer und nicht gleich auf alle Dienste und Daten. Zusätzlich sind die Rechte die ein VServer hat beschränkbar (CAPABILITIES).
- Auf dem Hostsystem müssen keine oder fast keine Dienste mehr laufen. damit wird es viel schwerer dieses anzugreifen.
- Das Hostsystem kann die VServer überwachen, z.B. mit Integrit
- Die VServer benutzten keinen eigenen Kernel und verbrauchen im Leerlauf kaum Resourcen. Hinzukommt dass eine Datei die auch mehreren VServer installiert ist dank vhashify nur einmal Platz auf der Festplatte belegt.
- Man kann sehr leicht Testinstallationen anlegen auf denen man Benutzern sogar root Rechte einräumen kann ohne befürchten zu müssen dass diese versehentlich wichtige Sachen beschädigen
Kernel Patch installieren und den neuen Kernel booten.
VServer Utils installieren (bezieht sich hier auf die
Debian vserver utils)
So einfach kann man einen neuen VServer aufsetzten:
# find free context id
find /etc/vservers/ -name context -exec cat '{}' ';' | sort -n
# assume 1234 is still unused
vserver foo build -m debootstrap --hostname foo.example.com --netdev eth0 --interface 10.0.1.5/32 --context 1234 -- -d etch
Das setzt einen VServer names foo mit Debian Sarge auf, der Rechner glaubt er heißt foo.example.com und er wird unter der IP-Adresse 10.0.1.5 erreichbar sein.
Einen Gentoo VServer setzt man wie folgt auf:
vserver-new mygentoo --hostname mygentoo --interface eth0:10.0.1.6 --context 1253 stage3 ./stage3-i686-20060317.tar.bz2 x86
Die Stage Datei bekommt man von einem beliebigen Gentoo Mirror, vserver-new findet man im entsprechenden vserver Paket in Gentoo. Siehe auch
Gentoo Linux-VServer Howto.
Um vhashify zu ermöglichen (ja der Ordner heißt vunify nicht vhashify):
mkdir -p /etc/vservers/foo/apps/vunify
Ordner (für alle vserver) aus dem vhashify ausschließen:
/usr/lib/util-vserver/defaults/vunify-exclude
Wenn man eine Datei nicht mehr löschen kann:
# whoami
# ls -ld foo/bar.txt
# ls -ld foo/
# lsattr foo/bar.txt
# lsattr -d foo/
# showattr foo/bar.txt
# showattr foo/
(Bei showattr sind nur die Optionen die mit große Buchstaben aufgeführt sind wirklich gesetzt)
# su
# chmod u+w foo/
# chmod u+w foo/bar.txt
# chattr -i foo/bar.txt
# setattr --~iunlink-but-not-immutable foo/bar.txt
# setattr --~iunlink-but-not-immutable foo
Meine VServer haben alle private IP-Adressen. Mit folgender iptables Zeile auf dem Hostsystem können die VServer über die IP-Adresse des Hostsystem ins Internet (die Variablen natürlich mit den passenden Werten versehen):
iptables -t nat -I POSTROUTING -s $VSERVER_NET ! -d $VSERVER_NET -j SNAT --to $EXT_IP
Wenn ein Dienst (z.B. ssh) sowohl auf dem Host als auch auf einem VServer laufen lassen will muss man verhindert dass der Dienst auf dem Host sich für alle Anfragen zuständig fühlt. Dazu bindet man den Dienst auf dem Host nur auf die IP Adresse des Hosts.
Dienste die als Deamon gestartet werden können in der Regel so konfiguriert werden, Dienste die bisher über inetd gestartet wurden müssen auf xinetd umgestellt werden. Dort geht das einfach mit
bind = 10.0.0.1
11-04-2007 12.38