Monthly Archives: September 2017

distributed teams

De cand o ard freelancer, cu exceptia proiectelor in care ma duc cateva zile la client sa fac cate o chestie punctuala, lucrez in echipe distribuite pe proiecte la distanta:

  • eu si cu oamenii de la client
  • eu, alti freelanceri si oamenii de la client

Ce inseamna distribuit? Pai ca fiecare suntem pe unde ne nimerim si facem treaba impreuna. Fiecare cu ce stie mai bine cand e super mult de treaba, sau fiecare cum e mai liber sau cand e ceva de depanat si trebuie sa ne punem capetele la contributie.

Cel mai important in toata treaba asta e sa ne sincronizam cu ce facem, ce planuri avem etc. Pentru ca nimeni nu poate tine minte tot ce-a zis, sau ce-o sa facem sau cum, mai ales cand nu ai mintea intr-un singur loc tot timpul, dar chiar si-asa.

Ce merg ca si tool-uri pentru asta:

  • Slack (in mare parte) pentru conversatii in timp real care sa ramana si scrise, snippet-uri de configuratii sau cod, iar in ultima vreme chiar si pentru conferinte. Skype e o idee super proasta pentru ca mai pierde mesaje, clientul se misca super greu cand sunt multi oameni care scriu (cel putin ala nou de pe mobil e o retardare crunta).
  • Skype/Hangouts in mare parte pentru conferinte. Desi pe Skype merge cu clientii corporate ca nu-i lasa politicile de firma pe Slack. In principiu merge orice solutie de videoconferinta care permite si screen-sharing.
  • JIRA. Urmarirea task-urilor, “accountability” in sensul de cine ce-a facut si cand. Exista si alte sisteme de ticketing, insa pe unde m-am dat doar JIRA era.
  • Google Docs pentru prezentari, scris documente in echipa (ocazie cu care am ajuns sa urasc mailurile alea cand se plimba un document pe la fiecare sa mai scrie ceva in el si dupa aia ala de trebuie sa le puna cap la cap se sinucide subit).
  • Confluence (unde e) pentru documentat procese, arhitecturi, howto-uri si alte cele. Acum mai nou (de anul asta) stie si asta de editare concurenta, ceea ce e foarte misto. Daca nu e confluence, atunci Wiki-ul din GitHub. Sau orice altceva tip Wiki unde sa ai mereu informatia la zi.
  • GitHub pentru cod. De obicei scripturi sau chestii de configuration management. Merg si solutiile hosted precum GitLab, da tre’ sa ai grija de ele :))

Ca toata treaba asta sa mearga bine, e nevoie de doua componente esentiale:

  • Comunicarea (duh). Adica sa fii la curent la ce lucreaza membrii echipei, sa spui cand te apuci sa faci ceva sa nu se trezeasca altul ca i-ai restartat masina pe care lucra, iar in cazurile sensibile sa explici ce vrei sa faci si de ce ca sa elimini erorile de gandire. Ca desi poate ai o idee buna, aplicand-o strici mai multe decat repari.
  • Procesul. Adica treaba de mai sus sa zici ce faci, tichete prin care se poate urmari progresul si documentarea operatiunilor sau, dupa caz, adaugarea de comentarii utile in cod sau pe commit-urile de git. E foarte important aici sa n-o arzi “cowboy style” ca se duce totul pe pula super repede.

Periodic, o data pe saptamana sau mai rar/des in functie de volumul de munca si de cati sunt in echipa, niste teleconferinte de sincronizare fac minuni. E ca terapia in grup: fiecare spune la ce lucreaza, raspunde la intrebari de la altii ca sa inteleaga lumea mai bine lucrurile, se formuleaza planuri, se dezbat si se trag concluzii.

Este de remarcat faptul ca in functie de cat de OK este echipa si de cum se raporteaza membrii echipei unii la altii, cu atat mai productive sunt aceste teleconferinte. Suna a truism, dar daca raportul de forte este dezechilibrat, rezultatele nu vor fi chiar cele asteptate.

Lucrul asta merge super bine cand te cunosti cu aia cu care vorbesti, si bine cand nu te cunosti dar esti “on the same page” sau la acelasi nivel de cunostinte. Si prost, evident, cand nu exista deloc aliniere intre oameni, cunostinte si proiect.

