01
gitolite und email
Nur damit ich es selber nicht vergesse ...
cd .gitolite/hooks/common
cp /usr/share/doc/git/contrib/hooks/post-receive-email post-receive
gitolite setup --hooks-only
Und in .gitolite.rc noch den override der maillinglist mail adresse zulassen:
GIT_CONFIG_KEYS => 'hooks\..*',
Und schon läuft das - grrr
Network Management in a Box
So langsam nimmt hier das neue Network Management Formen an. Nach 4 Wochen:
- Zentrales git mit gitolite + Gitweb
- Single Credential via LDAP
- Inventarierung und Configuration basierend auf CouchDB + JS Frontend
- Config Backup aller devices ins GIT
- Icinga2 für das Monitoring
Das ganze kann man aus dem git auschecken - starten und nach 10-15 Minuten hat man den ganzen Kram wieder am laufen.
Morgen mache ich den rest Icinga und dann gehts an das Performance Management Backend damit das Cacti weg kommt. Das mit dem neu schreiben des ganzen Zeugs hat auch Vorteile. Ich bekomme fast Lust das mal als LiveCD zu bauen
Dakar Tag 3 - TATRA
5 stellige PIN in 2016
Das ist echt der Hammer. Selbst in 2016 lässt die Sparkasse Gütersloh nur eine 5 stellige PIN für die Anmeldung am Online Banking zu.
Was soll das? Ich hätte gerne
The quick brown fox jumps over the lazy dog!!!
Und das ist absolut legitim und dient der Sicherheit.
Wann wacht da mal einer auf und holt die letzten 20 Jahre nach. Schon vor 20 Jahren hat ein standard Unix system Passwörter mit weniger als 6 Zeichen abgelehnt.
Es rumpelt(e) ein wenig
Mein allseits bekannter ex-Arbeitgeber hat mal wieder zugeschlagen und wollte kein hidden primary für meine DNS Zonen mehr sein. Wie das halt so ist wenn einem das schwarze unter den Fingernägeln nicht mehr gegönnt wird.
Die anderen Beteiligten haben wenigstens alle mitgespielt so das ich denke das es sich jetzt so langsam wieder beruhigt. Gestern hatte es ja schon silicon-verl.de erwischt die ein bischen in der Wurst hing - Sollte aber mittlerweile aus allen caches raus sein.
icinga2 und service dependencys
So - Nachdem ich ja mich hier mit der Einführung von neuen Konfigurations und Inventarisierungstools beschäftigt habe und letzte Woche die strukturierten Konfigurationssicherungen an den Start gekommen sind läuft jetzt auch die überwachung mit service dependencies für subinterface etc ... Es lohnt sich gleich icinga2 zu machen weil vieles mit den checks viel schönes gelöst ist. Damit plumpst dann jetzt automatisiert gleich sowas raus:
object Service "IF Bundle-Ether5" {
import "generic-service"
host_name = "cr-141"
check_command = "customif"
vars.ifname="Bundle-Ether5"
vars.sla = "24x7"
}
object Service "IF Bundle-Ether5.4090" {
import "generic-service"
host_name = "cr-141"
check_command = "customif"
vars.ifname="Bundle-Ether5.4090"
vars.sla = "24x7"
}
object Dependency "cr-141-cb7aee14377f35ccb58d46d9c30528e3-cr-141-cb7aee14377f35ccb58d46d9c305451c" {
parent_host_name = "cr-141"
child_host_name = "cr-141"
parent_service_name = "IF Bundle-Ether5"
child_service_name = "IF Bundle-Ether5.4090"
}
Cisco und die bootscripte
*Jan 12 07:36:57.502: %SYS-5-RELOAD: Reload requested by Exec. Reload Reason: Reload command.
*Jan 12 07:36:57.976: %IOSXE-3-PLATFORM: 1 process sysmgr: Reset/Reload requested by [console].
<Tue Jan 12 07:36:57 2016> Message from sysmgr: Reason Code:[3] Reset Reason:Reset/Reload requested by [console]. [Reload command]
umount: /proc/fs/nfsd: not mounted
/etc/rc6.d/S01reboot: line 198: umount_cisco_filesystems: command not found
Please stand by while rebooting the system...
[606968.629033] Restarting system.
Guckt da eigentlich mal IRGENDWER auf die Fehler auf der seriellen Konsole? Ich würde mich ja schämen sowas an Kunden rauszugeben.
Juniper SRX Backup
Configbackup für Juniper SRX Firewalls dann auch mal fertig gebaut. Das schöne ist das die ihre config über ssh command execution rausrücken. Net:SSH2 ist mein Froind ...
$s->connect($dev->{addr}) || die "Failed to login $!";
$s->auth_publickey($user->{user},
$user->{key} . ".pub",
$user->{key}) || die "Failed to login $!";
my $c=$s->channel() || die "Failed to create channel";
$c->exec($cmd) || die "Failed to run show configuration";
Und dann aus dem channel lesen bis es nichts neues mehr gibt ... Sehr schön ...
VSS und Cluster Device Modell ...
Das ist echt kompliziert die Abhängigkeiten richtig auf die unterschiedlichen Bestandteile eines Switch/Routers der als Cluster wie z.b. ein Stack oder VSS gebaut ist zu verteilen.
Das braucht noch ein paar Iterationen bis das was wird glaube ich ...
Sorting interface names
Immer derselbe Ärger. Sortieren von Interface Namen in Webfrontends. Am Ende kriegt man sowas und soll die schön sortieren.
FastEthernet1
Port-channel5
TenGigabitEthernet1/1/1
Port-channel10
eth0.5
TenGigabitEthernet1/1/1.3
eth0.5:3
FastEthernet1.1
TenGigabitEthernet2/2/32
eth0
Port-channel5.4055
ae0.3
Was sich erstmal als nicht so schlimm darstellt aber dann doch
beliebig doof wird. Wenn man einfach die handelsüblichen String
Sortierroutinen in Perl, Javascript oder einer anderen Sprache nimmt wird
Lexikografisch sortiert. Das geht natürlich beliebig schief.
So werden dann die Port-channel
falschrum sortiert:
Port-channel10
Port-channel5
was natürlich Lexikographisch absolut richtig ist aber leider nicht was was man haben möchte.
Also muss man den String an "word" Boundaries zerlegen wobei hier sowohl der Übergang von Buchstabe auf Zahl wie Sonderzeichen und auch umgekehrt gilt.
Wir klassifizieren die Zeichen:
function chartype(ch) {
if (ch >= 'a' && ch <= 'z') {
return 1;
}
if (ch >= 'A' && ch <= 'Z') {
return 1;
}
if (ch >= '0' && ch <= '9') {
return 2;
}
switch(ch) {
case('-'):
case('/'):
case(':'):
case('.'):
return 3;
}
return 0;
}
Danach zerlegen wir den String in ein array:
if (chartype(ch) != chartype(last)) {
elements.push(str.substr(0, i));
str=str.slice(i,str.length);
}
Danach sind die interfaces schön zerlegt:
["TenGigabitEthernet", "2", "/", "1", "/", "31"]
Und können danach ganz einfach das Array rekursiv vergleichen als
function für array.sort()
. Hier wird wenn es numerische Elemente
sind numerisch verglichen andernfalls wird localeCompare
bemüht.
Sollten die elemente gleich sein wird die nächste Ebene bemüht.
function shortlist_sort_deeparray(a, b, i) {
/* Elements numeric ? */
if (!isNaN(a[i]) && !isNaN(b[i])) {
rc=a[i]-b[i];
} else {
rc=a[i].localeCompare(b[i]);
}
if (rc == 0) {
return shortlist_sort_deeparray(a, b, i+1);
}
return rc;
}
Es gibt noch ein bischen Optimierungspotential. So könnte man den chartype 3
also die "Sonderzeichen" einfach nicht in das Array packen. Was natürlich
dann bei eth0:3
und eth0.3
zu undefiniertem Verhalten führt. Da es normalerweise
um <100 Interfaces geht macht das ganze auch wenig Sinn.
[[!img Error: "media/201601131032.sorting_interface_names.jpg" does not seem to be a valid jpeg file]]
Die Arbeit und Ich
Ich hatte es ja schonmal anklingen lassen das ich mich nochmal etwas ausführlicher zu meinem Jobwechsel äussern werde. Anlässlich scheinbar gelöschter Kommentare ist jetzt ein guter Zeitpunkt da nochmal einiges Klarzustellen und zu erklären.
Weil mein ex-Kollege P.d.S. scheinbar meine Kommentare zu freien Stellen und meinem exArbeitgeber löscht wird es Zeit das ich da nochmal was zu sage. So wie man mich da "entsorgt" hat kann man niemandem mehr empfehlen bei diesem Arbeitgeber anzufangen. Ich habe meinen exChef P. eines schönes Tages gefragt warum wir Leistungen für eine Firma erbringen aber keine Rechnung stellen. Die Antwort wurde mir verweigert was ein sehr unübliches Verhalten war - Vor allem unter dem Aspekt das man man schon 18 Jahre zusammenarbeitet. Daraufhin habe ich mich, da es um erhebliche Beträge ging, mich gezwungen gesehen unseren 1. Geschäftsführer D.P. mit ins Boot zu holen. Das hatte zur Folge das man mir 2 Wochen später, am 18.9., eine Fristlose Kündigung hingelegt hat, natürlich ohne Grund aber mit dem Hinweis ich hätte ihm Unterschlagung oder Begünstigung vorgeworfen. Das ich diese Worte nie benutzt habe und diese Vorwürfe mir auch geradezu Absurd vorkamen hat keinen mehr interessiert - Woher die Idee dieser Unterstellung gekommen ist mag ich nicht zu beurteilen. Der Kommentar mit dem man mir die Kündigung gegeben hat war: "Man könne ja nochmal reden" und eine Kündigung auch zurücknehmen.
In folgenden Gesprächen mit P. und D.P. hat man sich dann erstaunt gegeben das eine Fristlose Kündigung immer eine Sperre im ALG I nach sich zieht. Es ist schon seltsam das man als Geschäftsführer einer Firma zu "Personalmaßnahmen" greift deren Konsequenzen man angeblich nicht überblickt. In den Gesprächen wurde aber immer suggeriert man würde die Kündigung zurücknehmen u.a. auch deshalb habe ich auf die Kündigungsschutzklage verzichtet. Kaum drohte die Frist für die Kündigungsschutzklage abzulaufen hatte u.a. der Geschäftsführer D.P. wenig Zeit für ein Gespräch. Nach viel hin und her hat man mir 6 Wochen nach der Kündigung in einem Gespräch angeboten mich zum 1.1.2016 WIEDERzubeschäftigen. D.h. das vermeintliche Angebot die Kündigung zurückzunehmen war vom Tisch und das Ergebniss wäre gewesen 3 1/2 Monate Gehaltsverlust, 5 Jahre weniger Betriebszugehörigkeit etc. Auf den Hinweis ich sei jetzt schon Pleite und ich könne mir das nicht leisten bis zum 1.1.2016 ohne Job zu sein kam dann allen ernstes vom Geschäftsführer P. die Aussage man habe "mir ja den Resturlaub ausgezahlt - es könne ja nicht so Eng sein". Das muss ich mir von einem Single mit dem vermutlich mind. 1 1/2 fachen meines Gehaltes, der sich sogar sein Auto von seinem Arbeitgeber bezahlen lässt, anhören. Wie sehr diese Realität von einem nicht gezahlten Hauskredit, einem leeren Öltank und einem kaltem Haus entfernt ist hat nicht interessiert. Nur dank meines Vaters war die Hütte irgendwann wieder warm.
Daraufhin habe ich dankend auf das "Angebot" verzichtet. Im Vertriebsjargon nennt sich soetwas ein "Prohibitives Angebot". Das T.B. jetzt der überzeugung ist "Ich hätte ja nicht mehr gewollt" erschliesst sich mir nicht - Ich kann es mir nur Indoktrination durch P. erklären. Natürlich ist das die Parole die ausgegeben wurde - Der Lohoff wollte ja nicht mehr.
Leute - Ich konnte es mir schlicht nicht leisten.
Wer etwas anderes behauptet oder hört ist schlicht fehlinformiert. Man hat mich auf unterirdische Art und Weise entsorgt. Einen Mitarbeiter auf das übelste mit seine ökonomischen Existenz erpresst. Man hat Aktiv versucht zu verhindern das ich woanders einen Job finde indem man den potentiellen Arbeitgebern erzählt man würde noch mir Verhandeln. Und jeder muss mal für sich im stillen Kämmerlein überlegen wie lange er so durchhält wenn von einem auf den anderen Tag das gesamte Einkommen entfällt. Viele halten keine 2 Wochen durch - Bei mir waren es immerhin 6 Wochen bevor ich den Hauskredit hätte nicht mehr zahlen können und mein Vater eingesprungen ist.
Bitter an der ganzen Nummer ist eigentlich das ich diese Firma aufgebaut habe - Ich war Mitarbeiter Nummer 1 und ALLE die da Arbeiten sind durch mich vorgeschlagen worden und haben deshalb dort ihren Job - einschließlich des Geschäftsführer P. der mich so entsorgt hat.
std::unique_ptr fallen
Finde den Fehler:
void way(std::unique_ptr<CompressedWay> cw) {
double distance=origin->distance(*cw);
ways.push_back(std::make_pair(distance,std::move(cw)));
std::cout << "cwid " << cw->id() << " distance " << distance << std::endl;
}
Das Nutzen von cw->id()
im std::cout
wirft einen Segfault. Am Ende
ist das wie ein "use after free" dadurch das ich den Pointer
mit std::move
in meinen ways vector move.
Auf sowas muss man erstmal kommen.
Feedback im Frontend
Die gute Tat für heute. Im Frontend direkt für das jeweilige Objekt die semantischen Fehler der Objektstruktur anzeigen.
Vollausstattung
Neue Arbeit ... Neue Spülmaschine
So ... Zeit des Handspülens ist vorbei ... Seit September war die Schüssel ja kaputt und die Neuanschaffung wurde aufgrund meines ehemaligen Arbeitgebers vertagt.
Was ist das ?
Der einzig sinnvolle Dialog in Rambo 3: Was ist das? Blaues Licht. Was macht das? Es leuchtet blau.
HSRP und VLANs
Die gute Tat für heute: Wir monitoren Default GW/HSRP MAC Adress Verfügbarkeit in den Switchen. Datenmodell der Konfigurationsdatenbank um service-bridge, service-vlan und service-hsrp erweitert. Aus der HSRP instance kann man die MAC Adresse berechnen - alternativ kann man sie angeben. Alle Switches die an diesem VLAN teilhaben sollten diese MAC Adresse in der CAM table haben. Also einen Exporter ins Icinga2 und einen check_bridge der auch angegebene MAC Adressen überwacht. Schon steht die L2 DefGW überwachung.
SMM Rootkit
Eine fieses proof-of-concept. Wir schaffen es das SMM Bios zu infiltrieren. Dafür gab es ja diverse exploits ... Danach ist man im prinzip unsichtbar auf dem System weil der SMM und das SMM Bios nicht sichtbar sind für das normale OS.
Dann diesen proof-of-concept auf die Maschine ins SMM Bios und sie ist und bleibt kompromittiert. Am Ende lässt sich das nur durch den Austausch des Mainboards lösen - aber ist man sich sicher ein nicht kompromittiertes zu bekommen? Da der ganze Bereich SMM davon abhängt unsichtbar zu sein kann man es nicht validieren.
https://scumjr.github.io/2016/01/10/from-smm-to-userland-in-a-few-bytes/
icinga2, embedded perl und perlcc
Heute mal ein bischen mehr Dampf in das Icinga2 gebracht. Rund 700 interfaces hinzugefügt und schon explodiert der Host.
Des Rätsels Lösung: Meine selbstgeschriebenen Perl Checks killen die Maschine - Load von > 100. Icinga2 supported offensichtlich keinen embedded perl Interpreter mehr. D.h. jeder check startet einen neuen Perl interpreter. 700 Interfaces a 5 Minuten macht 2.3Checks/Sekunde. Eigentlich hört sich das nicht so wild an - Geht aber nicht.
Kurze idee den perl check mit perlcc
zumindest von der last des
Parsens zu befreien haben sich zerschlagen. perlcc
ist mit perl 5.10
entfernt worden weil unmaintained.
Vermutlich läuft das darauf hinaus die Checks in C++ zu schreiben.
c++ was keines ist
Nachdem icinga2 ja kein embedded perl hat gucke ich mal wie es so um C++ Implementierungen für SNMP ausehen. Net::SNMP ist da ja eher nicht so geeignet. Also SNMP++ angesehen. Wir probieren die ersten Schritt und es ist so halbherziges c++ das es keinen Spaß macht.
Wieso throwed der Constructor einer Klasse keine exception nicht sondern returned über einen int einen Status?
Snmp snmp(status, 0, (snmpaddress.get_ip_version() == Address::version_ipv6));
if (status != SNMP_CLASS_SUCCESS) {
std::cout << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "\n";
return 1;
}
Oder warum können die gängigen initialisierungen für Adresse keinen
std::string
? Warum muss das ein const char *
sein?
ctarget.set_readcommunity(vm["community"].as<std::string>().c_str());
Oder warum erkennt die Klasse Snmp
nicht am dem Target objekt ob
das ipv6 oder ipv4 ist? Warum muss ich das bei der instanzierung
von Snmp
machen?
c++ rewrite der icinga checks
Der c++ rewrite des checkif
ist fast vollständig. Das icinga2 läuft jetzt mit einem c++ checkif dem nur
noch die Entity MIB query für die Optiken fehlt. Hier mal ein Performancevergleich:
flo@p3:~/projects/snmp-plus-plus/test$ time ./checkif.pl --host 127.0.0.1 --community public -i eth0
IF OK - IPv6 UP
real 0m0.155s
user 0m0.140s
sys 0m0.016s
flo@p3:~/projects/snmp-plus-plus/test$ time ./checkif --address 127.0.0.1 --community public --ifname eth0 --cachedir /tmp
IF OK in 2.57MBit/s 241 pkt/s out 86.98KBit/s 139 pkt/s
real 0m0.007s
user 0m0.004s
sys 0m0.000s
Wir sind also in der real time - also wirkliche Laufzeit bei einem Faktor 22 und bei den verbrauchten CPU Cycles im Userspace bei einem Faktor 35.