Never ending Spam

nospamHeute halten wir uns schlicht und einfach und möchten die Allgemeinheit und die IT-Welt mal wieder vor den ganzen Spam-Wellen warnen. Derzeit kommen diese mit ZIP Files in unterschiedlichsten Zusammenhängen.
Beispiele sind Nachrichten von Ihrer freundlichen Apotheke, der Post/DHL wegen einer Sendung, dem Telefonbetreiber zwecks Rechnung oder Kündigung oder dem Klassiker der Bank. Wer bei seinem Filter Zip als Anhang durchlässt wird es aber auch schwer haben diese Spams derzeit zu filtern. Wieder ein Grund mehr ZIPs nicht als Anhang zuzulassen, E-Mails sind nicht zum File-Transfer entworfen worden 🙂
Es gibt sicher eine Person im Kreis der Verwandten von jedem, wo man sicher ist, das dieser derartige Nachrichten samt Anhang öffnet. Hier kann man nur noch einmal warnen, das z.B. die o.g. Absender einem nicht ohne weiteres eine Mail mit dubiosem Anhang schicken.
Daher bitte weitersagen, das man vor dem öffnen der Anhänge erst einmal die Nachrichten genau prüfen soll. Bin ich überhaupt Kunde, hat der Absender eigentlich die Adresse, wird man direkt angesprochen (Name, Vorname).
Und wer Hilfe bei Setup seines Mailservers braucht kann gern auf unsere Unterstützung zurückgreifen oder den Service direkt bei uns nutzen.

Listen filtern in Python

Zum Abschluss dieser Woche kommt von meiner Seite noch ein wenig Code. Angenommen wir haben eine Liste von Benutzern (users) und möchten nur auf den gesperrten weiterarbeiten, so können wir diese, auf verschiedene Art und Weise filtern:


disabled_users = []
for user in users:
    if user.disabled:
        disabled_users.append(user)

Das ganze geht natürlich auch noch etwas eleganter mit list comprehension oder der Built-in-Funktion filter:


disabled_users = [user for user in users if user.disabled]
def is_disabled(user):
    """Returns True if user is disabled else False.
    """
    ...
disabled_users = filter(is_disabled, users)
# oder:
disabled_users = [user for user in users if is_disabled(user)]

Die oberen Beispiele erzeugen jeweils eine neue Liste. Um dies zu verhindern, arbeiten wir mit folgender Modifikation auf Referenzen des Listeninhalts:


users[:] = [user for user in users if user.disabled]

Der “[:]”-Operator erzeugt uns hier eine shallow copy der Liste.
Wer jetzt noch den Unterschied zwischen Generatoren und Iteratoren kennt, bekommt mit folgender Zeile die ultimative 🙂 Art, Listen zu filtern:


users[:] = (user for user in users if user.disabled)

Schönes Wochenende.

Eric Lippmann
Eric Lippmann
Lead Senior Developer

Eric kam während seines ersten Lehrjahres zu NETWAYS und hat seine Ausbildung bereits 2011 sehr erfolgreich abgeschlossen. Seit Beginn arbeitet er in der Softwareentwicklung und dort an den unterschiedlichen NETWAYS Open Source Lösungen, insbesondere inGraph und im Icinga Team an Icinga Web. Darüber hinaus zeichnet er sich für viele Kundenentwicklungen in der Finanz- und Automobilbranche verantwortlich.

Nginx als lastverteilter Bild Konverter

Der bekannte Webserver nginx, auf dem ca. 6% aller Webseiten des Internets laufen und der auch noch Reverse Proxy- und pop3/imap Proxyserver sein kann,  hat noch eine andere, oft wenig beachtete Möglichkeit. Mit Hilfe seines Image Filters ist es möglich, ihn als lastverteilten Lieferanten für Bilder zu benutzen, die er on-the-fly in andere Größen skalieren kann.

1. Lastverteilung

Nginx kann von Haus aus Anfragen an andere Webserver verteilen. Hierzu definiert man zuerst einen Upstream Server.

upstream cache_group {
server :8888 weight=100;
server 127.0.0.1:8888 weight=1;
}