Ce nu merge prea bine e cand faci lucruri remote si nu te-ai vazut niciodata cu oamenii cu care lucrezi si exista intelegeri diferite asupra aceluiasi lucru. Treaba asta am rezolvat-o prin a ma duce sa ma vad cu oamenii, sa vorbim, sa discutam si de alte chestii in afara de munca si atunci lucrurile se imbunatatesc.

Fara un pic de “personal touch” nu prea merge treaba asa cum ar trebui, si prin asta se elimina multa neintelegeri si sincope in colaborare.

Evident, sunt si lucruri care nu merg distribuit daca co-echipierii nu au experienta cu ceva anume si este si greu sa explici cum vrei sa arate lucrurile de la distanta. Oricate desene ai face, nimic nu se compara cu dusul la fata locului si explicat/aratat ce si cum. Dar aici se aplica treaba cu vizita la fata locului descrisa mai sus.


Ziceam la inceput ca “fiecare pe unde e”. Asta poate insemna mai multe lucruri:

  • fiecare e in acelasi timezone sau +/- o ora, maxim doua.
  • fiecare e pe continente diferite.

Pentru proiectele care necesita lucru cu clientul in timpul programului lui de lucru, atunci e  bine sa nu fii la prea multe ore distanta fata de client; ca nu e nici o distractie sa ai conferinte la 4 dimineata sau la 12 noaptea, sau sa incepi programul la 17 si sa termini la 02. Sau sa incepi la 4 dimineata sa apesi butoane. Cel mai important aspect fiind ca-ti futi tot ritmul circadian si o sa fii mereu defazat fata de restul societatii, da daca esti mai “special” e ok, nu pierzi nimic :))

Pentru proiecte cu activitati asincrone si fara restrictii, cum ar fi tichete care trebuie rezolvate/implementate oricand, atunci orice loc cu ceva Internet e suficient, ca poti fi si +/- 11 ore fata de client ca n-are importanta.

Astea fiind zise, cand lucrezi distribuit sau solo, ideal ar fi sa ai numai clienti care nu necesita sa fii si tu treaz cand sunt ei la munca, si in felul asta sa poti sa te plimbi peste tot in lume ca n-ai nici un impediment. Sau mai bine zis, asta ar fi “the perfect work/life balance” ;)

ipv6 & ipsec & bugs

Mai anul trecut la inceput de vara ma jucam io in niste masini virtuale cu Layer2 peste Layer3 in Linux. Anul asta am gasit un client unde sa bag jucaria in productie sa vad ca toate treburile merg cum trebuie si pe bune :)

Eh, pentru ca atunci cand ai optiuni multe iti vin idei, am zis ce-ar fi daca intre 2 gateway-uri de VPN as face io conexiunea pe IPV6 in loc de IPv4, ca e bine sa fim pregatiti de viitor :))

Am pus io doua CentOS 7, configurat interfete & shit, am pus libreswan, am facut un tunel IPSec si am dat ping6 intre cele doua masini si a mers jucaria (tcpdump zicea ca vede ESP pe fir).

Ca oricem om prevazator, zic sa dau reboot ca poate am uitat sa configurez ceva sa porneasc la boot si daca ramai fara curent sau s-o panica kernelul de singuratate, sa mearga treaba cand dai restart de la buton.

Si dau io restart si evident ca pula tunel. ipsec status zicea ca e in CONNECTING, da nici in loguri si nici pe fir nu vedeam vreun pachet plecat la alalalt gateway. Ce-are, ce-are. Dat restart la libreswan, o lua. Am zis ca poate e vreo problema cu libreswan, ca mai dadusem de una draguta un pic inainte.

Aia draguta era misto, ca fix imediat dupa boot nu voia sa ridice tunelul de nici un fel. ipsec auto –up $nume_conexiune zicea ca nici una din cheile RSA nu e buna de folosit pentru autentificare, insa fara a modifica nimic, dupa un libreswan restart brusc deveneau bune cheile.

De draci ajunsesem la o varianta taraneasca, dupa pornirea sistemului sa-si dau un start/stop manual s-o ia.

Hai ca zic merge tunelul, sa fac niste teste de trafic cu ping6 sa vad daca MTU-ul e cum trebuie, dau io ping6 -s 1500 si timeout. Pe la vreo 1300 bytes si ceva payload mergea. Pun de mana MTU-ul la 9000 (ca interfete gigabit) si dau iar ping6, si iar timeout. Mai dau si un restart lu’ libreswan (ca vorba aia: when in doubt, restart) ca poate fiind pornit se uita o data la MTU si dupa aia o tine cumva cont de el. tcpdump zicea ca pachetele pleaca da nu ajung.

