linux
From String to Array of Strings in Bash
Definition eines String:
STRING="A"
Definition eines Array:
STRING[0]="A" STRING[1]="B"
oder
STRING="A" STRING[1]="B"
Das heißt, nur mit STRING=“A“ kann noch nicht unterschieden werden, ob es nur ein String ist, oder ein Array. D.h. man kann eine bestehende Definition einfach weiterverwenden. Und auch, diese bei Bedarf einfach um ein zweites Feld erweitern.
Wie aber muss der Code aussehen, damit er von Haus aus mit der Erweiterung umgehen kann?
Feststellen der Anzahl der Elemente im Array
${#STRING[*]}
COUNT=0 while [[ ${COUNT} -lt ${#STRING[*]} ]]; do echo ${STRING[$COUNT]}; COUNT=$((COUNT+1)); done
Output für
unset STRING
(kein Output)
Output für
STRING="a" a
Output für
STRING="a" STRING[1]="b" a b
Voraussetzungen: Elemente im Array von 0 weg zählend durchnummerieren. Das erleichtert das durchlaufen einer Zählschleife ungemein!
OpenSSL STR_COPY variable has no value
Openssl kann Shellvariablen im der Konfigurationsdatei verarbeiten. Kommt dabei eine Fehlermeldung wie
openssl.exe version 6870300:error:0E065068:configuration file routines:STR_COPY:variable has no value:conf_def.c:618:line 19
liegt das daran, dass die Shellvariable nicht definiert ist.
Eine leere Variable dagegen ist aber OK.
Ich dachte schon einen Bug gefunden zu haben. Der Report dafür wurde aber nicht anerkannt, weil das Verhalten so gewünscht und dokumentiert ist.
Wie kommt man zum Fehler? Mit einer Config wie:
[req] promt=no distinguished_name=dn default_md=sha256 default_bits=2048 req_extensions=alt_names [dn] C=AT ST=NOe L=xxx O="org" OU="ou" E="test@example.com" [alt_names] subjectAltName=${ENV::SAN}
Wie repariert man es?
Indem man einen Default Wert in der Config setzt:
SAN="" [req] promt=no distinguished_name=dn default_md=sha256 default_bits=2048 req_extensions=alt_names [dn] C=AT ST=NOe L=xxx O="org" OU="ou" E="test@example.com" [alt_names] subjectAltName=${ENV::SAN}
Dokumentation, wenn auch leicht verwirrend findet man unter https://www.openssl.org/docs/man1.0.2/apps/config.html bzw. https://www.openssl.org/docs/manmaster/apps/config.html für die letzte Version.
Suchen auf der Seite nach Begrif „ENV“.
Service Names in Windows
Zwischen Linux und Windows ist ja vieles anders, oder auch einfach nur bewusst inkonsistent gehalten.
Beispiel: Samba unter Linux – heißt in Windows „Server“. Überraschenderweise sogar in der deutschen Version.
Aber schlimmer wirds beim Webserver. In Linux schon unter vielen Namen bekannt, je nach Distribution als: apache, apche2, httpd für den Apache2 Webserver oder eben lighttpd, nginx oder was da sonst noch so kreucht und fleucht. Als was würde man den Windows Internet Information Server Dienst suchen? Als Microsoft IIS, IIS, Internet Information Irgendwas, Windows Internet Information, Windows Web, Windows HTTP? Nein, alles Falsch. Der Dienst heißt World Wide Web Publishing Service.
OpenLDAP Dynamic Configuration
Aktuelle LDAP Pakete z.B. für Ubuntu finden sich beim LDAP Tool Box project. Aber ein Problem gibt es mit den Paketen – per Default ist nur die statische Konfiguration über die slapd.conf unterstützt. Das lässt sich aber theoretisch ganz leicht ändern, man legt ein zusätzliches Verzeichnis an, wo die dynamische Konfiguration gespeichert werden kann, und trägt es in /etc/default/slapd in der Zeile „SLAPD_CONF_DIR“ ein. Was passiert dann?
slapd: [ALERT] OpenLDAP configuration test failed
Wie kann das sein? Wieso kann die Konfiguration fehlerhaft sein, wenn es doch noch gar keine gibt? Und sollte die nicht per Default angelegt werden?
Dann teste ich eben, ob ich den Dienst händisch starten kann! Wie sieht die Befehlszeile aus den slapd zu starten?
ps aux | grep slap ldap 32099 0.0 0.3 1085388 3480 ? Ssl 18:31 0:00 /usr/local/openldap/libexec/slapd -h ldap://*:389 ldaps://*:636 -f /usr/local/openldap/etc/openldap/slapd.conf -u ldap -g ldap -l local4
Also muss ich den Dienst doch mit -F statt -f starten können?
# /usr/local/openldap/libexec/slapd -h ldap://*:389 ldaps://*:636 -F /usr/local/openldap/etc/openldap/slapd.d -u ldap -g ldap -l local4 usage: /usr/local/openldap/libexec/slapd options -4 IPv4 only -6 IPv6 only -T {acl|add|auth|cat|dn|index|passwd|test} Run in Tool mode -c cookie Sync cookie of consumer -d level Debug level -f filename Configuration file -F dir Configuration directory -g group Group (id or name) to run as -h URLs List of URLs to serve -l facility Syslog facility (default: LOCAL4) -n serverName Service name -o <opt>[=val] generic means to specify options; supported options: slp[={on|off|(attrs)}] enable/disable SLP using (attrs) -r directory Sandbox directory to chroot to -s level Syslog level -u user User (id or name) to run as -V print version info (-VV exit afterwards, -VVV print info about static overlays and backends)
Wie konnte das passieren?
Die Bash versucht den „*“ bei der IP Konfiguration aufzulösen. Also schützen wir die Sterne vor der Shell:
# /usr/local/openldap/libexec/slapd -h "ldap://*:389 ldaps://*:636" -F /usr/local/openldap/etc/openldap/slapd.d -u ldap -g ldap -l local4 # ps aux | grep slap ldap 32589 0.1 0.2 1068476 2700 ? Ssl 18:49 0:00 /usr/local/openldap/libexec/slapd -h ldap://*:389 ldaps://*:636 -F /usr/local/openldap/etc/openldap/slapd.d -u ldap -g ldap -l local4
Und wir haben das Configverzeichnis mit einer ersten Konfiguration befüllt.
Ab jetzt klappt der Start des Dienstes auch mit dem Start/Stop Script bzw. mit dem service-Befehl.
Compile OpenSSL
Most distributions contain only an old version of openssl. If you need a newer version for your scripts, ther often is no other way than compiling it from source. Here I’ll show you, how to do it. And don’t be afraid, it’s super easy! The latest version is a 1.1 development version.
There are only a few prerequisits: You need the packets make and gcc. First you download the source from github and unpack it:
wget https://github.com/openssl/openssl/archive/master.zip unzip master.zip cd openssl-master
You simply do the steps for compiling software on unix/linux:
./config make make install
You need to do at least the 3rd step as root, so it can install the files for you. By default, everything gets installed into /usr/local/ssl – so it won’t destroy your system OpenSSL.
# /usr/local/ssl/bin/openssl version OpenSSL 1.1.0-pre2-dev xx XXX xxxx
Have a lot of fun!
Verschlüsseln auf der Shell
Um mal eben eine Datei oder einen Stream auf der Shell zu verschlüsseln kann man bcrypt oder ccrypt verwenden. Das ganze funktioniert etwa so:
~ echo hallo | ccrypt -f > output Enter encryption key: Enter encryption key: (repeat) ~ cat output u~�-�x�� O���Ļ_U ~ ccrypt -f -d < output Enter decryption key: hallo
Beschrieben zum Beispiel unter Encrypt Files on Linux
Swap Space anlegen
Zum Beispiel ein GB Swap anlegen geht einfach mit dd:
# time dd if=/dev/zero of=swapfile bs=1MB count=1024 1024+0 records in 1024+0 records out 1024000000 bytes (1.0 GB) copied, 14.979 s, 68.4 MB/s real 0m14.986s user 0m0.016s sys 0m10.332s # mkswap swapfile Setting up swapspace version 1, size = 999996 KiB no label, UUID=118351b9-94a4-4782-9470-643eaef3e5f4 # swapon swapfile # cat /proc/swaps Filename Type Size Used Priority /dev/sda2 partition 1952764 211944 -1 /dev/sdb2 partition 1952764 0 -2 /root/swapfile file 999996 0 -3
Schneller gehts mit fallocate:
# fallocate -l 2G swapfile2 # mkswap swapfile2 Setting up swapspace version 1, size = 2097148 KiB no label, UUID=50a99651-bb65-4ae7-a114-83d627670866 # swapon swapfile2 # cat /proc/swaps Filename Type Size Used Priority /dev/sda2 partition 1952764 211944 -1 /dev/sdb2 partition 1952764 0 -2 /root/swapfile file 999996 0 -3 /root/swapfile2 file 2097148 0 -4
Tritt dabei dieser Fehler auf
swapon: swapfile has holes
gibts vermutlich ein Problem mit dem verwendeten Dateisystem. Zum Beispiel auf NFS Freigaben lässt sich dieser Fehler erzeugen – aber dort macht der Swap doch keinen Sinn mehr.
Auch Abschalten geht ganz einfach:
# swapoff swapfile # swapoff swapfile2 # cat /proc/swaps Filename Type Size Used Priority /dev/sda2 partition 1952764 211944 -1 /dev/sdb2 partition 1952764 0 -2
Das kann ziemlich lange dauern, falls der Swap schon gefüllt ist und vor dem aushängen erst leergeräumt werden muss.
Speicherfresser
Anmerkung zum Artikel „Speicherfresser – Speicherverwaltung bei High-End-Systemen“ im Linuxmagazin 03/14
Einfach gesagt, geht es um eine Thema über das ich schon vor einiger Zeit gebloggt habe: Swap
Es geht in dem sieben seitigen Artikel unter anderem um die Frage, warum man auch auf modernen Systemen, mit massenhaft Speicher noch immer Swap-Speicher benötigt.
I/O intensive Prozesse können den Speicher von Anwendungen, die kaum I/O lastig sind, in den Swap Bereich zwingen. Am Besten verständlich wird das anhand eines Beispieles: Eine Datenbank hält jede Menge Speicher für verschiedene Buffer belegt. Der Großteil des nötigen Datensets liegt im RAM und alles ist gut. Dieses eingespielte System verursacht dann nur mehr wenig I/O. Läuft jetzt aber ein Backup, von dem die ganze Disk gelesen wird, wandern diese Daten in den Cache und zwingen so die eigentlichen Arbeitsdaten in den Swap. Im Anschluss wird die ursprüngliche Performance erst wieder erreicht, wenn die Daten den eigentlich unnötigen Cache wieder verdrängt haben.
Context Switching
Zuerst muss man sehen, was ein Context Switch überhaupt ist. Ganz einfach gesprochen ist es das, was auch mit nur einer CPU im System Multitasking ermöglicht.
Die Wikipedia definiert das ausführlicher:
Kontextwechsel oder Taskswitching (englischcontext switch) nennt man den Vorgang in einem Betriebssystem, bei dem die Bearbeitung des aktuellen Prozesses (oder auch Threads, Tasksoder Programms) unterbrochen wird (z. B. nach einer festgelegten Zeitspanne durch einen Timer-Interrupt oder bei Systemaufrufen) und zu einer anderen Routine gewechselt wird. Dabei wird derKontext (im Wesentlichen die Prozessor-Register) des aktuellen Prozesses/Threads/Tasks gesichert und der Kontext des neuen restauriert. Durch diesen Vorgang wird Multitasking ermöglicht, da sich so mehrere Prozesse im Zeit-Multiplexverfahren auf einem einzelnen CPU-Kern mehr oder weniger gleichzeitig ausführen lassen.
Wie aufwändig ist jetzt ein Context Switch? Dieser Frage wird ein einem Blogartikel nachgegangen: Also im Worst case 4500 ns. Schon klar, das kann deutlich besser aussehen, je nach verwendetem System oder auch der verwendeten CPU.
Wie viele Context switches passieren denn so auf einem System? Am einfachsten eniemal mit dem SAR command nachsehen:
# sar -w 1 10000 Linux 2.6.34.10-0.6-default (ServerWalterschlag) 03/09/14 _i686_ (1 CPU)
10:37:57 proc/s cswch/s 10:37:58 0.00 157.00 10:37:59 0.00 158.00 10:38:00 0.00 319.80 10:38:02 0.00 161.00 10:38:03 0.00 159.41 10:38:04 0.00 165.35 10:38:05 0.00 150.00 10:38:06 0.00 199.00 10:38:07 0.00 184.16 10:38:08 0.00 275.76 10:38:09 0.00 190.10 10:38:10 0.00 154.90 10:38:11 0.00 273.00 10:38:12 0.00 1380.20 10:38:13 0.00 2915.00 10:38:14 0.00 2785.00 10:38:15 0.00 3614.00 10:38:16 0.00 3548.00 10:38:17 0.00 2745.00 10:38:18 0.00 2072.28 10:38:19 0.00 2262.38
Das kann ganz schön Schwanken, je nachdem wie viele Prozesse da aktuell laufen. Aber ausgehend von den 2200 context switches jede Sekunde und 4500 ns pro context switch würde das 9,9ms allein für context switche ergeben. Das System würde also ca. 1% seiner Zeit mit der Prozessverwaltung verbringen. Das ist so gut wie zu vernachlässigen. Steigt aber die Prozessanzahl und die Contextswitches weiter an, um etwa einen Faktor 10, dann wird die Anzahl der Switches interessant.
Weitere Betrachtungen wären nötig, für Systeme mit mehreren CPUs – für eine erste Näherung würde ich einfach die Anzahl der Context Switche durch die Anzahl der vorhandenen CPUs dividieren, da die Prozessorkerne ja gleichzeitig die Switches durchführen können.
Swap
Ein weiterer Grund, warum der verbrauchte Speicher, nicht mit belegtem Speicher plus Swap übereinstimmt: …
As it turns out, swap means more than just pages swapped to disk. An application's binary and libraries need not stay in memory the whole time. The kernel can mark some of the memory pages as unnecessary at the time; but because the binary is at a known location on disk, there is no need to use the swap file. This is still counted as swap because the part of the code isn't resident. In addition, memory can be mapped to a disk file by the application. Because the whole size of the application (VIRT) includes the mapped memory, but it isn't resident (RES), it's counted as swap.