Jul 02, 2017
Unser Servernetz besteht hauptsächlich aus virtuellen Maschinen auf VM-Hosts, deren Daten in einem Storage-Cluster (SAN) verteilt liegen. Die Maschinen sind aus Redundanzgründen aufgeteilt auf verschiedene Standorte in Vahingen und Stadtmitte. Wichtige Dienste (z.B. DHCP, DNS) sind auch redundant auf mehreren VM-Hosts verteilt.
Wir haben vorgestern (nach dem AOA) und gestern auf unserem Storage-Cluster ein Update der Ceph Version von "Hammer" auf "Jewel" durchgeführt. Gleichzeitig haben die Admins von unseren VM-Hosts diese auf ein aktuelles Debian geupdated.
Damit es nicht zu Ausfällen kommt, haben wir auf einem unserer 3 VM-Hosts (den in der Stadt) alle wichtigen VMs am laufen gehalten.
Das Update vom Ceph-Cluster lief anfänglich gut, bis auf eine kurze Downtime. Das Cluster hat Lese- und Schreibzugriffe blockiert, weil kurzzeitig zu wenige Teile vom Cluster online waren. Aber dann waren auch alle Clusterknoten auf der neusten LTS Version.
Das "Upgrade" der VM-Hosts wurde zu einer Neuinstallation, damit alles mal wieder sauber und gleichmäßig aufgesetzt ist. Daher hat das länger als geplant gedauert. Besonders kamen hier unerwartete Inkompatibilitäten zwischen Betriebssystem, verwendeter Virtualisierungssoftware und Storage zu Tage, welche den Prozess weiter verzögerten.
Die wichtigsten VMs (auf dem KVM-Host in der Stadt) konnten dann leider unerwarteterweise nicht mehr mit der neuen Ceph Version reden und damit waren auch DHCP/DNS-Dienste nicht mehr verfügbar. Das war Freitagbend gegen viel-zu-spät Uhr und das war auch der Zeitpunkt als die ersten Mails von euch eintrudelten :)
Um den Netzbetrieb schnellst möglich wieder herzustellen wurde ein manuelles Upgrade des Linuxes auf dem VM-Host in der Stadt durchgeführt (das dauert leider auch etwas...). Nach dem Upgrade waren die Ceph Versionen wieder kompatibel und die wichtigsten Server konnten wieder gestartet werden. Damit hatten alle (ok fast alle) Nutzer wieder Internetzugriff.
Die Ausfälle haben also lediglich unsere Server betroffen. Unser (Kabel-)Netzwerk ist super stabil und redundant aufgebaut. Die Ausfälle des Internetzugangs rühren daher, dass man ohne DHCP-Server keine IP-Adresse bekommt und ohne DNS-Server keine Domains in IP-Adressen auflösen kann.
Zusätzlich erschwerend kam hinzu, dass es aktuell ungelöste Probleme im Netzwerk zwischen der Serverfarm in der Stadtmitte und den Wohnheimen Pfaffenhof 2 und Bauhäusle gibt. Dieses Problem sorgt zum Beispiel dafür, dass der zweite DHCP-Server in der Stadt seine Antworten nicht an eure Computer in den betroffenen Wohnheimen schicken kann, die Pakete gehen unterwegs verloren oder kommen so kaputt an, dass sie verworfen werden. Daher kamen die meisten eurer E-Mails auch aus den besagten Wohnheimen.
Wenn du es geschafft hast bis hier zu lesen: Komm doch demnächst nach dem Support mal bei uns vorbei und lass dir alles zeigen. Wir sind auf der Suche nach neuen und motivierten Mitgliedern. Du lernst hier spannende Dinge und hast die Möglichkeit mit neuer cooler Hardware zu spielen.
Feb 09, 2015
The last time, I analyzed the the hardware and figured out where the
firmware is stored. So let's dump it. The datasheet
tells us, that the flash IC has an SPI interface. Now we need something
that adapts SPI to a more common interface like preferably USB. There
are several devices to to this:
- Use some microcontroller and write firmware for it that reads the
SPI flash and dumps its contents via UART/USB. Downside: have to
write code for microcontroller, hard to debug
- Bus Pirate already
supports SPI flashes. Unfortunately, Selfnet doesn't have one.
- FTDI also makes USB to SPI converters besides USB to UART. I didn't
have one at hand either, but I've had existing code for using
certain FTDI bridges as USB - SPI converts.
So I purchased the FT2232H Mini Module
and built an adapter to connect the SPI flash to it.
The FT2232H contains a so called MPSSE (Multi-Protocol Synchronous
Serial Engine) to do SPI. Side note: FTDI claims that the MPSSE also
supports I²C, but since the FT2232H doesn't have open-drain outputs
and has some glitching issues, it's really painful to implement. Since
my existing code was developed on Windows™, it used the proprietary
FTD2XX driver. After some fiddling, I got ftd2xx to work on python 3. Sorry, libftdi people :(
Implementing the protocol used by the SPI flash was rather
straightforward since its datasheet is available. One particular nice
aspect of the protocol is that you can read an arbitrary amount of data
after sending the start address. So I hacked an IPython notebook to
dump the flash. Magically, it worked the first time, therefore I didn't
bother to clean it up to make it publishable.
That's inside the romdump:
$ binwalk romdump
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
94976 0x17300 U-Boot version string, "U-Boot 1.1.3 (Dec 4 2013 - 08:55:41)"
131584 0x20200 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3515396 bytes
1441792 0x160000 Squashfs filesystem, little endian, version 4.0, compression:lzma (non-standard type definition), size: 5051300 bytes, 627 inodes, blocksize: 131072 bytes, created: Fri Jun 20 05:19:24 2014
8126480 0x7C0010 XML document, version: "1.0"
In the next post, we'll dig into the romdump.
Feb 08, 2015
If you ever want to graph interface errors with MRTG you'll find a few posts on mrtg related mailing lists,
however none of them seemed to work with our installation of MRTG. There is no native support in MRTG but you can
specify a template for interfaces via the experimental --if-template flag. The following code is based on an example
by Tobias Oetiker, I have merely added support for multiple OIDs via a for loop. The code is ugly, but it works.
There is one kink to be aware of though: Since there is not always an evenly matched set of ifIN/ifOUT OIDs I've decided
to graph all OIDs on their own. This is achieved by setting
for each OID and by that making sure that MRTG doesn't render 'outgoing' data.
To configure the template you have to fill the 3 arrays special_oid_name, special_oid and special_oid_desc according to your needs, I have included some example OIDs below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 | # Author: Tobias Oetiker <tobi@oetiker.ch>
# Date: 2006-09-06
# Purpose: Add an Error graph for each Traffic Graph
# 02/07/2015: add juniper interface errors / Hannes Rist
# i am soooo sorry for this
# see http://www.oidview.com/mibs/2636/JUNIPER-IF-MIB.html
my @special_oid_name = ('ifJnxInFrameErrors', 'ifJnxInQDrops','ifJnxInRunts');
my @special_oid = ('1.3.6.1.4.1.2636.3.3.1.1.10','1.3.6.1.4.1.2636.3.3.1.1.11','1.3.6.1.4.1.2636.3.3.1.1.12');
my @special_oid_desc = ('Framing Errors: The number of input packets which were misaligned.','Drops: The number of packets dropped by the input queue ofthe I/O Manager ASIC.','Runts: Frames received that are smaller than the runt threshold.');
#$target_lines = $default_target_lines."\n";
for (my $i = 0; $i < @special_oid_name; $i++) {
my $el = $default_target_lines;
$el =~ s/^(Target\S+:\s+).+/${1}$special_oid[$i]$if_ref&$special_oid[$i]$if_ref:$router_connect/m; # Error Target
$el =~ s/^([^\s\]]+)/${1}.$special_oid_name[$i]/gm; # Filename for error log and graphs
$el =~ s|</h1>| - $special_oid_name[$i]</h1><span style="color: white; background-color: black;">$special_oid_desc[$i]</span><br />|i;
$el =~ s|^(Title\[.+)|$1 - $special_oid_name[$i]|mi;
$el =~ s/Traffic/$special_oid_name[$i]/;
$el =~ s/^(MaxBytes)(\S+)\s+\d+/$1$2 10000/m; # more than 10'000 errors a second are BIG trouble anyway
$el .= <<LEGEND;
YLegend$2 $special_oid_name[$i] per Minute
ShortLegend$2 e/min
Legend1$2 $special_oid_name[$i] per Minute
Legend3$2 Maximal 5 Minute $special_oid_name[$i]
LegendI$2 $special_oid_name[$i]:
Options$2 perminute,noo
LEGEND
if (oid_pick($router_connect,$v3opt,"$special_oid[$i].$if_index")){
$target_lines .= $el;
}
$target_lines =~ s{<tr>\s+<td>(.+?)</td>\s+<td>(.+?)</td>\s*</tr>}{<tr><td>$1</td>\t<td>$2</td></tr>}g;
}
|
If you want to use it the template has to be passed as an argument to cfgmaker like so (Line 13):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | /usr/bin/cfgmaker \
--global 'workdir: /var/www/mrtg-rrd' \
--global 'Forks: 5' \
--global 'LogFormat: rrdtool' \
--global 'Options[_]: bits' \
--global 'WithPeak[_]: ymw' \
--no-down \
--show-op-down \
--ifref=name \
--ifdesc=alias \
--enable-ipv6 \
--if-filter="$default && !($if_type ~~ [1, 53, 131])" \
--if-template=if_errors.tmpl \
public@$device:::::2 \
>> $device_err.cfg
|
After that running MRTG with $device_err.cfg will create graphs like this one:
I hope this article is of some help and spares you of many hours searching the web.