Uite asa m-am trezit io in zona crepusculara, unde lucrurile in teorie trebuiau sa mearga iar in practica erau diferite de teorie. Si e frustrant ca zici ca, mortii ma-sii, e un VPN, mai mult de cateva ore n-are ce sa ia, ca doar ma dau cu IPsec pe Linux de cand eram mic si stiam ce fac.

Dupa o zi de injuraturi, am oprit IPSec, si zic hai ca in clar tre sa mearga cacatul si o iau dupa aia pe dos sa vad unde se strica. Intre astea doua masini aveam un switch ca sa simulez realitatea. Si zic sa pun un cablu direct intre ele sa elimin orice element in plus care ar putea sa induca erori.

Evident, cu cablu direct mergea treaba de n’avea aer. Acuma switch-ul avea porturi gigabit si cablurile erau bagate in el in porturile alea. Si totusi ce n’avea switch-ul pe porturile gigabit? Jumbo frames in pizda ma-sii. Jumbo frames n-avea. Ca HP in vasta sa inteligenta s-a gandit ca probabil nu sunt bune si n-a implementat suport pentru ele in switch. Si uite asa ai conexiune la gigabit da cu frame-uri de maxim 1504 bytes, sa incapa si un VLAN tag acolo da nimic in plus.

Dupa dracii cu HP, m-am intors la problema initiala, de ce ma-sa dupa reboot n-o ia tunelul. S-a facut tarziu si m-am dus sa dorm.

Evident ca n-am dormit ca ma rodea problema, mi-am facut repede un laborator cu doua CentOS 7 si zic sa incerc strongswan in loc de libreswan, ca poate o avea ala suport mai bun pentru ce fac. Suport in a vorbi cu framework-ul de XFRM din kernel unde se intampla magia.

Fac repede o configuratie si dau reboot la un nod, si dupa reboot pula tunel. Dupa niste tcpdump ma loveste problema: Cand un neighbor IPv6 vrea sa afle ce adresa MAC are alt neighbor, trimite pe multicast FF02::1 un mesaj de Neighbor Solicitation (echivalent de mesajul trimis pe broadcast in IPV4 pentru a afla MAC-ul unui computer din reteaua locala) si primeste unicast un raspuns.

Ce se intampla in kernel in combinatie cu IPSec-ul: pachetele de solicitation plecau cum trebuie si ajungeau la alalalt nod, ala raspundea unicast si nodul care a trimis solicitarea le ignora pentru ca… tananana… se astepta sa fie criptate conform configuratiei (SA-urile erau facute intre 2 /128).

Acu la 2 noaptea stiam care e problema, sa o si rezolv:

conn ipv6nd
   auto=route
   keyexchange=ikev2
   authby=never
   type=passthrough
   leftsubnet=2001:abc:def:ffff::2/128[ipv6-icmp/136]

Unde leftsubnet reprezinta IP-ul aluilalt gateway, iar pe ala se face pe dos configuratia. Et voila, merg chestiile dupa configuratia asta.

Ce inseamna ce-am facut mai sus? Inseamna ca sistemul va accepta pachete ICMPv6 Neighbor Advertisement necriptate. E important ca regula asta sa fie scrisa prima in config ca sa aiba precedenta fata de urmatoarele. E ca la firewall, de sus in jos :)

Asa, acu c-am rezolvat-o, am trecut la pasul urmator. Tipul conexiunii era de tip transport, ca aveam treaba sa protejeze doar traficul intre cele 2 gateway-uri.

Peste am facut un tunel L2TPv3 si cateva sesiuni sa car niste VLAN-uri dintr-o parte in alta. Pe fiecare cap aveam o interfata fizica cu tag-uri de VLAN, una de pseudowire, ambele bagate intr-un bridge.

Pe o interfata de bridge am pus o adresa IPv4, la fel si pe alalalt gateway si minune… mergea ping-ul intre ele. Scopul declarat fiind sa le folosesc pe post de adrese de management pe un VLAN de management.

Cu experimentul pe IPv4 reusit, am pus un set de adrese IPv6 pe interfetele de bridge asteptand acelasi rezultat. Si-am asteptat, si-am asteptat… cum asteapta un caine parasit stapanii care nu se mai intorc.

Pentru ca IPv6 e special, cand ai o adresa pusa pe interfata de bridge, neighbor solicitation nu se duce doar pe interfetele de compun bridge-ul, ci pe toate interfetele din sistem, mai putin pe alea de pseudowire.

