Etikettarkiv: python

Nytt projekt: Antivirus

IT-säkerhet, webbutveckling och devops är de tre delar som jag gillar allra mest. Och nu har jag äntligen utvecklat en ny typ av antivirus-produkt som använder alla dessa.

Denna nya tjänst som jag utvecklat är helt klart intressant och riktar sig både till privatpersoner och företag. Den är skapad för att hitta skadlig kod som andra produkter ej troligtvis hittar: riktade intrång, zerodays, rootkits etc.

Tanken är att först köra en beta-period helt gratis för privatpersoner och dra lärdom om hur produkten ska utvecklas. Även spännande för mig har varit att den mesta av koden är skriven i Python,  Windows kommer initialt att stödjas. Python är populärt och hipster-mjukvara såsom Dropbox är utvecklad i Python.

Hoppas även på en Mac OS X version men det ligger nog lite längre bort även det skulle behövas.

Psst, du följer väl Kryptera.se där jag bloggar om IT-säkereht och kryptering?

Docker är kittet i DevOps

Docker

Då och då dyker det upp mjukvara som underlättar livet avsevärt, då man nästan utropar Heureka! När jag först lärde mig använda Fabric så tycke jag att detta var ju guld värt: Att slippa göra samma sak manuellt på flera servrar. DevOps-filosofin i ett nötskal

Men! Nu tog jag mig tid och försökte lära mig Docker. Docker har tagit det hela lite längre och isolerar filer samt processer från underliggande operativsystem samt innehar versionshantering. Vad innebär detta då?

Jo, för sådana som mig som har beroenden långt utanför vad vanliga webbhotell kan leverera såsom Redis, Sphinx och Memcache så är Docker en mjukvara som löser detta.

Man kan kort och gott säga att Docker är ett operativsystem i operativsystemet. Lite som Xen eller Vmware men mycket ”lättare”.

I detta underliggande operativsystem så utgår du från en spegelbild som fungerar som bas och allt du lägger till får en ny revision. Detta gör exempelvis om du vill flytta en webbsajt med Redis, MySQL och Sphinx Search från en server till en annan så behöver du enbart flytta det som ändrats från spegelbilden.

Docker är så klart öppen källkod och helt gratis att använda. Och inte nog med det så är det ett MeetUp om några veckor i Stockholm om just DevOps och Docker med talare från bl.a. Spotify:

GitHubs sökfunktion, en guldgruva

Innan jag fortsätter med nästa inlägg i min serie om DevOps med Python/Fabric så tänkte jag tipsa om Githubs relativt nya avancerade sökfunktion. Denna sökfunktion har räddat mig många gånger då jag funderat hur en viss funktion kan användas eller exempel på kod hur saker kan genomföras.

Om du vill lära dig hur du kan sätta datornamn (hostname) via Fabric så kan följande sökning genomföras:

python fabric

Kolla även in den avancerade sökfunktionen:

DevOps med Python Fabric

DevOpsOm du har precis som mig många servrar som är utspridda på flertalet leverantörer så finns det några smarta hjälpmedel för att underlätta administration och deployment av ny kod. Ett av dessa hjälpmedel heter Fabric och är snarlikt med Capistrano för Ruby.

På en Ubuntu-kärra så är det lättast att bara köra apt-get install fabric så får du prylarna du behöver på ett nafs (alternativt pip install fabric).

Testa sedan med:

$ fab

Fatal error: Couldn't find any fabfiles!

Remember that -f can be used to specify fabfile path, and use -h for help.

Aborting.

Det finns olika sätt att sedan använda fabric för att exekvera kommandon på flertalet servrar. De vanliga är att man skapar fabfiles eller bakar in det man vill göra direkt i sin Python-kod efter en import fabric.

Fabric i Python via import fabric

Rätt enkelt och behövs inte så många rader kod. Vår kod ser ut enligt nedan och startas med python kodnamn.py:

#!env python
from fabric.api import run,env,hosts,execute

env.key_filename = "/home/jonasl/jonasl.pem"
env.user = "ubuntu"

@hosts(['79.125.115.128'])
def uname():
  return run("uname -a")

execute(uname)

Ovan kod beskriver först vilken nyckelfil (pem) vi använder. Precis samma sak som att köra ssh -i jonasl.pem. Och env.user berättar vilken användare vi loggar in med.

Sen använder vi en rolig sak i Python som kallas för dekorator (decorator) och den sätter vilken IP-adress vi ska ansluta mot. Denna dekorator behövs inte i nästa exempel som skiljer sig lite.

Fabric direkt via kommandoskal och fabfile

När man använder kommandot fab så läser Fabric direkt en fil som heter fabfile.py i samma katalog som man står i och där kan man placera kommandon såsom ovan uname som ska köras mot olika servrar. Först skapar vi fabfile.py som ser ut så här:

#!env python
from fabric.api import run,env,hosts,execute

env.key_filename = "/home/jonasl/jonasl.pem"
env.user = "ubuntu"

