OpenVPN Python Firewall

Python Firewall

Da un mese a questa parte mi e’ capitato di controllare i logs del mio demone VPN (OpenVPN) e trovare “strani” messaggi tipo questo

an 29 19:32:22 openvpn[1715]: 87.162.209.63:43237 TLS Error: TLS handshake failed
Jan 29 19:32:22 openvpn[1715]: 87.162.209.63:43237 SIGUSR1[soft,tls-error] received, client-instance restarting
Jan 29 19:32:23 openvpn[1715]: 87.162.209.63:6235 TLS Error: TLS key negotiation failed to occur within 60 second

Una rapida ricerca su google sul codice di errore mi porta a pensare che qualcuno sta cercando di autenticarsi sul mio server usando un protocollo diverso rispetto a quello impostato.

La soluzione piu’ ovvia sarebbe quella di cambiare la porta su cui il demone VPN e’ in ascolto (port 1194), con una meno conosciuta… ma purtroppo questo non puo’ essere il mio caso perche’ alcuni miei client hanno tutte le porte bloccate tranne quella di default.

La mia soluzione e’ stata quella scrivere un piccolo script in python il quale ha il compito di leggere il file di log ogni ora (esattamente 12 minuti dopo ogni scoccare di ora)

12 * * * * python /home/unicondor/pythonFirewall/OpenVpnParser.py -s /var/log/openvpn > /home/unicondor/out.txt 2>&1

ed andare a prendere quelli IP che per 50 volta hanno provato ad autenticarsi sul server VPN.

Una volta avuta questa lista, possiamo procedere con l’aggiornare iptables e la chain di INPUT droppando tali ip

# iptables -A INPUT -s ip_to_block -j DROP

Lo script in python e’ disponibile al seguente indirizzo

https://github.com/flaviopace/pythonOpenVpnIpBlocker

Parser Python per pagine HTML

Python Parser HTML
Python Parser HTML in azione

Dopo (tanti) anni di studio ed un lavoro (precario) credo sia arrivata finalmente l’ora di iscrivermi all’albo degli Ingegneri, ma prima di farlo ho cercato di fare una piccola statistica su quanti ingegneri c’erano nella mia provincia (Potenza) e a quale tipo di specializzazione appartenessero.

