Seite wählen

NETWAYS Blog

Request Tracker 4.4 Security Update and UTF8 issues with Perl’s DBD::Mysql 4.042

Last week, Best Practical announced that there are critical security fixes available for Request Tracker. We’ve therefore immediately pulled the patches from 4.4.2rc2 into our test stages and rolled them out in production.

Update == Broken Umlauts

One thing we did notice too late: German umlauts were broken on new ticket creation. Text was simply cut off and rendered subjects and ticket body fairly unreadable.

Encoding issues are not nice, and hard to track down. We rolled back the security fix upgrade, and hoped it would simply fix the issue. It did not, even our production version 4.4.1 now led into this error.
Our first idea was that our Docker image build somehow changes the locale, but that would have at least rendered „strange“ text, not entirely cut off. Same goes for the Apache webserver encoding. We’ve then started comparing the database schema, but was not touched in these regards too.

DBD::Mysql UTF8 Encoding Changes

During our research we learned that there is a patch available which avoids Perl’s DBD::mysql in version 4.042. The description says something about changed behaviour with utf8 encoding. Moving from RT to DBD::Mysql’s Changelog there is a clear indication that they’ve fixed a long standing bug with utf8 encoding, but that probably renders all other workarounds in RT and other applications unusable.

2016-12-12 Patrick Galbraith, Michiel Beijen, DBI/DBD community (4.041_1)
* Unicode fixes: when using mysql_enable_utf8 or mysql_enable_utf8mb4,
previous versions of DBD::mysql did not properly encode input statements
to UTF-8 and retrieved columns were always UTF-8 decoded regardless of the
column charset.
Fix by Pali Rohár.
Reported and feedback on fix by Marc Lehmann
(https://rt.cpan.org/Public/Bug/Display.html?id=87428)
Also, the UTF-8 flag was not set for decoded data:
(https://rt.cpan.org/Public/Bug/Display.html?id=53130)

 

Solution

Our build system for the RT container pulls in all required Perl dependencies by a cpanfile configuration. Instead of always pulling the latest version for DBD::Mysql, we’ve now pinned it to the last known working version 4.0.41.

 # MySQL
-requires 'DBD::mysql', '2.1018';
+# Avoid bug with utf8 encoding: https://issues.bestpractical.com/Ticket/Display.html?id=32670
+requires 'DBD::mysql', '== 4.041';

Voilá, NETWAYS and Icinga RT production instances fixed.

Conclusion

RT 4.4.2 will fix that by explicitly avoiding the DBD::Mysql version in its dependency checks, but older installations may suffer from that problem in local source builds. Keep that in mind when updating your production instances. Hopefully a proper fix can be found to allow a smooth upgrade to newer library dependencies.
If you need assistance with building your own Request Tracker setup, or having trouble fixing this exact issue, just contact us 🙂

CPAN Minus

CpanPerl ist ein etablierter Kanndidat wenn es darum geht, mit kleiner Software Probleme zu lösen. Zum Beispiel ist die nahtlose Integration von Textverarbeitung in Kombination mit regulären Ausdrücken ein unschlagbares Feature.
Perl erweitert seine Funktionalität mit Modulen welche im Comprehensive Perl Archive Network zu Verfügung gestellt werden, kurz CPAN genannt. Unglücklicherweise ist die Nutzung von CPAN immer mit schmerzhaften Erfahrungen verbunden. Builden, Testen, fehlende Abhängigkeiten und megabyteweise Ausgaben führen oft zu einem Fehlschlag und rütteln an der Akzeptanz des Tools.
Seit einiger Zeit wird CPAN Minus immer populärer. Ein Grund ist vermutlich die einfache Arbeitsweise. So kann man ohne Konfiguration und Kommandozeilenschlachten, Module und deren Abhängigkeiten installieren. Na bitte, so geht es also auch.
Beispiele:
Installation unter Ubuntu / Debian:
$ apt-get install build-essential perl # Abhängigkeiten
$ apt-get install cpanminus

Alternativ kann das Skript auch einfach mit Curl oder Wget runter laden:
$ curl -L http://cpanmin.us > cpanm
$ chmod +x cpanm

Die Installation von Modulen kann jetzt auf zwei Arten erfolgen. Entweder installiert man ein einzelnes Modul:
$ sudo cpanm --installdeps Date::Holidays

Oder eine Gruppe von Modulen wird in einer Datei bereitgestellt:
$ head -n3 cpanfile
# Core
requires 'Apache::Session', '1.53';
requires 'CGI', '3.38';
$ cpanm --installdeps .

Alles übrige wird im Hintergrund erledigt.
Nach Jahren der Selbstkasteiung ist das mal ein gutes Tool!

Marius Hein
Marius Hein
Head of IT Service Management

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert und viele Jahre in der Softwareentwicklung gearbeitet. Mittlerweile ist er Herr über die interne IT und als Leiter von ITSM zuständig für die technische Schnittmenge der Abteilungen der NETWAYS Gruppe. Wenn er nicht gerade IPv6 IPSec Tunnel bohrt, sitzt er daheim am Schlagzeug und treibt seine Nachbarn in den Wahnsinn.

Monthly Snap September: Tools for Graphite, OSMC and OSBConf, Poor man´s Cloud and much more

In September Markus W. told us about tools to use to generate metrics for Graphite.
The Open Source Monitoring Conference ist getting and Bernd counted 49 to the conference by sharing Florian Forster tweekly snapalk: „Introduction into collectd“. Michael Medin, our old stager at the OSMC, wrote a guest post where he explained why the OSMC is the best conference and Daniela gave us an insight into the OSBConf which took place in Cologne last month.
Alexander F. looked at the advantages of Perl over PHP and Python while Markus F. followed and showed us poor man´s Docker with own Cloud.
Jean-Marcel, one of our trainees, then explained why dynamic window manager is the best and Alexander K., also trainee,  told us what he learned new  at NETWAYS.
And last but not least, Marius G. reported on the first team event of the managed services guys.

Stephanie Kotilge
Stephanie Kotilge
Accountant

Steffi ist seit 2011 bei NETWAYS. Sie fing als Office Managerin an und unterstützt seit 2017 als Accountant das Finance & Administration Team in allen buchhalterischen Belangen. In ihrer Freizeit ist sie mit ihrem Sohn immer auf der Suche nach den schönsten Spielplätzen in Nürnberg oder plant den nächsten Familientrip.

From Perl to Python and beyond

I’ve seen and learned plenty of programming languages either during my studies or in work or spare time related projects – be it C/C++/C#, VHDL, Java or PHP/Perl/Python/Ruby even (I’ve removed some in my XING profile to reduce recruiter spam level ;)). Choosing the „right“ language is always hard but most of the time the requirements of existing software or newly designed projects allow you to skip that part and already have one in mind.
python-logo-master-v3-TMWhen joining NETWAYS in late 2012, I took over the LConf backend project being entirely written in Perl similar to other plugins and scripts floating around as open source software. Icinga 1.x Core is partially using Perl as well (although embedded Perl in C is a horrible mess). Most recently our development team decided to go for Python as the primary programming language.
So, my Python foo wasn’t that good after some years not really using it. Learning from my colleagues and looking into additional ressources helped a lot. I also found „Head first Python“ from O’Reilly in my bookshelf as a gift from the Nagios/Icinga cookbook review which also provides an extensive introduction into Python – when you already know a scripting language like Perl.
We’ve been working on a customer’s project developing a plugin framework for executing checks via a defined transport (e.g. ssh) and parsing cli output. Find some collected hints and tricks I’ve learned below.

Remove colors from shell output

The EMC „isi“ cli command puts colors into the shell output (e.g. for a critical state turning the background red). While one could disable color support on the shell, this was not possible in that environment. The fix by Gunnar was easy: Parsing text output into a list called „lines“ and clean the line string from shell color codes:

lines = text.split('\n')
lines = [re.sub('\x1b\[[0-9;]*m', '', line).strip() for line in lines]

Convert datetime to unix timestamp

Consider having a datetime string whose output format is not fixed, which means some strftime print magic does not work for proper parsing. Luckily there’s a Python module called dateutil providing the required functionality.

import time
import datetime
import dateutil.parser
def datetime2unixts(time_str):
    dt = dateutil.parser.parse(time_str)
    return time.mktime(dt.timetuple())
$ python
Python 2.7.8 (default, Apr 15 2015, 09:26:43)
[GCC 4.9.2 20150212 (Red Hat 4.9.2-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time, datetime, dateutil.parser
>>> def datetime2unixts(time_str):
...     dt = dateutil.parser.parse(time_str)
...     return time.mktime(dt.timetuple())
...
>>> time_str = "Wed May 13 16:15:34 CEST 2015"
>>> datetime2unixts(time_str)
1431526534.0

Initialize nested dictionary

Similar to what I am used to do with Perl and hashes I was stumbling over this with Python. In Perl one does not care about initializers, but just keeps populating all items like so:

my $hash = {}
$hash{'key1'}{'key2'} = "val1";

In Python this does not work out-of-the-box. There are some modules available such as „collectors“, but I prefer a somewhat native implementation making it work on older distributions. I came across this solution which I consider pure awesome 🙂

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value
hash = AutoVivification()
hash["key1"]["key2"] = "val1"

Note: It certainly does create non-existing keys if you are checking for their existance. My implementation does not care about key checks, but requires known-to-exist values from a flat dictionary with „id_label“ as key stashed into a nested dictionary where id and label are separated/nested for further operations.

        jobs = AutoVivification()  # use a pre-initialized nested dict
        for k, v in sorted(perfdata.iteritems()):
            (job_id, label) = k.split("_", 1)
            if label == "ended_ts":
                jobs[job_id][label] = float(v)
            if label == "started_ts":
                jobs[job_id][label] = float(v)

Fix the indent

If your editor doesn’t do that automatically (e.g. converting tabs into 4 spaces) it might still work, but could also cause weird behaviour in Python depending on the indent only (no brackets as I am used to with Perl). Fixing this is fairly easy by using autopep8 – I’m using Fedora 22:

dnf install python-autopep8
autopep8 check_plugin -i

Note: ‚-i‘ replaces the given file with all the changes. Make sure to commit your other changes to git before.

Conclusion

I never thought that I would dig deep in Python again that easy. I used to hack that in the past with Win2k usb driver test frameworks, and also checkmk plugins, but gaining back experience worked out pretty well.
Icinga 2’s code, value types and configuration look a lot like Python as well – take dictionaries for custom attributes using apply for loops, eh? (Hint: Testdrive this config snippet inside the Icinga 2 Docker container).

object Host "dns" {
  import "generic-host"
  address = "127.0.0.1"
  address6 = "::1"
  vars.dns_checks["dns icinga.org"] = {
    dns_lookup = "icinga.org"
    dns_server = "ns1.netways.de"
    dns_expected_answers = "185.11.254.83"
  }
  vars.dns_checks["dns netways.org"] = {
    dns_lookup = "netways.org"
    dns_server = "ns1.netways.de"
    dns_expected_answers = "185.11.252.37"
  }
}
apply Service for (dns_check => config in host.vars.dns_checks) {
  check_interval = 1m
  retry_interval = 30s
  check_command = "dns"
  vars += config
}

Icinga 2, plugins, your project – here I come 🙂
PS: See you at the OSMC hackathon.

OSDC 2014: Der Countdown läuft – nur noch 8 Tage

NUR NOCH EINE WOCHE!!!
Aber heute gibt’s noch mal Serverorchestrierung mit Rex.

OSDC? Noch nie gehört…
Das ist aber schade und fast schon ein unentschuldbares Versäumnis!
Aber wir holen das nach:
Die Open Source Data Center Conference (kurz OSDC) ist unsere internationale Konferenz zum Thema Open Source Software in Rechenzentren und großen IT-Umgebungen. 2014 findet sie zum sechsten Mal statt und bietet mit dem Schwerpunktthema Agile Infrastructures ganz besonders erfahrenen Administratoren und Architekten ein Forum zum Austausch und die Gelegenheit zur Aneignung des aktuellsten Know-Hows für die tägliche Praxis. Diesmal treffen wir uns dafür in Berlin!
Workshops am Vortag der Konferenz und das im Anschluss an die Veranstaltung stattfindende Puppet Camp komplettieren dabei das Rundum-sorglos-Paket für Teilnehmer, die gar nicht genug Wissen in sich aufsaugen können.