Im vhost der die ersten Anfragen annimmt, definiert man dass der Webserver zuerst schaut, ob er das optimierte Bild schon hat, bzw. wenn das Original gefordert wird dieses sofort ausliefert.

server {
       listen   80;
       server_name mein_Server;
       location = /favicon.ico {
               #empty_gif;
               return 204;
       }
       location / {
               root                    /var/www/images;
               rewrite "^\/(50|100|150|200|250|300|350)\/(.*)\.(jpg|png)$" /$1/$2.$3 break;
               rewrite "^\/(.*)\.(jpg|png)" /$1.$2 break;
               error_page              404 = @cache;
       }
       location @cache {
               internal;
               proxy_pass              http://cache_group;
               proxy_store             on;
               proxy_store_access      user:rw  group:rw  all:r;
               proxy_temp_path         /var/www/temp;
               root                    /var/www/images;
       }
}

Falls der Server das Bild nicht findet schaut er, statt die error_page 404 auszugeben, in der cache_group nach. Hier greift die bei Upstream eingerichtete Gewichtung der Server. Nginx wird 100mal so oft auf dem zweiten Image Server suchen wie auf sich selbst. Wenn das Bild auch auf dem anderen Server nicht gefunden wird, wird es dort generiert. Das sorgt natürlich dafür, dass der erste Server entlastet wird. Das Verzeichnis /var/www sollte ein gemeinsames Share sein, damit das generierte Bild auch beiden Servern zur Verfügung steht.
Die im vhost eingestellten rewrite Regeln sind nötig, um unterscheiden zu können, welche Größe des Bildes angefordert wird, bzw. ob einfach das Original benutzt wird. Ruft der Client http://mein_Server/300/testbild.jpg ab bekommt er das Bild aus /var/www/images/300/testbild.jpg. Bei http://mein_Server/testbild.jpg greift die untere rewrite Regel und er kommt auf /var/www/images/testbild.jpg

2. Bildoptimierung

Der vhost für den Cache sieht folgendermaßen aus:

server {
        listen 8888;
        server_name mein_Server;
        location / {
                root                    /var/www/images/;
                error_page              404 = @local_image;
        }
        location @local_image {
                internal;
                proxy_pass              http://local_group_image;
                proxy_store             on;
                proxy_store_access      user:rw  group:rw  all:r;
                proxy_temp_path         /var/www/temp;
                root                    /var/www/images;
        }

Von hier aus springt er, falls das Bild dort nicht finden kann in den Image teil.
Hierfür muss man zunächst noch einen Upstream angeben:

upstream local_group_image {
        server 127.0.0.1:7777;
}

Und anschließend den vhost inklusive Imagefilter und Sicherheitscheck (es sollen nur die Größen erstellt werden, die wir vorher angeben) erstellen. Der Sicherheitscheck funktioniert durch den Regex in der Location Direktive.

server {
        listen 7777;
        server_name mein_Server;
        location ~ "\/(50|100|150|200|250|300|350)\/.*\.(png|jpg)$" {
                root    /var/www/images/;
                rewrite "^\/(50|100|150|200|250|300|350)\/(.*)\.(jpg|png)$" /$2.$3 break;
                image_filter resize $1 $1;
                image_filter_buffer 6M;
                image_filter_jpeg_quality 95;
        }
}

Jetzt sollte alles so funktionieren, wie wir uns das vorstellen. Das Konstrukt ist natürlich noch um weitere Server erweiterbar. Auch zusätzliche Aufgaben, wie z.B. SSL oder andere Bild Formate sind schnell integriert. Wen man so weit ist, wie hier beschrieben, hat man eine skalierbare, stabile und leicht gewichtige Lösung die mit ein wenig Mehrarbeit auch Ausfallsicher ist.

Christoph Niemann
Christoph Niemann
Senior Consultant

Christoph hat bei uns im Bereich Managed Service begonnen und sich dort intensiv mit dem internen Monitoring auseinandergesetzt. Seit 2011 ist er nun im Consulting aktiv und unterstützt unsere Kunden vor Ort bei größeren Monitoring-Projekten und PERL-Developer-Hells.