Purtroppo lo strumento di ricerca del sito ( http://www.ordingpz.it/albo/Albolist.asp ) mette a disposizione dell’utente poche opzioni di ricerca, per tale motivo ho rispolverato la cara e vecchia libreria python Beautiful Soup per scrivere un piccolo script python il quale mi aiutasse ad effettuare il parsing di più pagine HTML e tirasse fuori i dati che mi interessavano.

Il sito in questione (http://www.ordingpz.it) ha una pagina web per ogni ingegnere iscritto all’albo. Tale pagina contiene i vari dettagli dell’ utente, compreso il campi che a me interessavano: “Settore” e “Specializzazione“.

Al seguente link è possibile avere un esempio reale del dettaglio dell’utente (l’ingegnere non è stato scelto a casa, ma è un mio amico con cui ha avuto il piacere di lavorare assieme).

http://www.ordingpz.it/albo/Alboview.asp?N__ISCR_=2714

Dalla sintassi dell’URL si capisce che ad ogni account è associato un ID (N__ISCR_) numerico univoco.

Per tale motivo il primo passo è stato quello di capire come estrapolare questi ID per poi andare a processare ogni singola pagina.

La prima parte dello script serve proprio a questo, a tirare fuori tutti gli ID dal sito.

Get ID

import urllib2
from bs4 import BeautifulSoup
import sys

f = open(‘IngPZAll.txt’, ‘w’)

url = “http://www.ordingpz.it/albo/Albolist.asp?pageno=1&t=Albo&RecPerPage=3000”
print url

try:
data = urllib2.urlopen(url).read()
except:
print url

soup = BeautifulSoup(data)

n = soup.findAll(“td”,{“width”:”100″})

#print n
numIscr = []

for i in n:
numIscr.append(i.div.string)

A questo punto la lista numIscr contiene tutti gli ID dell’albo degli Ingegneri di Potenza, adesso non ci resta che accedere alle singole pagine degli user e memorizzare tutte le informazioni che ci servono.

Il ciclo for può esterno non va altro che prendere tutti gli ID contenuti in numIscr , accedere alla pagina dell’utente ad esso associato e tramite BeautifulSoup effettuare il parsing della pagina HTML per tirare fuori le informazioni.

Parse HTML

[sourcecode language=”python”]
for i in range(len(numIscr)):
url = “http://www.ordingpz.it/albo/Alboview.asp?N__ISCR_=”+str(numIscr[i])
f.write(url+”\n”)
print “Parsing “+ str(i) + ” of ” + str(len(numIscr))
print url

try:
data = urllib2.urlopen(url).read()
except:
print url

soup = BeautifulSoup(data)
#print soup.prettify()
n = soup.findAll(“td” , “ewTableHeader”)

fields = []

for i in n:
fields.append(i.string.encode(‘ascii’,’ignore’))

n = soup.findAll(“div”)

values = [];

#print n
count = 0;

for i in n:
count=count+1;
#print count
if(i.string != None and count > 19):
#print i.string
values.append(i.string.encode(‘ascii’,’ignore’))

for i in range(len(values)):
try:
f.write(str(fields[i]+ “: “+values[i]).encode(‘utf-8’)+”\n”)
except:
print fields[i]+ “: “+values[i]

f.write(“\n”)

f.close()
[/sourcecode]

Nella lista fields saranno elencati tutti i campo della tabella (Ex. Nome, Cognome, Specializzazione ecc) ed in quella values tutti i valori dei campi prima citati. Lo step successivo è quello di scrivere tutte queste informazioni in un unico file per poi poter fare tutte le nostre statistiche in maniera semplice ed immediata.

Il file IngPZAll.txt è output dello script, ed avrà al suo interno il dettaglio di tutti gli ingegneri iscritti all’albo.

Output Example

[sourcecode language=”text”]
..
..
..
http://www.ordingpz.it/albo/Alboview.asp?N__ISCR_=2714
N Iscrizione: 2714
Cognome: MONACO
Nome: Pierpaolo
Luogo di Nascita: Potenza
Data di Nascita:
C.F.:
Indirizzo:
CAP:
Citt:
Provincia: PZ
Sezione: A
Settore: Civile ed Ambientale, Industriale, Dell’Informazione
N Iscrizione: 2714
Data Iscrizione: 04/01/2012
Specializzazione: Informatica
Sede Laurea: Roma
Data Laurea: 21/03/2011
Sede Abilitazione: Roma
Anno Abilitazione: 2011
Ordine di Provenienza: Potenza
Data Prima Iscrizione: 04/01/2012
..
..
[/sourcecode]

Ora con una semplice comando bash posso facilmente capire ciò che volevo…

[sourcecode language=”bash”]
unicondor@iMac:> grep -c “Specializzazione: Informatica” IngPZAll.txt
19
[/sourcecode]

Ecco l’informazione che cercavo, su 2506 iscritti all’albo solo 19 hanno come specializzazione Informatica 😀

Attach:

alboIngPzParser.py

IngPZAll.txt

GitHub Project:

https://github.com/flaviopace/SimplePythonHTMLParser

P.s. tutti i dati che trovate in questo articolo solo liberamente disponibili sul sito dell’albo degli Ingegneri di Potenza

Facebook Hacker Cup 2 Round: my Card Game Solution

FacebookHackerCup 2 Round

This is my solution to the problem of Card Game, work fine for small input… but when the value of k grows (k>500 ) my code spent a lot of time.

The bottleneck it’s about the iteration to find the max in the array…

So i hope you can optimize it 😀

[sourcecode language=”python”]

import sys
import math
from collections import Counter
import re
import itertools

in_file = open(sys.argv[1],"r")
exp = in_file.read()
in_file.close()

inputFile= exp.split("\n")

index=[]
values=[]

def findsubsets(S,m):
return set(itertools.combinations(S, m))
a=[]
flavio=1
for i in range(1, len(inputFile)-1) :
values=[]
allsub=[]
if(i%2) :
# index.append(inputFile[i])
n,k=map(int,inputFile[i].split())
else :

values= map(int,inputFile[i].split())

# Optimization , not call a function
allsub=itertools.combinations(values,k)

my_sum=0

for f in allsub:

my_max=max(f)
my_sum += (my_max)

if(my_sum>=1000000007):
my_sum = my_sum -1000000007

print "Case #"+str(flavio)+": "+str(my_sum)

flavio +=1

[/sourcecode]

GitHub

https://github.com/flaviopace/FacebookHackerCup2_CardGameSolution

Facebook Hacker Cup Qualification 2013: le mie soluzioni in Python

Hacker Cup Facebook

Quest’anno sono riuscito a partecipare (me ne sono ricordato :P) all’Hacker Cup che Facebook organizza ogni anno. I problemi per le qualificazioni erano 3 e di seguito vi posto le mie soluzioni scritte in python.

Il terzo problema (Find the min) non e’ difficile, sono riuscito a risolverlo ma il tempo che ci impiega il mio algoritmo e’ molto al di sopra di quello che mette a disposizione Facebook. In realta’ bastava guardare un po output della lista che utilizzavo per memorizzare i valori per capire che da un certo punto in poi si ripeteva ( per cui non serviva tutta la potenza di calcolo che avevo immaginato 😛 ). In poche parole per gli indici della liste pari a 2k+1, i valori si ripetevano… me ne sono accorto troppo tardi ed ho finito solo i primi due step 😀

1 – Beautiful strings  (20 points)

beautiful_stringstxt.txt

outputFile.txt

[sourcecode language=”python”]import sys
import math
from collections import Counter

in_file = open(sys.argv[1],"r")
exp = in_file.read()
in_file.close()

a= exp.split("\n")

b=[]
c=[]

values=[]

d={}
u={}

for i in range(1, len(a)-1) :

b.append(a[i].lower()[::-1])

flavio=1
for i in b:
d={}

values=[]
num=26
find=1
numSum=0
for k in range(0,len(i)):

#d[str(i[k])] = i.count(i[k])
if(str(i[k]).isalpha()):# or str(i[k])==’!’):
d[str(i[k])] = i.count(i[k])

for k in range(0,len(i)):
if (str(i[k]) in d):
# print i[k] + " num "+ str(num) + " # " + str(d[i[k]])
numSum += num*d[i[k]]
values.append(d[i[k]])
del d[i[k]]
num -=1

values_sorted= sorted(values, reverse=True)

num=26
numSum =0
for item in range(len(values_sorted)):

numSum += num * values_sorted[item]
num -=1
print "Case #" + str(flavio)+ ": " +str(numSum)
flavio +=1
[/sourcecode]

2 – Balanced Smileys  (35 points)

balanced_smileystxt.txt

outputBalanced.txt

[sourcecode language=”python”]import sys
import math
from collections import Counter
import re

in_file = open(sys.argv[1],"r")
exp = in_file.read()
in_file.close()

b=[]
c=[]

values=[]

d={}
u={}

for i in range(1, len(a)-1) :

b.append(a[i].lower())

replacements = {":(",":)"}

for i in range(0,len(b)) :
#b[i]= b[i].replace(

b[i]= re.sub(r’\([^)]*\)’, "", b[i])

b[i]= b[i].replace(‘:(‘,”)
b[i]= b[i].replace(‘:)’,”)

def isBalanced(strInput):
"""Validate if an input string is having balanced bracket pairs
this includes bracket ordering. i.e a round bracket must be closed
by a round bracket. Emtpy strings are treated as balanced."""
#if strInput:
# list of all bracket kinds, in paired tuples
brackets = [ (‘(‘,’)’), (‘[‘,’]’), (‘{‘,’}’)]
# define fake constants – python does not support the concept of constants
kStart = 0
kEnd = 1
# internal stack used to push and pop brakets in the input string
stack = []

for char in strInput:
for bracketPair in brackets:
if char == bracketPair[kStart]:
stack.append(char)
elif char == bracketPair[kEnd] and len(stack) > 0 and stack.pop() != bracketPair[kStart]:
return False

if len(stack) == 0:
return True

#return False

flavio=1
for i in range(0,len(b)) :
if(isBalanced(b[i])):
print "Case #" + str(flavio) + ": YES"
else:
print "Case #" + str(flavio) + ": NO"

flavio +=1

[/sourcecode]

3 – Find the Min  (45 points)

find_the_mintxt.txt

outputFindTheMin.txt

[sourcecode language=”python”]import os, sys

f = open(sys.argv[1], ‘r’)

T = int(f.readline())

def next(ary, start):
j = start
l = len(ary)
ret = start – 1
while j < l and ary[j]:
ret = j
j += 1
return ret

for t in range(T):
n, k = map(int, f.readline().strip().split(‘ ‘))
a, b, c, r = map(int, f.readline().strip().split(‘ ‘))

m = [0] * (4 * k)
s = [0] * (k+1)
m[0] = a
if m[0] <= k:
s[m[0]] = 1
for i in xrange(1, k):
m[i] = (b * m[i-1] + c) % r
if m[i] < k+1:
s[m[i]] += 1

p = next(s, 0)
m[k] = p + 1
p = next(s, p+2)

for i in xrange(k+1, n):
if m[i-k-1] > p or s[m[i-k-1]] > 1:
m[i] = p + 1
if m[i-k-1] <= k:
s[m[i-k-1]] -= 1
s[m[i]] += 1
p = next(s, p+2)
else:
m[i] = m[i-k-1]
if p == k:
break

if p != k:
print ‘Case #%d: %d’ % (t+1, m[n-1])
else:
print ‘Case #%d: %d’ % (t+1, m[i-k + (n-i+k+k) % (k+1)])
[/sourcecode]

Riferimenti:

https://www.facebook.com/hackercup/problems.php?round=185564241586420

Correct Solution Find The Min

http://facebook.stackoverflow.com/questions/14536384/python-too-slow-of-large-inputs

 

GitHub

https://github.com/flaviopace/FacebookHackerCupQualification2013

 

Python: UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\u20ac’

Chiunque abbia fatto un minimo di parsing HTML tramite Python, ha incontrato almeno una volta questo fatidico errore (almeno lo spero, altrimenti sono l’unico pseudo smanettone ad averlo avuto 😛 ), soprattutto se il parsing e’ stato effettuato su pagine web in cui la valuta e’ l’Euro, dato che \u20ac rappresenta il simbolo “” (dannato Euro, anche nel mondo dell’informatica ci da’ problemi).

Il problema deriva avviene quando Python cerca di codificare il simbolo  € con un carattere ASCII.

Codifica?? Uhm?? se sei confuso come me… continua a leggere 😀

Prima di continuare facciamo un piccolo ricapitolazione di “Fondamento di Informatica”…la cosa piu’ importante da sapere e’ che: l’oggetto str in Python memorizza il suo valore come bytes, cioe’ con una sequenza di 8-bit, a.k.a string. Per questo motivo ogni carattere ASCII viene codificato in 8-bit, questo vuol dire che abbiamo a disposizione 0-255 rappresentazioni diverse… ma questo non e’ sufficiente per rappresentare i caratteri Russi, Arabi, Giapponessi… ed il nostro famoso simbolo dell’euro.

Per superare questa limitazione, Python usa unicode che memorizza il carattere con 16-bit o 32-bit dandoci la possibilita’ di rappresentare qualsiasi simbolo in qualsiasi linguaggio.

Voi direste.. Evviva! basta usare l’unicode e risolvo il problema, giusto? NO, non puoi…. ci mancherebbe che il mondo dell’informatica sia cosi’ logico e “clean” 😀

In particolare, non si puo scrivere su un file usando l’unicode, perche’ il file vuole una stringa che sia rappresentata da 8-bit. Dato che Python e’ molto “smart” cerchera’ in automatico di codificare/uniformare il carattere in unicode per la scrittura su file (o qualsiasi altro stream, come la shell), ma ahime’ c’e’ un problema… vediamo meglio con un esempio.

[sourcecode language=”python”]
>>> price_info = u’the price is \u20ac 5′
>>> type(price_info)
<type ‘unicode’>
>>> f = open(‘priceinfo.txt’,’wb’)
>>> f.write(price_info)
Traceback (most recent call last):
File "", line 1, in ?
UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\u20ac’ in position 9: ordinal not in range(128)
>>>
[/sourcecode]

What happened?? Quando Python cerca di scrivere nel file “the price is € 5”, egli cerca di trasformare il valore unicode ‘\u20ac‘ in un carattere ASCII ad 8-bit… ma prima abbiamo detto che ASCII non contiene il carattere in questione… per cui… mi stai seguendo?? 😀

La soluzione e’ semplice (dopo che ho passato almeno una nottata su stackoverflow 😛 ):

[sourcecode language=”python”]
>>> price_info_enc = price_info.encode(‘utf-8’) # >> price_info_enc
‘it costs \xe2\x82\xac 5’
>>> type(price_info_enc)
<type ‘str’>
>>> f.write(price_info_enc)
>>> f.close()
[/sourcecode]

Semplice!! abbiamo codificato l’unicode tramite ‘utf-8’, il quale usa una sequenza di 3 caratteri ‘\xe2\x82\xac‘ per rappresentare il simbolo dell’Euro , in questo modo possiamo passare facilmente da ‘utf-8′ ad ASCII.

Ovviamente nel caso volessimo leggere il simbolo al contrario ( cioe’ vedere sullo schermo il simbolo dell’euro) dovremmo procedere con la decodifica dei tre caratteri in ‘utf-8′ e poi effettuare il print 😉

Ma c’e’ davvero gente che legge i miei post??? Mmmm ne dubito… ma come sempre, questo post mi servira’ da qui ad una settimana, visto che la mia memoria e’ scarsa e mi capitera’ di nuovo di imbattermi in questo problema… spero almeno di ricordarmi di aver scritto qualcosa sull’argomento 😛

Programma Unire Workout Sport-Tracker

Overview Applicazione Sport-Tracker

** VERSIONE AGGIORNATA 1.2 **

Non c’è più bisogno di specificare i Km da aggiungere, per tale motivo accetta solo due parametri come ingresso: i due .gpx file da unire

 

Era da un bel po’ che non pubblicavo qualcosa sul blog, oggi con la scusa di dover unire due mappe/percorsi fatti con il software Sport-Tracker mi sono cimentato nella realizzazione di un piccolo programmino in Python che non fa altro che unire due percorsi in uno solo.

Partiamo subito con due esempi:

Supponiamo di essere partiti da un Punto A ed aver azionato il nostro Workout ( il percorso tracciato con il GPS tramite il software Sport-Tracker ) e di esserci fermati in attimo in un Punto B e di aver premuto erroneamente il tasto “Stop” al posto di “Pause” ( succede molto spesso a me 😛 ). In questo modo abbiamo chiuso il primo Workout senza avere la possibilita’ di poterlo di nuovo riazione e continuare con il conteggio dei Km e/o minuti.

Con questo piccolo programmino possiamo unire due Workout a nostro piacimento in un’unico Workout, in modo da conservare il corretto valore dei Km percorsi, del tempo e di tutte le relative informazioni.

 

Passiamo all’esempio, supponiamo di avere il primo Workout esportato nel formato .gpx: first.gpx ed un secondo Workout second.gpx e volessimo unirli per avere un unico Workout

Tramite il programma in Python sport_tracker_union.py ora e’ possibile unirli (Scaricate il file dal link appena postato, dato che ci sono problemi con la formattazione e l’indentata del codice Python qui di seguito).

[sourcecode language=”python”]

import sys
import math

def usage():

print " Syntax: "
print "$ python sport-tracker-union.py file_one.gpx file_two.gpx "

if len(sys.argv)<3:
usage()
exit()

find_word = False

in_file = open(sys.argv[1],"r")
print "Leggo file: " + str(in_file)
exp = in_file.read()
in_file.close()

in_file1 = open(sys.argv[2],"r")
print "Leggo file: " + str(in_file1)
exp1 = in_file1.read()
in_file1.close()

a= exp.split("\n")
b= exp1.split("\n")

km_to_add = 0

out_file = open("route.gpx","w")

for out in a:

if (int(out.find("</trkseg>"))!= -1):
#print "entro break"
break
else:

find_km = out.split(" ")

for i in range (len(find_km)):

if (find_km[i].find("Distance") != -1):

km_to_add = float(find_km[i+1])

out_file.write(out+"\n")

for string in b :

if (string.find("trkpt") != -1) or find_word:

find_word = True

find_km = string.split()

for i in range (len(find_km)):

if (find_km[i].find("Distance") != -1):

distance=float( find_km[i+1])
new_distance = distance + km_to_add

stringa_new= string[0:string.find("Distance ")-1] + " Distance " + str(new_distance) + " km</desc>"+"\n"

out_file.write(stringa_new)
else:
out_file.write(string+"\n")

out_file.close()

[/sourcecode]

La sintassi per usare il programma e’ molto semplice, basta specificare nell’ordine il primo file .gpx di partenza ed il secondo file .gpx da unire.

[sourcecode language=”bash”]
$ python sport_tracker_union.py first.gpx second.gpx
[/sourcecode]

in questo modo in output si crea un file di nome route.gpx che potra’ essere importato direttamente dal sito di Sport-Tracker :D, tale file non sar’ altro che la copia (quasi) speculare di first.gpx e la copia modificata di second.gpx con l’aggiunta dei Km che in automatico calcolerà dal primo file .gpx

Immagino questo programmino serva solo a me… almeno ho sconfitto la pigrizia che mi impediva di scrivere qualcosa sul blog 😀

Ecco il mio ultimo Workout caricato utilizzando il mio programma, non vi resta altro che seguirmi 😀

 

P.s. dato l’enorme successo 😛 presto sarà on-line anche una versione con l’interfaccia grafica…

 

GitHub

https://github.com/flaviopace/SportTracker_Union_Workout

Primi Passi Con Python…

Grazie a Coderloop, ho iniziato a passare le mie serate cercando di risolvere qualche Quiz messo a disposizione dal sito, potendo utilizzare qualsiasi linguaggio di programmazione.

Per i primi esempi ho usato Java e C ( i pochi corsi universitari sui linguaggi di programmazione sono serviti a qualcosa 😛 ), per poi passare ad un linguaggio piu’ ad alto livello ed orientato agli oggetti come il Python per rendere il tutto piu’ celere usando una sintassi meno pignola. Infatti in Python , come in PHP , non abbiamo bisogno di definire variabili, istanziarle, effettuare il garbage collection degli oggetti e molto altro.

Di seguito vi incollo qualche pezzo di codice che mi e’ stato molto utile nell’implementazione dei miei primi esempi.

Passaggio di parametri da riga da comando e conseguente lettura del file passato come stringa di ingresso. Stampa a schermo del file letto
[sourcecode language=”python”]import sys

in_file = open(sys.argv[1],”r”)
exp = in_file.read()
in_file.close()

print exp
[/sourcecode]
 

Definizione di una Funzione ReverseString:

 
[sourcecode language=”bash”]import sys

stringa = “vitadastudente”

def reverseString(s):

return s[::-1]

print reverseString(stringa)
[/sourcecode]
 

In Python state molto attenti all’indentatura, dato che non si utilizzano parentesi per delimitare i blocchi del codice. Un esempio dell’implementazione del codice di Fibonacci

 
[sourcecode language=”bash”]
def fib(n):
print ‘n =’, n
if n > 1:
return n * fib(n – 1)
else:
print ‘end of the line’
return 1

[/sourcecode]
Spero questi piccolissimi esempi vi siano serviti a qualcosa, ora non vi resta altro che “smanettare” e mettervi anche voi alla prova con questo linguaggio di programmazione 😀