def uname():
  return run("uname -a")

Sen kör vi bara fab -H ip-nummer uname på följande sätt:

$ fab -H 79.125.115.128 uname
[79.125.115.128] Executing task 'uname'
[79.125.115.128] run: uname -a
[79.125.115.128] out: Linux syslog 3.2.0-53-virtual #81-Ubuntu SMP Thu Aug 22 21:21:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
Done.
Disconnecting from 79.125.115.128... done.
$

I nästa avsnitt ska jag gå igenom lite mer hur man kan använda olika server-roller för att skjuta utkod via git.

Vad händer?

blogbackupr

En liten statusuppdatering vad jag pysslar med eftersom jag är så dålig på att uppdatera bloggen:

Håller på att sälja av Blogbackupr + Bloggbackup och kommer snart att läggas upp på Flippa.

Har byggt om lite på https.se så det är lättare att beställa SSL-certifikat. Bl.a. möjligheten att välja faktura direkt och använder Billogram. Dock ej deras API ännu, men det kommer nog.

Förbereder sista delarna på en ny startup som kommer att ha release på Internetdagarna.

Underlättar administration av alla mina servrar med Python + Fabric och försöker bli en ninja på JavaScript.

På det mer personliga planet så har jag anmält mig till IRONMAN Kalmar 2014 och tränar en hel del inför tävlingen.

Från HTML till text

Ett av de vanliga problem man stöter på om man skriver en egen webbcrawler/spider eller vill genomföra scraping (skrapning?) är att konvertera HTML-sidor till ren text. Detta kan tyckas som en tämligen enkel uppgift men trasig html och tolkning av html är några saker kan ställa till det en hel del.

Att exempelvis ladda in Aftonbladet.se i Python Beautifulsoup kan ta flera sekunder. Därför så sökte jag efter en lösning som inte bara är snabb men även passar sig för att baka in i en webbcrawler.

Det var då jag hittade Boilerpipe. Ett bibliotek att detektera och plocka bort runtomkring text på en webbsida och enbart returnera det som förhoppningsvis är huvudtexten på sidan.

Boilerpipe är skriven i Java men fungerar utmärkt i Python med jpype. Här finnes Python porten på github: github.com/misja/python-boilerpipe

För att sedan använda Boilerpipe i Python skriver du enbart:

from boilerpipe.extract import Extractor
extractor = Extractor(extractor='ArticleExtractor', url=your_url)

Extractor kan vara någon av följande:

  • DefaultExtractor
  • ArticleExtractor
  • ArticleSentencesExtractor
  • KeepEverythingExtractor
  • KeepEverythingWithMinKWordsExtractor
  • LargestContentExtractor
  • NumWordsRulesExtractor
  • CanolaExtractor

Jag fick bäst resultat med KeepEverythingExtractor i de få tester jag genomförde.

Så analyserar och använder du iPhone Appars API

Visste du att majoriteten av alla iPhone och iPad-appar använder någon form av API?

Jag tänkte gå igenom hur du själv kan använda dessa API:er i dina egna implementationer med hjälp av exempelvis PHP eller Python. Observera att informationen som du hämtar via API:er eventuellt inte användas till vad som helst då den kan omfattas av upphovsrätt eller andra lagar.

Först och främst så måste vi ladda hem någon form av Proxy-programmvara som medger analys av den API-trafik som går fram och tillbaka från iPhonen och Appen. Jag rekommenderar Charles Proxy som är gratis att använda men det finns även en betalversion för ynka 50$ som jag har köpt (du slipper ”nag-screens” och sådant). Charles Proxy fungerar för Linux, Mac och Windows.

Här är en skärmdump på hur det ser ut när du startat upp Charles Proxy:

Så, det första vi ska göra är att stänga av så att vi ej ser all webbsurf till och från vår egna dator och det kan man göra under Proyx-fliken och sedan se till att ”Windows Proxy” ej är förkryssad.

Nästa steg är att vi ska skicka ett E-brev med Charles SSL-certifikat till vår iPhone för att ges möjlighet att analysera krypterad HTTPS-trafik till och från telefonen. Ladda hem följande ZIP-fil: charlesproxy.com/ssl.zip och packa upp den där du sedan hittar en .CRT fil som du bifogar i ett mail som du sedan kan öppna på din iPhone (Dropbox eller annan typ av filöverföring går säkert också bra).

När du lagt in Charles certifikat i din telefon bör det se ut så här under Inställningar -> Allmän -> Profil (längst ner):

Då var det nästa steg, och det är att ta reda på IP-adressen till din dator. Jag brukar använda cmd.exe och sedan skriva ipconfig så bör det se ut något i stil med:

Denna IP-adress skall vi ange under inställningarna som det nätverk vår iPhone är ansluten till. I mitt fall så är det via WiFi och längst ner under inställningarna för det trådlösa nätverket anger jag IP-adressen till min dator som kör Charles Proxy så det ser ut så här:

Sedan är det bara att starta den App som vi vill analysera på iPhonen, i mitt fall så startar jag Swedavias App vid namn Arlanda flygplats. Och se hur Charles Proxy visar API-anropen efter varandra. Eftersom vi är intresserad av Avångar så klickar jag helt enkelt på Avångar i Arlanda Appen och får upp följande intressanta API-anrop i Charles:

Fleratalet parametrar är intressanta att anteckna eftersom de behövs vid anrop från PHP eller Python. Det varierar från app till app men i detta fall är det URL:en för anrop som innehåller flygplats (airport=arn_utr) samt datum (searchDate=2011-08-10).

Tittar vi på XML-svaret så ser det ut enligt följande:

När vi sedan implementerat en funktion som härmar denna förfrågan så bör vi få ut samma XML-svar i slutändan och kan då exempelvis hämta hem avgångar med PHP och CURL på följande sätt:

<?php
  $today = date("Y-m-d");
  $path = '/ArrivalsDeparturesMobile/ArrDepMobileService/ArrDep.asmx/GetDeparturesFlightTable?airport=arn_utr&language=sv&searchString=&searchDate='.$today;
  $host = "wsc1.swedavia.se";

  $headers = array(
    "GET $path HTTP/1.1",
    "Host: $host",
    "User-Agent: Arlanda/1.4 CFNetwork/485.13.9 Darwin/11.0.0",
    "Authorization: Basic V1NBcnJEZXBNb2JpbGU6c1AtR0U1NWJlY3I4c1BhKWhlMHBlNXJ1NkVmYUNyRSE=",
    "Accept: */*",
    "Accept-Language: sv-se",
    "Accept-Encoding: gzip, deflate",
    "Pragma: no-cache",
    "Connection: keep-alive"
  );

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "http://".$host.$path);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

  $sXML = curl_exec($ch);

  $oXML = new SimpleXMLElement($sXML);

  print_r($oXML);

?>

Ovan kod kan du sedan köra från kommandotolken enligt följande:

$ php swedavia.php

Tadaa! Nu slipper vi använda vår iPhone varje gång vi ska se avgångar från Arlanda. I detta exempel så behövdes ej SSL-certifikatet användas då anropen skickas i klartext.

NoSQL: Redis, CouchDB och MongoDB prestanda

Eftersom jag testar NoSQL-mjukvaror såom Redis, CouchDB och MongoDB just nu  så genomförde jag ett litet prestandatest där Redis vann över CouchDB och MongoDB.

Så här lång tid tog det att stoppa in 100 000 objekt i en databas:

MongoDB

db version v1.2.2, pdfile version 4.5
real    13.306s
user    9.130s
sys     0.940s

Redis

Redis version 1.3.17
real    7.044s
user    5.330s
sys     0.070s
Redis version 2.1.5 (8d3e063a:0)
real    6.400s
user    4.760s
sys     0.110s

CouchDB

Apache CouchDB version 0.10.0

Fick inte vara med för att det tog 4 sekunder att sätta in 100 objekt. Ungefär samma prestanda som Amazon SQS, och då använde jag även full_commit=False vilket bör öka prestandan. Ska testa Hovercraft för att se om jag kan få upp prestandan.

Observera även att ovan tid inkluderar exekvering av Python, inladdning av moduler samt den kod som körs mellan det att information trycks in.

Att utveckla för molnet

Att utveckla webbtjänster för molnet gör att utvecklingen blir bättre. Jag upplever att jag tvingas att tänka på portabilitet och möjlighet till skalnCC http://commons.wikimedia.org/wiki/File:Bedeckt.gifing på ett annat sätt än när jag vanligtvis skapar webbtjänster.  Detta gör mig troligtvis också till en bättre programmerare.

Låt mig ta några exempel:

1. Istället för att använda Pythons inbyggda köhantering (Queue) så använder jag Redis och får då automatiskt skalning. Dock inte till vilket pris som helst eftersom Redis äter minne. Men med Amazon EC2 och 15GB minne så kommer jag rätt långt. Har testat Amazon SQS för köhantering men prestandan är direkt usel och är inte avsedd för miljoner operationer per sekund.

2. Sökvägar tvingas att sättas dynamiskt eftersom jag använder Amazon EBS där sökvägarna sätts på den extramonteringen som EBS tillhandahåller. Dock är det lite trist att vara låst till en ”zon” hos Amazon.

3. Att inte tänka på begränsningar på samma sätt. Det går alltid att kasta fler servrar, ramminne och hårddisk på problemet så löser det sig utan att behöva införskaffa fysisk hårddvara. Detta är något som jag ser som mycket intressant, att som liten ensam entreprenör kunna bygga stora system med hundratalet servrar. Dock ska ju allt underhållas också..

Finns säkert en drös med andra saker som jag inte kommer på just nu, men lämna gärna en kommentar på vad du ser för fördelar med att använda molntjänster vid utveckling.