Kleine und große Linux AHAs
Sascha
Dieser Benutzer hat keine Details eingegeben.
Beiträge von Sascha
SSH authorized_keys mal anders verwalten
15. Jun
Wir haben viele Admins, die sich über ihre SSH Schlüssel per root an unsere RHEL Server direkt anmelden wollen. Das root Passwort ist keinem bekannt. Durch geeignete Log Optionen in der sshd_config können finger prints der Schlüssel, die sich anmelden protokolliert werden.
Die Verwaltung der authorized_keys auf so vielen Servern war aber immer etwas mühselig, bis wir auf die Idee gekommen sind, das ganze per RPM verwalten zu lassen. Den öffentlichen Schlüsselteil verpacken wir in ein RPM mit sprechendem Namen und verteilen dieses auf die entsprechenden Systeme.
Das Verfahren hat folgende Vorteile:
- Wenn ein Admin einen neuen Schlüssel erzeugt (weil Passphrase vergessen, Schlüssel kompromittiert, …), ist die Verteilung des neuen Schlüssels durch ein neues RPM mit höherer Versionsnummer sehr einfach über die Standard System Update Mechanismen (Satellite usw.) zu realisieren.
- Wer direkten Root Zugriff hat ist leicht über die RPM Paketliste zu erkennen.
- Scheidet ein Kollege aus, muss nur sein RPM überall deinstalliert werden und schon hat er keinen root Zugriff mehr auf die Systeme.
So funktionierts:
Das Spec File für das ssh rootkey RPM findet ihr hier: ssh-rootkey-_USERNAME_.spec
Einfach überall _USERNAME_ in einen sprechenden Namen austauschen, z.B. ssh-rootkey-hsimpson.spec und die SSHKEY_-Variablen mit den Schlüsselinformationen bestücken und das Spec file ist fertig.
Ein rpm -bb erzeugt dann das entsprechende RPM. Ab ins System Management Tool, auf die Systeme installiert und schon hat der Admin mit seinem Schlüssel Zugriff auf das System.
Ein Drahtsieb wird beobachtet
28. Apr
Das Drahtsieb (-> LEO), besser bekannt als screen, lässt sich hervorragend dazu verwenden, seine Konsole mit anderen Benutzern zu teilen. Das ist dann hilfreich, wenn man remote auf einem System ist und einem Kollegen seine Arbeit auf der Shell zeigen möchte.
Screen zählt zu den Standardpaketen und kann mit yum install screen unter Red Hat oder Centos einfach installiert werden.
Derselbe Benutzer
User zort startet eine screen Session mit:
screen
Der Kollege meldet sich mit demselben Benutzer, also zort an und hängt sich dann mit
screen -x
auf die gerade gestartete screen Session mit drauf (mit “screen -ls” können vorher alle screen Sessions angezeigt werden). Nun können beide mit dieser Shell arbeiten, alles was getippt wird, sieht der andere und umgekehrt. So kann man den Kollegen auch gut ärgern!
Mit <Strg>+a+d kann sich jeder Benutzer einzeln von der screen Session wieder abhängen (detachen). Mit exit wird die screen Session beendet.
Verschiedene Benutzer
Etwas komplizierter wird es, wenn man sein screen für andere Benutzer frei geben möchte. Hier gibt es dann aber auch die Möglichkeit den anderen Benutzer lediglich zum zusehen zu verdammen.
Damit das ganz funktionieren kann, muss screen im root Kontext gestartet werden, also:
chmod +s /usr/bin/screen
Wie gehabt, zort startet screen und drückt dann <Strg>+a und „:“ um in den screen Kommandomodus zu gelangen. Mit folgenden Befehlen gibt er seine screen Session für den Benutzer narf frei und schaltet die screen multiuser Fähigkeit ein:
acladd narf multiuser on
Will er nun, dass narf nur zuschauen und sich höchstens noch von screen wieder detachen kann, so erledigt er das so:
aclchg narf -wx "#?" aclchg narf +x „detach“
Wer näheres über die Befehle wissen möchte, bitte ich in man screen nach zu schlagen.
Benutzer narf verbindet sich nun auf das Screen von zort mit:
screen -x zort/
Nun sehen beide Benutzer denselben screen, wobei zort vollen Zugriff hat und narf nur zuschauen darf.
Blinken und .screenrc
Wem das geblinke in screen auf den Keks geht, kann das im Kommandomodus mit
vbell off
abschalten.
Alternativ können alle Befehle in die ~/.screenrc als default abgelegt werden. Merkwürdiger Weise funktionieren die aclchg Befehle auf unseren RHEL Systemen aus der .screenrc heraus nicht, sodass sie immer im Screen Kommandomodus eingetippt werden müssen.
Und nun viel Spaß beim zuschauen!
Aber Vorsicht: Immer den Datenschutz im Auge behalten!
Winbind und idmap_rid
31. Mrz
Ich weiß nicht warum, aber die ganze Welt schimpfen auf Winbind. Ist aber meiner Meinung nach oft zu unrecht, denn es kann einem viel Arbeit beim AD/LDAP/ID Mapping ersparen. Wer Winbind noch nicht kennt, Winbind mappt die Windows SIDs auf lokale Linux UIDs und GIDs, sodass man unter Linux mit den Active Directory Benutzern und Gruppen arbeiten kann.
Meist wird winbind aber nicht eingesetzt, da es im nicht konfiguriertem Zustand zu einer Windows SIDs auf verschiedenen Servern unterschiedliche UIDs bzw. GIDs zurück liefert. Das ist in einer professionellen Umgebung natürlich inakzeptabel.
Die Lösung, die komischerweise nur wenige kennen hier, ist idmap_rid. Mit diesem Winbind Backend werden auf allen Linux Servern die selben UIDs zu Windows SIDs generiert.
Hier unsere Konfiguration mit idmap_rid in Kurzform (wer noch mehr wissen möchte einfach mich anschreiben).
Zunächst die Kerberos Konfiguration:
/etc/krb5.conf:
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = <SUBDOM.DOMAIN.DE>
dns_lookup_realm = true
dns_lookup_kdc = yes
ticket_lifetime = 24h
forwardable = yes
[realms]
<SUBDOM.DOMAIN.DE> = {
default_domain = <subdom.domain.de>
}
[domain_realm]
.<subdom.domain.de> = <SUBDOM.DOMAIN.DE>
[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
Die nsswitch nicht vergessen:
/etc/nsswitch.conf:
... passwd: files winbind shadow: files winbind group: files winbind ...
Und hier die Einträge in der smb.conf:
/etc/samba/smb.conf
[global] workgroup = <WORKGROUPNAME> security = ads realm = <SUBDOM.DOMAIN.DE> password server = * wins server = load printers = no printcap name = /etc/printcap idmap domains = DLD idmap config DLD:backend = rid idmap config DLD:range = 40000-1000000 winbind separator = / template shell = /bin/bash winbind enum users = yes winbind enum groups = yes winbind use default domain = yes acl group control = yes [test] comment = Test Share for domain users only path = /smbdata read only = yes valid users = @"DOM/domain users" write list = "DOM/testy"
Die wichtigen Zeilen sind hier die drei idmap Einträge. Hier habe ich als backend, für die Berechnung der Linux UIDs und GIDs das Modul “rid” angegeben sowie eine Range für die IDs von 40.000 – 1.000.000 reserviert, sollte reichen…
Nachdem einem
net ADS join -U <username>
kann mit
wbinfo -t
die Winbind Konfiguration getestet werden. Ist hier alles OK sind die AD SIDs dem Linux bereits bekannt.
Prüfen:
getent passwd | grep testy testy:*:65435:78221:USERNAME:/home/DOM/testy:/bin/bash
Der Benutzer testy hat bei dieser Konfiguration auf allen Linux Servern die uid 65435.
Nun dürfen alle Benutzer aus der AD Gruppe “domain users” auf die Samba Freigabe test zugreifen und testy darf zusätzlich schreiben.
Das ganze funktioniert übrigens auch mit mehreren Domains! Die Manpage “man idmap_rid” hilft weiter.
Einziger Nachteil ist hier, dass man jedem dieselbe Shell zuweisen muss. Das benötigt man ja aber eh nur, wenn sich der Benutzer auch direkt am System anmelden möchte.
Also: Winbind ist nicht nur böse! Nicht immer drauf rumhacken!
Incron – Ein Fileevent basierter Cron
01. Feb
Zeitgesteuert Skripte oder Programme über Cron zu starten ist ja schon sehr praktisch. Nicht selten möchte man aber sofort eine neue Datei verarbeiten, sobald diese im Dateisystem erzeugt wurde. Bevor man aber nun einen Cronjob einplant, der im Minutentakt prüft ob neue Dateien angelegt wurden, gibt es eine viel elegantere Methode sofort, ohne Zeitverlust zu reagieren. Hier kommt incron ins Spiel.
incron
incron arbeitet ähnlich wie das bekannte cron, wird aber nicht zeitlich sondern durch Dateisystem Events gesteuert. So ist es möglich mehrere Verzeichnisse zu überprüfen und wenn auf eine Datei zugegriffen wird, ein entsprechendes Programm zu starten.
Wir verwenden incron auf einem SFTP Server, der einkommende Dateien sofort an die weiterverarbeitenden Stellen verschiebt. Unnötige Wartezeiten gehören der Vergangenheit an.
Eine Voraussetzung für incron ist, dass man mindestens einen 2.6.13er Linux Kernel mit inotify einsetzt (sollte bei allen aktuellen Linuxkerneln als default gesetzt sein).
Quellen
Die Sourcecodes können bei folgender Adresse herunter geladen werden: http://inotify.aiken.cz/
Hier sind auch weitere Dokus und FAQs zu dem Thema inotify zu finden.
Wer den bequemen Weg wählen möchte, hier gibt es unter anderem RPM Pakete:
http://rpmfind.net/linux/rpm2html/search.php?query=incron
Installation
Nach der Installation hat man sein System um zwei Binaries, einem Startskript, einem Configverzeichnis und einer Configdatei bereichert. In der Hauptkonfigurationsdatei /etc/incron.conf können diverse Pfade gesetzt und sogar der Zugriff auf incrontabs für Benutzer (neben system incrontabs) konfiguriert werden.
Nun nur noch das Startskript incrond starten.
service incrond start
Konfigurationsbeispiel
Um System-incrontabs einzurichten erstellt man eine entsprechende Datei in dem Verzeichnis /etc/incron.d/.
Beispiel: /etc/incron.d/watch_sftpin:
/data/sftpin IN_CLOSE_WRITE mv $@/$# /data/save
Mit dieser Konfiguration wird jede Datei, die in /data/sftpin erzeugt wird von incrond sofort nach /data/save verschoben.
Genauer: Sobald eine Datei mit dem Event IN_CLOSE_WRITE, also nach einem Schreiben geschlossen wurde wird der Befehl hinter IN_CLOSE_WRITE ausgeführt (move Datei nach save). $@ ist hier Platzhalten für das überprüfte Verzeichnis und $# beinhaltet den Namen der entsprechenden Datei.
Änderungen an den incrontab-Dateien werden sofort, ohne Serviceneustart übernommen.
Aber ACHTUNG: Leider dürfen die Argumenten in der incrontab nur mit genau EINEM Leerzeichen getrennt sein, sonst funktioniert es nicht.
Test des Beispiels:
[root@server data]# echo "test" >sftpin/hallo [root@server data]# ll sftpin/ total 0 [root@server data]# ll save/ total 4 -rw-r--r-- 1 root root 4 Jan 27 17:04 hallo [root@server data]#
Die Datei “hallo” wird sofort nach save verschoben.
Man kann auch verschiedene Fileevents reagieren:
- IN_ACCESS Datei wurde lesend geöffnet
- IN_ATTRIB Metadaten sind geändert worden (permissions, timestamps, extended attributes, etc.)
- IN_CLOSE_WRITE Datei wurde nach schreibendem Zugriff geschlossen
- IN_CLOSE_NOWRITE Datei wurde geschlossen ohne dass etwas geschrieben wurde
- IN_CREATE Datei oder Verzeichnis wurde erstellt
- IN_DELETE Datei oder Verzeichnis wurde gelöscht
- IN_DELETE_SELF Überprüftes Verzeichnis selbst wurde gelöscht
- IN_MODIFY Datei wurde geändert
- IN_MOVE_SELF Überprüftes Verzeichnis selbst wurde verschoben
- IN_MOVED_FROM Datei ist aus überprüftem Verzeichnis verschoben worden
- IN_MOVED_TO Datei ist in überprüftes Verzeichnis geschoben worden
- IN_OPEN Datei ist geöffnet worden
Folgende Variablen kann man verwenden:
$@– Der Name des überprüften Verzeichnis selbst$#– Name der betroffenen Datei$%– Das entsprechende Event (Textform)$&– Das entsprechende Event (Nummerische Form)$$– Ein Dollarzeichen
Fazit
Uns hat incrond einiges an sinnlosen Warteschleifencronjobs eingespart und die Verarbeitung an manchen Stellen sehr beschleunigt. Ich hoffe euch hilft incron auch.
Bash Kommandozeilenparameter verarbeiten
07. Aug
Ich muss recht oft kleine Bash Skript schreiben, denen Kommendozeilenparameter mitgegeben werden müssen. Bevor man nun riesig, komplizierte If und while Strukturen über alle möglichen und unmöglichen Argumente erstellt, gibt es ein sehr nützliches Kommando das die Sache sehr vereinfacht: getopts
getopts ist eine Bash BuildIn Funktion, für andere shells gibt es das Programm getopt, was etwas anders arbeitet, ich aber hier nicht beschreibe. Ach ja, eine Einschränkung gibt es noch: getopts beherrscht nur kurze (ein Zeichen-) Optionen, also z.B. -v, -vba werden als drei einzelne Parameter gesehen, also: -v -b -a. getopts beherrscht leider keine langen Parameter, wie z.B. –verbose oder ähnliches.
Ich benutze folgendes Template für meine Skripte:
while getopts ":vprf:h" opt
do
case $opt in
v)
echo "-v Option wurde gesetzt"
# Irgendwelche Variablen setzen
;;
f)
[ ${OPTARG:0:1} = "=" ] && arg=${OPTARG/=} || arg=$OPTARG # evtl "=" entfernen
echo "-f Option wurde mit dem Argument $arg gesetzt"
;;
\?)
echo "Fehler: Kenne Parameter $OPTARG nicht"
# Irgendwelche Variablen setzen um spaeter Hilfe auszugeben
;;
esac
done
# alle gefundenen Argumente aus $@ entfernen
shift $(($OPTIND-1))
# $@ bzw. $* enthaelt nun nur noch alle restlichen Argumente
echo "Rest: $*"
Kurze Erläuterung:
getopts bekommt als erstes Argument alle möglichen Optionen mit. Hier in diesem Beispiel kann das Programm also -v -p -r -f und -h verarbeiten. Der : hinter dem Parameter f bedeutet, dass -f ein Argument erwartet. Der : am Anfang unterdrückt Fehlermeldungen von getopts, wenn Optionen angegeben wurden, die nicht in der Liste stehen. “opt” ist die Variable, in die getopts die aktuelle Option zuweist.
Nun wird $opt auf die möglichen Optionen mit einem case abgefragt. Laut Definition soll ja für -f ein Argument mit angegeben werden. Dieses legt getopts in die Variablen $OPTARG ab. Um beide Arten von Argumentangaben abzufangen (einmal mit einen White Space und einmal mit einem “=”), ist die erste Zeile im -f case Zweig zuständig. Diese löscht ein evtl. angegebenes = einfach heraus und weißt das geputzte Argument der Variablen arg zu. Wer nicht auf = reagieren will, der lässt die Zeile einfach weg und greift direkt auf $OPTARG zu.
\? wird ausgeführt, wenn eine Option angegeben wurde, die nicht erlaubt ist, also nicht getopts übergeben wurde (und ein : am Anfang der möglichen Parameter steht).
Ganz am Ende werden alle bekannten und bereits verarbeiteten Parameter aus $@ bzw $* entfernt, sodass nur noch der Rest des Programmaufrufs übrig bleibt. Mit $* kann dann auf den Rest zugegriffen werden.
Es folgen einige Beispiele:
[schlabbl@home ~]$ ./mygetopts -pvr -f="file=foo" -f foobar file1 file2 -v Option wurde gesetzt -f Option wurde mit dem Argument file=foo gesetzt -f Option wurde mit dem Argument foobar gesetzt Rest: file1 file2 [schlabbl@home ~]./mygetopts -vx -v Option wurde gesetzt Fehler: Kenne Parameter x nicht Rest:
Neuer Kernel und VMware Config
07. Mai
Sobald ein neuer Kernel auf einem VMware Gast installiert wird, muss nach dem nächsten Reboot vmware-config-tools.pl aufgerufen werden, um unter anderem die Netzwerk Kernel Module für den neuen Kernel einzurichten. Dumm nur, ohne Netzwerk muss alles über die Konsole durchgeführt werden.
Abhilfe bringt folgendes InitV Script: (/etc/init.d/vmwareautoconfig)
#!/bin/bash
# chkconfig: 2345 00 00
# description: Checks and installs automatically vmware modules for new kernel
if [ "$1" == "start" ] ; then
if [ ! -e /lib/modules/`uname -r`/.vmware_installed ]; then
/usr/bin/vmware-config-tools.pl --default >/var/log/vmware_config_last.log 2>&1
touch /lib/modules/`uname -r`/.vmware_installed
fi
fi
Auf einem Red Hat System noch mit ausführbar machen und mit chkconfig --add vmwareautoconfig in den Bootprozess einbinden und man muss sich nie wieder um vmware-config-tools.pl kümmern.
Kurz zum Skript:
Sobald ein neuer Kernel bootet, für den vmware-config-tools.pl noch nicht ausgeführt wurde (siehe Trigger Datei), führt es vmware-config-tools.pl --default aus. Im Anschluss wird die Trigger Datei /lib/modules/<kernel>/.vmware_installed erzeugt.
Soll vmware-config-tools.pl noch einmal beim nächsten Boot ausgeführt werden, einfach /lib/modules/<kernel>/.vmware_installed löschen.
Der Bootvorgang läuft dann wie gewohnt weiter und der VMware Gast hat gleich beim ersten Boot Netzwerk!
RPM und 64bit Systeme
05. Mai
Eieieiei, immer wieder muss ich nachschauen und aufs neue den rpm Befehl zusammen basteln. Jetzt schreibe ichs mal auf:
RPMs inklusive Architektur auf einem 64bit RHEL System auflisten lassen:
rpm -qa --qf "%{NAME}-%{VERSION}-%{RELEASE} (%{ARCH})\n"
Wenn ein Paket für mehrere Architekturen installiert ist, kann man mittels .
rpm -qi glib2.x86_64
Und deinstallieren des 64Bit Paketes:
rpm -e glib2.x86_64
Veraltete Einträge in .ssh/known_hosts
04. Mai
Ronny hat mir grade eine kleine Bash Funktion geschickt, die mir ab jetzt viel Nerven sparen wird:
Wenn ein Server neu installiert wird (passiert bei uns schon ab und zu) ändern sich auch die SSH Server Keys. Beim nächsten Versuch, sich per SSH auf die neu installierte Maschine zu verbinden, verweigert SSH Aufgrund der Sicherheitseinstellungen den Dienst.
Es war dann immer umständlich, die alten Keys aus der known_hosts zu löschen.
Mit der folgenden Funktion (eingebaut in die .bashrc) geht das recht flott.
Als Übergabe nur die Zeilennummer mitgeben, die bei der SSH Fehlermeldung steht:
function sshknownhosts {
if [ $1 ]; then
sed -i ${1}d ~/.ssh/known_hosts
sed -i ${1}d ~/.ssh/known_hosts
echo "Zeile ${1} geloescht"
else
echo "Bitte Zeilennummer angeben"
fi
}
Sehr feines sed Skript zum löschen einer Zeile in einer Textdatei.
Thx Ronny!
ROAB – Run Once After Boot
04. Mai
Ich hatte oft die Anforderung, ein Skript nach dem nächsten Reboots eines Servers (genau ein mal) laufen zu lassen. Da ich ja, wie alle Admins faul bin und keine Lust hatte aufzupassen, wann ein Server neu gestartet wird, habe ich ein kleines SystemV Skript geschrieben, das mir diese Arbeit abnimmt.
ROAB – “Run Once After Boot” macht genau das was es sagt: Ein oder mehrere Skripte nach dem nächsten Reboot eines Servers genau einmal auszuführen. Dabei wird die Zeit und die Ausgaben der Skripte mit protokolliert, damit man im Nachhinein die Ausgaben auch kontrollieren kann. Außerdem kann nach erfolgter Arbeit ein weiterer automatischer Reboot konfiguriert werden.
Installation:
Ich habe ein RPM für Red Hat erstellt. Also einfach installieren.
Wer das ganze zu Fuß machen will, hier das Skript. Dieses einfach nach /etc/init.d kopieren, ausführbar machen und mit “chkconfig roab on” in den Bootvorgang einbauen.
Download: roab-0.1-1.noarch.rpm (RPM für Red Hat Enterprise Linux)
Mit ROAB arbeiten:
Nun können beliebige Skripte und Programme nach /etc/roab/run.d/ gelegt werden, die dann, nach dem nächsten Reboot alphabetisch sortiert, gestartet werden. Alle Skripte und deren Ausgaben werden im Anschluss nach /etc/roab/run.log/ verschoben. Außerdem wird das Starten jedes Skriptes im Syslog (per logger) gemeldet.
Existiert die Datei /etc/roab/forcereboot, wird nach dem Ausführen aller Skripte ein Reboot des Systems durchgeführt.
Ausprobieren:
echo "touch /tmp/das_war_ein_roab_script" >/etc/roab/run.d/testscript
reboot
Nach dem Reboot ist das testcript-Script nicht mehr im run.d Verzeichnis, sondern in run.log zu finden. Außerdem die Ausgabe in <datum>testscript.log. In diesem Beispiel gab es ja keine Ausgabe, deswegen ist die Datei leer.
Deinstallieren:
Das RPM einfach deinstallieren. Das Log Verzeichnis wird beibehalten.
Ich hoffe ROAB nimmt euch genau so viel Arbeit ab wie mir!