Aci ma panicasem un pic, ca sa nu pot sa fac management pe IPv6 nu era un capat de lume, da incepusem sa ma gandesc ca daca se intampla la fel si pe trafic intre 2 host-uri din acelasi VLAN care trec prin jucaria mea?

Well, aci am avut noroc si asta nu se intampla. De aflat am aflat testand si injurand iar HP-ul ca are ceva cu pachetele de IPv6 multicast si nu merge Neighbor Discovery. O sa investighez daca intr-o versiune mai noua de firmware au facut lucrurile sa mearga.

De ramas am ramas la strongswan din mai multe motive:

  • pare mai robust fata de libreswan
  • suporta DH Group 19/20/21 (curbe eliptice, chei mai mici, securitate mai mare)
  • suporta chei de tip ECDSA (cu ocazia asta mi-am facut si niste certificate digitale pe 521biti de tip Elliptic Curve)
  • nu are dilemele lui libreswan cu cheile (ba sunt bune, ba nu sunt bune)
  • merge OK partea de fragmentare a pachetelor care depasesc MTU la nivel de IKE (e misto sa dai ping cu -s 65000 si sa mearga fara sa faci nimic)
  • are suport de TFC (traffic flow confidentiality) pe IKEv2 in mod tunel. Asta inseamna ca face padding pana la MTU-ul interfetei si indiferent de cat trafic ai de fapt, unu care sta cu urechea pe fir va vedea mereu pachete de 9000 bytes (in cazul gigabit ethernet), fara sa stie exact cat sunt date utile si cat e gunoi.

Cu procesoare care au AES-NI (Intel Ivy Bridge sau mai noi) exista si accelerare hardware pentru criptare, via aesni_intel, mai ales daca AES e folosit in GCM. La fel, functiile de hash pentru integritatea datelor pot fi efectuate direct pe procesor prin sha512-ssse3 daca se foloseste SHA512 la IPSec.

Long story short, merge. Bine, merge da violat un pic tot setup-ul ca am dat de un bug in kernel care e nefixat in toate versiunile cu care am testat, adica de la 3.10 la 4.5 sau 4.10 cat era ultimul din CentOS 7 plus cand am testat.

BUG-ul e super misto: dupa cam o saptamana, moare treaba si fara reboot nu-si revine. Si asta se intampla pe ambele gateway-uri.

Dupa miliarde de draci si debug in fata serverului cu monitor si tastatura ca in vremurile bune, am descoperit problema, si anume un leak in kernel, mai mult de file descriptors din ce am bunghit pana acum.

Ce se intampla, ca e atunci cand se schimba cheile, nu se face free la esp6 si xfrm6 daca pe aceasi masina e si un tunel L2TP pentru setup-ul de pseudowires. Si creste utilizarea modulelor pana se strica jucaria.

[root@vpn-gw-1-1-c7-v ~]# lsmod | grep esp6
esp6 17180 1566 
[root@vpn-gw-1-1-c7-v ~]# lsmod | grep xfrm6
xfrm6_mode_transport 12631 3132

Si cand ajungi la cateva sute sau chiar mii, pocneste si nu mai merge. Si asta doar in combinatie cu modulul de L2TP pentru IPv6.

Pentru a rezolva asta, varianta cea mai buna a fost sa fac o masina virtuala in care sa termin partea de L2TP. Adica pe masina fizica am partea de IPSec intre capete, dupa care pe masina virtuala am facut multe interfete: una de inbound pe unde vin pachetele de L2TP si multe pe care sa scot pachetele in cate in un bridge, VLAN tagged sa le dau mai departe.

Postul asta trebuia sa-l public anul trecut cam acum (28 Septembrie 2016), da am uitat de el, da nu conteaza, ca BUG-ul nu e fixat nici acu si jucaria merge de atunci, line rate, fara nici o problema. Ar fi frumos sa fie si BUG-ul ala fixat pentru simplificarea setup-ului.

Cum setup super perfect nu exista, acum e un pic urata adaugarea de noi VLAN-uri pe acelasi pseudowire, in sensul ca trebuie sa le adaug de mana si sa editez si fisierele de configuratie astfel incat sa fie ce trebuie la reboot. Asta e din cauza ca pe CentOS nu exista script de network pentru a seta interfete de tip l2tp_eth. Insa e OK, ca nu schimb zilnic setari.