Posts Tagged ‘работа’

2014-06-01 Лекцията ми от Websummit 2014, “Възможности, които всички web услуги трябва да имат”

Sunday, June 1st, 2014

(презентацията)

[slide 2 Идеята за тази лекция]

Идеята за тази лекция ми дойде около няколко разговора с различни хора и от нашият опит с правенето на pCloud. Много често ни се случваше да погледнем конкуренцията как е направила нещо и да се ужасим в първия момент.
(а след това да се зарадваме, че се срещу нас има такива хора)

За всичките неща, за които ще говоря има лесни решения – прости като идея и сравнително лесни за реализация, като правенето им трябва да доведе до един по-добър свят.

Също така в историята има много случаи на проблеми, които са се случвали и за които всички са забравили или просто са отказали да обърнат внимание.

Нищо от това, което ще кажа не е особено ново, гениално или изобщо велико откритие. Всичкото е откриваемо с малко четене в google, wikipedia и от време на време някоя книга. Извинявам се предварително, че нямаме осигурени възглавници за хората, на които ще им се доспи от скучните неща, които ще разказвам.
(ако четете това като текст – нищо против нямам да го ползвате за приспиване)

[slide 3 Защо ние го говорим това]

Ние харесваме добре написаните неща. Също така се стараем да сме максимално отворени откъм API, код и т.н., и за това държим да правим неща, от които да не се срамуваме, или даже да се гордеем с тях.

Също така съм съвсем наясно, че тази лекция звучи като безкрайно фукане. Поне половината е такава :) За това искам да отбележа, че доста от тези грешки сме ги допускал и ние, в този или предишен проект.

[slide 4 Кои сме ние]

Минутка за реклама – ние сме cloud storage услуга, направена правилно. Startup сме, има ни от около година, имаме около 600k потребители и 600TB заето място и правим всякакви интересни неща, за които обаче ще ми трябва тричасов слот, че да ги изброя :)

Стараем се да сме максимално отворени – имаме пълна документация на API-то ни, както и код, който си говори с него. Ние самите за приложенията, които пишем ползваме същото API, т.е. не крием нищо от разработчиците :)

[slide 5 Authentication]

Почти всички услуги трябва да пазят в някакъв вид пароли за потребителите си и да им дават да влизат в системата, за да получат достъп до някаква допълнителна функционалност. Човек би си помислил, че това е изчистено и изяснено и трябва да няма проблеми…

[slide 6 Стандартен метод за auth]

По принцип в повечето случаи влизането в системата се реализира чрез изпращане на user и парола и получаване на отговор/token, с който да работим след това.

Което е лоша идея, понеже паролата ви минава по мрежата в някакъв вид, и не може да сте сигурни дали някой не подслушва или дали някой не се прави на отсрещния сървър.

[slide 7 Правилен метод]

Правилният метод, който използва един прост криптографски примитив, се нарича challenge-response. Има и реализация в самия HTTP протокол, т.нар. digest authentication, както и в много други системи (например SIP). В web твърде рядко се среща, поради нуждата от още една заявка (или поради неинформираността на разработчиците).

Работи по следния начин:
Сървърът ви генерира nonce – някаква стойност, която е произволна, няма да се повтори пак. Смятате криптографски hash в/у нея и паролата и изпращате резултата на сървъра. Той от своя страна може да направи същото изчисление и да разбере, че вие знаете същата парола.

Така никаква информация за самата ви парола не минава през мрежата, така че дори някой да се представя за сървъра, няма начин да бъде научена.

Методът е по-бавен от другия, понеже изисква още една заявка (да си вземете nonce, с който да работите), т.е. вкарва още един round-trip. Това не е проблем, понеже това така или иначе не трябва да е особено бърз процес – т.е. колкото по-бърз е, толкова по-лесно може да се използва за brute-force атаки.

Тази схема с малко разширяване дава възможност и клиентът да потвърди, че сървъра има паролата (т.е. да се получи двустранна auth.), което ще ви оставя за домашно :) Ние все още не го реализираме, но е в плановете за светлото бъдеще.

[slide 9 Plaintext в базата данни]

Пазенето на паролите се оказва проблем, който твърде малко хора успяват да решат.

Така като гледам, сме 2014, и все пак се случва някоя сериозна услуга да пази паролите в plaintext. Това в някакви моменти е удобно – lost password функционалността може да ви прати директно паролата по пощата (сигурността на което няма да обсъждам).

От друга страна обаче, поне няколко услуги биват hack-нати всяка година и паролите им попадат в ръцете на лоши хора (или в целия internet). Това е доста неприятно за потребителите, понеже те въпреки съветите на експерти и други заблудени люде все пак използват същата парола на много места, което води до допълнителни пробиви и подобни неприятни проблеми.
(съвсем скорошен пример – преди седмица-две-три източиха на ebay паролите)

[slide 10 Първи лесен (и грешен) вариант]

Първото решение на проблема, което е лесно и грешно, е просто да се съхранява някакъв криптографски hash на паролата – md5 (много-лоша-идея) или sha1 (не-толкова-лоша идея). Това се атакува тривиално с rainbow таблици.

Съвсем накратко, rainbow таблиците са пресметнати таблици с (почти) всички възможни пароли, така че лесно да може да се намери в тях някакъв валиден string, който да отговаря на дадения hash. Също така имат метод за съхраняване на по-малко данни, та по принцип за md5 таблиците са под 2TB, за sha1 има таблици с повечето пароли пак в някакъв такъв размер.

Накратко – лоша идея.

[slide 11 Втори лесен (и правилен) вариант]

Второто решение (и първото работещо) е известно на света от поне 1970та година, от хеширането на паролите в старите unix системи, дори в повечето езици името на функцията – crypt() идва от там (тя дори не криптира).

Идеята е проста, генерираният hash да е на някакъв salt и паролата. Salt-ът се подбира да е различен за всяка парола, и се слага преди получения hash. Така лесно може да се пресметне, но не може да му се генерира rainbow таблица (т.е. ако се генерира, ще трябва да съдържа и възможните salt-ове).

[slide 12 Трети не-толкова-лесен (но правилен) вариант]

Третият вариант, който може да се използва (и който сме реализирали при нас) е да се пази “частичен” hash на паролата (т.е. по-точно пълния state на hash функцията) и някакъв salt, така че да може и да се реализира challenge-response. Това ни отне малко повече време за реализация, но така не пазим пароли в plaintext и можем да реализираме challenge-response, за да гарантираме максимална сигурност на потребителите си.

Много близко е до lenghtening атаката в/у хешове.

( Корекция след самата лекция: Реално погледнато, challenge-response може да се реализира дори с хеширани пароли по предишния начин)

[slide 13 Четвърти (велик и труден за правене) вариант]

И последният метод, който дава най-голяма сигурност, и който не съм виждал реализиран никъде, освен на една лекция. Идеята му е в общи линии като на password-authenticated key agreement протоколите, повечето от които поне доскоро бяха патентовани и като цяло не се срещат особено често.

На база на паролата се захранва един pseudo-random генератор, от който след това се генерира двойка RSA ключове (частен и публичен). На сървъра се дава само публичния ключ, а клиентът няма нужда да пази нищо, понеже от паролата може да генерира същата двойка когато си реши. Автентикацията става чрез стандартните схеми за RSA и дава възможност да се пазите от всичките атаки по-горе, и дава още едно ниво на сигурност – ако някой ви се добере до базата на сървъра, с информацията после няма да може даже да влиза при вас, т.е. даже няма да има нужда потребителите да си сменят паролите.

За съжаление не съм виждал никъде реализация на схемата. Описанието и видях в една лекция на Дан Камински преди няколко години.

[slide 14 Further reading]

И понеже темата е доста обширна, може да потърсите този стандарт – password-based key derivation function, както и да погледнете конкурсът за нови такива алгоритми за съхраняване на пароли, може да са ви полезни.

Специално PBKDF2 показва едно доста важно свойство на всички тези схеми. Важно е проверката на паролата да не е максимално бързо действие, а да отнема някакво малко, но достатъчно време, така че да да се направят brute-force атаките по-трудни.
Самият PBKDF е схема за прилагане на хеш функция много пъти (1000, 10000 или нещо такова) върху входни данни и salt, така че от това да се получи някакъв набор битове, които да се използват или като съхранена парола, или като ключ за нещо друго. Поради големия брой действия, които няма как да се направят по-лесно, лесно може да се сметнат параметри, които да ви дадат нещо като 10ms за извършване на сметката, което да доведе до невъзможност да се правят повече от 100 теста в секунда на един core.
М/у другото, пример за използвана такава схема е WPA при wi-fi мрежите – там ключът за комуникация се генерира с pbkdf2 с 1000 пъти sha1 и essid-то (името) на мрежата за salt. Ако някой е пробвал да чупи такива пароли знае, че върви доста по-бавно, отколкото просто на хешове.

[slide 15 Комуникация]

Изразът с тъпата брадва идва от едно изречение на Дийкстра, “Молив не може да се наостри с тъпа брадва, същото важи и за 10 тъпи брадви”. Подобен израз, който може би е по-подходящ (и за който се сетих на лекцията) е “Манчестърска отвертка” – която всъщност е чук, идеалният инструмент за решаване на всякакви проблеми.

[slide 16 Стандартни неща]

По принцип всичко живо използва JSON и HTTP. Те са бавни протоколи, текстови, с много overhead и не-чак-толкова удобни за parse-ване (добре поне, че има такива библиотеки в почти всеки език).

Да не говорим, че HTTP е мислен за съвсем различни неща от тези, за които се използва в момента.

[slide 17 Трябва алтернатива]

Добре е да имаме алтернативи. Не всичките ни клиенти са browser-и, но всички са принудени да ползват интерфейси, писани за тях, което е доста неприятно и на моменти – много неефективно (но понеже хората са свикнали, вече не обръщат внимание). Най-добрият пример е какво ползват мобилните приложения – все http базирани api-та, а те уж са устройства, които трябва да пестят от батерия и CPU колкото се може повече.

Дори в самите browser-и вече не е това единственият подходящ и ефективен начин – в момента навлизат websockets и webrtc, точно заради това.

(имах въпрос от публиката после защо нещо не съм много оптимистично настроен по темата webrtc, човекът (Лъчко всъщност) се надявал да може да замести skype – понеже това, което реално успява да прави skype е да работи през всякакви мрежи и NAT-ове, което за останалата телефония е сложно и не се справя толкова добре. Webrtc-то още не е стигнало да бори наистина сериозно такива проблеми и вероятно ще му трябва доста време, докато започне да се справя с тях).

[slide 18 Примерен binary протокол]

По тази причина ние сме направили допълнителната възможност да може да се комуникира с интерфейсите ни през просто binary api.
Като казвам просто – то наистина е такова, описанието му се събира на няколко страници, реализацията (която имаме публикувана в github) е 700 реда на C или 536 реда на java, заедно с коментарите. Има много по-малко overhead, и се обработва много лесно на всякаква платформа. Също така в себе си има няколко хитрини, например ако в даден пакет определен string се среща повече от веднъж, съдържанието му се пази само на едно място и останалите са reference.

Разбира се, има и други варианти – в един предишен проект сме използвали protobuf (който се оказа доста удобен), има msgpack и какви ли не още отворени проекти с публични реализации за повечето платформи.
(ползвали сме protobuf за един друг проект и даже аз, дето по принцип не пиша код се оправих съвсем лесно да си parse-вам данните)

[slide 19 QUIC и пътят напред]

И да слезем по-надолу – един от проблемите в съществуващите протоколи е, че осъществяването на връзка е бавно. Нужни са 3 пакета (и 1 RTT), за да се осъществи връзка м/у две точки по TCP, а когато добавим SSL/TLS, добавяме и още 2-3 RTT-та в зависимост от някои настройки на протокола.

Едно от съществуващите решения е разработка на google, казва се QUIC – Quick UDP Internet Connections, протокол, който замества комбинацията от TCP+TLS. Има в себе си всички полезни неща от TCP, като правилните алгоритми за напасване на скоростта и congestion avoidance, но криптирането в него е по подразбиране, и осъществяването на връзка става в рамките на едно rtt, заедно с избирането на ключове и т.н..
Има също така интересни feature-и, като например multiplexing – да се обработват няколко заявки в една връзка (като в SCTP). Друго нещо е forward error correction, да може да коригира грешки в пакетите или изгубени такива по вече пратени данни.

Ние сме в процес на разглеждане на протокола, ако ни хареса достатъчно, мислим да го използваме. В момента има поддръжка в chrome и opera, ако придобие достатъчно разпространение, ще реши проблема и с firewall-ите. Разработката на google е пусната под BSD лиценз, и е сравнително малко код на C++, та би трябвало скоро да се появи и на други места.

Като цяло, струва си да прочетете описанието, протоколът е пример как трябва да изглежда следващото поколение internet протоколи.

[slide 20 Употреба на SSL/TLS]

Ако не сте живели под камък в последната година и половина, вероятно сте наясно защо е важно да се ползва криптиране на връзките и по принцип SSL/TLS.
(ако сте, питайте търсачките за Edward Snowden)

Вече повечето услуги имат поддръжка за TLS – отне години и доста лобиране/мрънкане от страна на общността, но е често срещано. Не винаги е реализирано правилно обаче…

[slide 21 Правилна употреба на SSL/TLS]

Първото е, че в твърде много случаи не се обръща внимание на шифрите, които се използват, съответно сигурността на връзката с някои места е почти същата като за без криптография. Пример за това е как преди около година Android смениха списъка си с поддържани шифри/алгоритми и приоритетите им, понеже “в java стандарта било така” (предишния им списък беше взет от openssl). Java 6 е стандарт на около 10 години и в новия е оправено…

Друго важно нещо е т.нар. forward secrecy – това е възможността след осъществяването на връзката двете страни да разменят през DH или друг алгоритъм ключове, които са само за тази сесия и се забравят след нея. Така се подсигуряваме, че дори да изтекат главните ключове на сървъра, то записаната от преди това комуникация няма да може да се декриптира и ще остане тайна.

За заинтересуваните хора, които имат сървъри – на този сайт може да проверите поддръжката си на подходящите алгоритми и шифри, резултатът може да ви е интересен.

И разбира се, SSL/TLS не е панацея, и те имат собствени проблеми (като например heartbleed наскоро).

[slide 22 SSL/TLS Session caching]

За услуги, които имат повече от един физически сървър, който поема криптираните сесии (но на същия domain), има друг полезен момент – да се реализира глобален SSL session cache, който да пази определени параметри, за да не се renegotiate-ват всеки път. Това спестява едно RTT от всяка заявка и определено се усеща.

За целта може да ви се наложи да използвате някакъв backend storage (memcache или redis), в който всичките ви сървъри да пазят тези сесии, но да се подкара не е особено сложно и може да има видим ефект за потребителите ви.

[slide 23 Privacy]

Много услуги правят грешката да разкриват информация за потребителите си, която реално не трябва да излиза извън тях. Например често през някоя функционалност, като lost password или invite може да разберете дали даден потребител е регистриран в услугата.
Това е неприятно, понеже улеснява всякакви атаки в/у вашите потребители, особено ако не сте ориентирани към разпространяване на информацията на потребителите ви и продаването и/им (като почти всички социални мрежи)
(корекция от публиката на лекцията – всички социални мрежи)

Примерът за разкриването дали даден файл (което btw е проблем, който идва основно от дедупликацията в повечето такива услуги) е как един определен service можеше да му кажеш “аз ще ти кача файл с тоя MD5” и той казваше “а, аз го имам, заповядай”. Това за известно време сериозно се използваше за share-ване на файлове без реално да се вижда какво става…

[slide 24 Не всички клиенти са равни]

Изобщо, на моменти имам чувството, че много от интерфейсите са правени от някой, който приятелката му го е зарязала заради някой developer и той сега държи да си го върне. Представям си човек, който стои в тъмна стаичка, пише спецификация и си мисли “и аз на теб да ти го …”…

Няма един правилен интерфейс, един правилен начин, един пръстен, който ги владее и т.н.. Колкото и да ни се повтаря от някакви хора, които нямат въображение, няма да стане вярно :) Има нужда от интерфейси, който да са удобни за различни хора, по различен начин, от различни среди и различни начини на мислене.

[slide 25 Предаване на параметри]

Например, предаването на параметри. При нас параметър може да бъде предаден където ви е удобно – като GET, като POST, в URL-то на POST-а, или в cookie. Даваме ви възможност за прострелване в крака, но от друга страна ви даваме начин да ни ползвате от възможно най-простите клиенти на тоя свят, които нямат POST.

[slide 26 обработка на request-и в движение]

Нещо, което е повече в категорията “имам тъпа брадва и искам с нея да остря моливи” – ужасно много услуги обработват заявката, след като я получат цялата. Ако качвате файл, който трябва после да отиде по други машини, имате една очевидна латентност, дължаща се на последвалата обработка.

Това се дължи най-вече на ползването на HTTP и криви сървъри, и като цяло може да не е така – повечето content може да се обработва в реално време, докато се качва – да се копира на други места, да му се смятат checksum-и и какво ли не още. Не е нужно да караме потребителите да чакат, само защото нас ни е домързяло да направим няколко прости подобрения.

[slide 27 blatant self-promotion]

И оставащата част от презентацията е хубави неща, които са специфични за cloud storage услуги, или “защо ние сме по-добри от останалите”. Не само ние правим тези неща, но май само ние правим всичките.

[slide 28 Thumbnail combining]

Нещо, което пак идва от тъпата брадва на HTTP/AJAX и компания – ако имате да покажете галерия от thumbnail-и, няма смисъл да ги дърпате един по един. Много по-ефективно е да може да ги комбинирате в един голям файл и да ги показвате, докато пристигат.

Конкретните методи за това са доста грозни (thumb-овете, изредени по един на ред в base64 и се декодират после), но си личи промяната в скоростта.

[slide 29 On-the-fly zip]

Нещо, което идва основно от мързела на разработчиците – не е нужно да генерирате zip файл и така да го дадете на потребителя, може директно да му го stream-нете, понеже zip-ът е такъв удобен формат (явно идва от времената, в които е трябвало да може да се пише на лента). Не е единственият такъв, но е пример за как някои неща могат да се случват моментално, вместо да се изчакват.

[slide 30 Rsync-подобен протокол]

Rsync съществува като идея от времената, в които аз бях младши системен администратор, но по някаква причина не се среща достатъчно често като идея в повечето услуги.

Идеята е много проста – ако от едната страна имате част от даден файл или негова по-ранна версия, е много по-лесно да копирате само разликите, а не целият файл. Поддържаме го и в двете посоки – и за качване, и за сваляне на файлове, като самата идея не е сложна за реализация, дори и в web приложения. Не ползваме директно rsync протокола, понеже не пасва добре в нашия интерфейс, но сме сравнително близо, и също така за една част от хешовете използваме друга функция, понеже се оказва по-удобна.

(още нямаме качена документацията за метода, понеже не остана време, обещавам да я качим в най-скоро време. Ще качим и код, който го реализира.)

[slide 31 Видео с напасващ се bit rate]

Една хубава възможност, която доста video услуги биха могли да предлагат – да се напасва bitrate на видеото към връзката ви (т.е. да не праща с повече, отколкото вие може да приемете), което прави възможно да гледате видеа и на доста неприятна връзка.

[slide 32 Файлови операции]

И накрая нещо, което е повече интересно, отколкото важно – интерфейсът за дребни промени по файловете, редакция на място е доста удобен и помага да се пренесат различни приложения и действията им директно към storage услугата.

[slide 33 Други готини неща за в бъдеще]

Тук исках да кажа и други неща, но не ми стигна времето да ги извадя.

Това е един план за светлото бъдеще (в рамките на годината) – да направим end-to-end криптиране на файловете на потребителите, т.е. да им дадем функционалност, чрез която те още при себе си да криптират всичко и да не можем да го четем, както и да са сравнително сигурни, че не не им подменяме или омазваме файловете. Би трябвало всички да го правят – реално погледнато няма причина нещата, които са лични за потребителя да могат да бъдат известни на оператора на услугата, и има доста разработки по въпроса.
Например, има дори няколко paper-а по темата за криптирана база данни – тя стои криптирана на един сървър (който няма ключовете), вие пращате криптирана заявка, сървъра прави някакви сметки и ви дава отговор от вашите данни, който също е криптиран и който само вие може да разберете. Все още нещата са в начални стадии, но са една добра идея за бъдещето.

[slide 34 Отворени сме към други идеи]

Сигурен съм, че има неща, които съм пропуснал в лекцията, и за които не сме се сетили да сложим в нашата услуга. Приемаме всякакви идеи и критики, а тази лекция винаги може да се удължи (например като за едно-семестриален курс).

Приемаме всякакви корекции и идеи – по принцип имаме натрупана работа като за 3-4 години напред, но това още не е успяло да ни уплаши :)

2014-05-18 Stateless auth tokens (lightning talk от PlovdivConf 2014)

Sunday, May 18th, 2014

(презентация)

[slide 3 Често срещана практика]

(този трик вероятно има някакво стандартно име, което аз не знам, цялата лекция ми хрумна една вечер докато не можех да спя и така и не се зарових)

Много често ни се налага да генерираме token/код, който да изпратим на някой потребител (по страничен канал), за да се удостовери. Едно често срещано решение е да се генерира нещо съвсем random, което обаче води до пазене на твърде много state и много често не е практически възможно.

[slide 5 просто решение – подпис с криптографски hash/hash mac]

Проблемът има просто решение, чрез криптографски (hash) подписан token, от който може да се извади цялата информация, без да е нужно да се гледа някакъв state. Генерира се тривиално, като до информацията се долепя един HMAC подпис с някакъв secret, който ви е познат на вас.
(hmac е метод за прилагане на hash функция, например sha1. Не е добра идея да се използва директно SHA1 или нещо от същото семейство, понеже подлежи на lengthening атака, но може да се ползва SHA3)

Така тази информация се проверява тривиално, и не изисква да пазите каквото и да е и да могат да ви препълнят някакви таблици, да генерират писания в базата и т.н.

[slide 6 Инвалидация на token]

Схемата има един проблем – няма прост начин да се инвалидира. За това има няколко различни workaround-а:
Имаме timestamp, при който знаем кога изтича token-а и като цяло го правим да е валиден за кратко.
Слагаме в него нещо, което потребителя може да промени и така да го инвалидира (например паролата му, чрез смяната и може да ги направи невалидни).
Можем и да пазим кога последно сме генерирали token и да не признаваме по-стари (или по-нови) такива.
В общи линии последните две неща ни карат да питаме външен източник, когато проверяваме token-а, но пак ми дават възможност да държим много по-малко state.

[slide 8 VERP ]

За всички, които трябва да пращат поща и да знаят дали адресът не е bounce-нал – проста схема, в която пишем в Return-path: адресът, на който сме пратили писмото и по отговорите на този адрес знаем кой точно не се е получил. Към това лесно се добавя един прост подпис, така че да не се получават случайни писма при някакво глупаво изчерпване.

[slide 9 TCP Syncookies]

Вече default на всички tcp/ip стекове. Идеята е съвсем проста – ISN (initial sequence number) на сесията, който връщаме в SYN+ACK пакета представлява hash на secret и още няколко неща, така че когато получим третия пакет от handshake, можем да сме сигурни, че този клиент е искал да се свърже с нас.
(За повече подробности потърсете за SYN flood и защита от него).

[slide 10 client-side session]

Също така можем да спестим място от потребителски сесии – можем да пазим само последен timestamp и нищо друго, а самата сесия да е в cookie при потребителя и да не ни интересува. Така можем да сме сигурни, че ние сме му я подали и че не съдържа нещо, което не сме искали.

2014-05-09 pandoc

Friday, May 9th, 2014

Никога повече няма да ползва WYSIWYG редактор, за да си пиша презентациите.

(tldr – може да видите какво ползвам в github и да си го нагласяте по ваш вкус)

Преди rogueconf бях решил, че повече не ми се занимава с libreoffice и кривото писане на лекции, та с малко търсене в google и съвети от хора открих pandoc, който се оказа доста удобен инструмент – от markdown генерира pdf презентации (и reveal.js и други такива бози), като сгъва markdown-а до latex, и от него прави pdf чрез beamer модула. Пример за това може да се види в лекцията ми от rouge2014.

Аз обаче имам навика да пиша и текста на самата лекция, освен презентацията, т.е. процесът ми е “бележки, презентация, текст, и после редактиране на последните две докато стават за нещо”. Дразнеше ме идеята, че трябва да редактирам два файла и че не мога да свържа добре нещата, защото обичам после и да блогна текста.

В крайна сметка стигнах до setup-а от github repo-то горе, който изглежда по следния начин:
В един .pandoc файл си пиша презентацията, и след всеки slide – текстът, в html коментар (който pandoc-а игнорира);
Чрез Makefile (щото съм мързел) от .pandoc файла генерирам:
презентация (с разни параметри, които ще разкажа);
бележки (реално текстът на .pandoc файла, подреден чрез a2ps така, че да се събира добре на landscape A4 листи);
blog post, който казва номер на slide, заглавие и след това текста от коментара (което се прави чрез тъп php скрипт, който си написах).

(едно от големите удобства на makefile и т.н. е, че може да си отворите презентацията с evince, при всяка промяна на файл да пускате make и той автоматично ще reload-не файла, така че да си виждате промените)

За да генерирам презентацията, както аз искам (т.е. какво може лесно да пипнете по кода горе) са правени следните неща:

–slide-level 2 – на колко “нива” са ви slide-овете. Примерната презентация е на 2, тази за pCloud api-то е на 3, като май 3 е идеално за нормално 40-минутна презентация и изглежда много добре с тая тема (Warsaw), понеже така отгоре се виждат секцията и под-секцията. Мисля, че май първо видях Харалд Велте да ползва нещо такова и бая ми хареса, но не бях мислил как го прави.

–template beamer.my – наложи се да пипна стандартния beamer template, щото по default не изкарваше кирилица (за pCloud-ската го използвах и да сложа логото в нея, което беше бая куц процес). Също така там има едно място, в което може да махнете да показва slide-ове за тези, които не са от най-долното ниво (т.е. в примерната презентация да няма “проблемът”, “решението” и “примери”).

-V colortheme:krok – има beamercolorthemekrok.sty в директорията, което е crane color theme от beamer-а, само че със сменени цветове (при мен зелено, в pcloud API-то – странно синьо).

Разбира се, може да си изберете и други теми, на този сайт има матрица с комбинациите от тема и тема за цветовете (темите за шрифтовете са малко и май default-а е ок).

Цялото нещо си има и проблеми – добавянето на лого беше супер мъчително (и стана със странен hack, в който не ми се навлиза), да се влияе на шрифтовете от markdown-а до latex-а е малко сложно, и има някакви странности (например, като сложех коментар веднага след заглавния slide, ми добавяше един празен). Също така ако не знаете latex (като мен) може да ви е доста криво да си правите някакви custom неща, но па google е добър приятел и даже в stackoverflow им texexchange, където хората редовно си задават такива въпроси и може да намерите нещо полезно.

RIPE SEE 3

Tuesday, April 15th, 2014

И мина RIPE-SEE-3.

Проведе се в х-л Кемпински, за два дни, беше с малко лекции/workshop-и и доста разговори/networking (видях се с хора, с които не се бях виждал от 10+ години).

Пропуснах първите неща от първия ден, че бях зает да си нося лаптопа на ремонт (и все пак да се наспя), та хванах сесиите след обяда. Първо слушах човека от DT по темата за новата мрежа, която правят (TeraStream) – интересна идея, забавното беше как чак 2011 осъзнали, че мрежата им е остаряла и не става, но па сега я правят както трябва – чист ipv6 (ipv4 е service с тунели отгоре), 100gbps и anycast на интересните услуги. Също така им е хрумнало в адреса да слагат няколко бита, които да играят ролята на QoS битовете, и да раздават няколко префикса на потребител, например един за видео/телевизия, един за voice, един за internet, и мислят как да стандартизират процеса за избиране на source адрес.
RIPE разказаха за различните неща, които правят – конференции и т.н., Erik Vinecke от cisco разказа нещо за мерене на ipv6 deployment-и, което заедно със следващите две неща не слушах, понеже си препрочитах моята лекция.
(чух някакви части от лекцията на Nathalie Trenaman за нейния deployment на ipv6 у тях, и си беше интересно и доста мъчително, Мариян я пита във въпросите що се е мъчила да се занимава с vendor-и, вместо да ползва opensource неща)

Моята (реално на Весо) лекция мина много по-добре, отколкото очаквах, и понеже няма записи малко по-късно ще я напиша на текст и кача заедно с презентацията. Хората изглеждаха заинтересувани, и даже се водеше една от по-техническите на конференцията.

Накрая на първия ден вечеряхме във Весело село (в което никога не бях ходил, и ми стана ясно защо), но храната ставаше, и успяхме даже да направим нещо интересно – да подкараме група на мрежовите оператори (за пореден път), понеже всеки, който питахме там каза “да, бих се записал”. Да видим :)

Втория ден започна с лекция за Ansible (което се оказа някакъв вариант на chef/puppet/cfengine), нищо интересно, след което имаше доста интересна лекция за “Crowdsourcing Infrastructure Geolocation”, т.е. проект, който по различни начини определя къде се намират ip-тата на разни router-и, за да може човек да си визуализира traceroute (note to self, да си оправя всичките DNS LOC записи). Искрено се надявам проекта да успее :)

От следващите неща слушах IXP панела, където от няколко български exchange-а, един чешки и (май единствения) сръбски хората обсъждаха различни оперативни неща. За съжаление не успяха да стигнат до техническата част, но доста дъвкаха for-profit и non-profit моделите, което пак беше интересно.

Следващият слот беше по “Governance” темата и привлече най-страшните въпроси. Първо говори един човек от CERT България (който не беше лектора по програма) и беше в общи линии изяден с парцалите, понеже нищо не знаеше.
После говори Венета Донова за net neutrality-то в Европа и в България, основно за законовите моменти около него – беше разширение и update на лекцията и от openfest (ако не се лъжа), и се получи доста добре.
Последва я Аглика Клайн от Europol EC3 – отдел, който се занимава с техническата част на разследванията, анализа и координиране на операции. В общи линии въпросите към нея бяха “защо да ви вярваме”, “вие сте тия, дето ни тровят най-много живота”, спряхме се на това как детското порно се използва основно срещу доставчиците (имаме си достатъчно такива случаи в България) и т.н., и т.н.. Успя да издържи на въпросите, но се измъкна от някои въпроси. Имаше и момента, че от една страна нямат право да приемат feedback и каквото и да е от хората или фирмите (само от държавите-членки), но от друга страна са пускали по молба на microsoft advisory, да кажат на хората, че XP-то спира да се поддържа.
(после имаше и допълнителни разговори и обяснение как една от причините никак да не ги обичаме е, че ги използват много усилено срещу нас, и че те са от хората, които трябва да се борят за улесняване на security research-а, не срещу него (както са направили в Германия със забраната да се пишат exploit-и), трябва да и пратя на FX лекцията за хардуера, който law enforcement хората ползват и колко е счупен)

Имаше три lightning talk-а, от които единия беше за BGNOG-а (който споменах по-горе), успяхме да стигнем от идея до реализация за около 12 часа.

В последният слот интересните лекции бяха две. Едната беше за RIPE Atlas проекта, и за anchor машините (за които мисля да взема една в нашия datacenter, Мариян се замисли за три), самият проект има лесен начин да се интегрира в monitoring системите ми и мисля тия дни да му отделя малко време. Другата лекция беше сравнителен анализ на internet-а в България, Турция и Румъния, гледан от BGP гледна точка, от Renesys – накратко, в Турция нещата не са добре, при нас и в Румъния са доста по-чисти, като в Румъния са около три пъти по-големи. Удобни сме от гледна точка на латентност за финансови и т.н. институции да си слагат тук нещата, дано успеем да се възползваме.

Като цяло събитието беше страхотно, и трябва да се направи пак (следващото е в Белград догодина, и може би след това пак да се случи при нас), много беше полезно от всякакви гледни точки – и контакти, и свършена работа, и никак не съжалявам за двата изкарани дни. Вероятно ще се сещам още неща и ще дописвам в идващите дни :)

Update: Трябваше да привлачим и Яна на събитието, понеже изкарах накрая поне половин час да давам идеи как да привлекат повече хора – имаше около 220 дошли, и те го считаха за голям успех, но аз си мисля, че даже чистите мрежови администратори в България са поне 150-200 и щеше да им е интересно да дойдат. Едното нещо, което може да помогне е NOG-а, другото – просто да си говорят директно с някакво количество хора/LIR-ове, не през някакви тежки mass mail-вания до адреси от базата им, щото тях никой не ги чете сериозно.

Update 2: Сайт с наземни кабели, за който не знаех (като допълнение на за подводните).

2014-04-08 openssl vulnerability CVE-2014-0160

Tuesday, April 8th, 2014

Не че не сте видели от други места, но:
DSA-2896
heartbleed.com
официалния сайт на openssl.

apt-get update && apt-get -y dist-upgrade и ритнете каквото трябва.

(алтернативното заглавие беше fuckfuckfuckfuckfuckfuckfuckfuckfuckfuck)

Update: Сайт, който тества за проблема.
Update 2 command-line test tool.

2014-04-05 Лекция “Single points of failure и избягването им” от RogueConf 2014

Saturday, April 5th, 2014

Това ми е в общи линии лекцията от rogueconf, презентацията може да се свали от тук, записът от тук. Има прилични разлики в това, което говорих, и реално ми се искаше да наблегна много повече на дистрибутирането, но нямах време да се подготвя и да го събера в нормалното време.

(и определено можеше да е по-добре, не става добре да говоря на конференции, където имам занимания и с организацията)

Single points of failure

[за какво става въпрос]

Single point of failure е единичен компонент от система, при чиито отказ цялата система спира да работи.

В системите, които правим/ползваме и са повече от един сървър, на който ни е всичко (т.е. един гигантски SPOF) такива неща пак се срещат доста често.

[авиационен модел]

Това е мечтания модел, който даже съществува в реалния свят. Това е напълно подсигурена система, при която имате главен компютър с един софтуер и един хардуер, backup компютри с два различни хардуера и един софтуер, който е различен от главния, и система за следене и кворум. В самолета освен това има и двама пилоти и всякакви резервни варианти.

[авиационен модел 2]

Това е скъпо. Толкова скъпо, че го правят само за случаи, при които умират хора (т.е. дори и в медицинската апаратура не се стига до такива подсигурявания).

Също така системите стават твърде усложнени, като пример – A380, който е наистина подсигурена система, има в себе си 530км кабели. Цената да се изгради и да се поддържа такава система не е по силите на някой друг.

[три неща]

И три неща, за които няма да говоря подробно.

[Софтуерни]

Софтуерните SPOF-ове никой не се опитва да ги заобикаля, или поне не сериозно. Правенето на няколко независими реализации на дадено нещо рядко е оправдано, отнема двойно повече усилия и се дебъгват два пъти подобни проблеми без да може кой-знае колко да се приложат знанията от едното в другото. Поддръжката на две различни системи за същото нещо и комуникацията между тях правят цялото нещо повече от два пъти по-скъпо и сложно.

А проблемите, които се получават от тях са доста по-неприятни, понеже са лавинообразни – ако на няколко места имате същия софтуер, може да очаквате, че ще се чупи по същия начин и в същото време.

[Meatware]

Човешките SPOF-ове са още по-гадна работа. Известни са още като “Bus factor”, т.е. колко човека трябва да ги блъсне автобус, за да спре да работи даден проект (и в много случаи факторът е 1).

В по-големите фирми се правят опити да се реши тоя проблем чрез взимане на повече хора, които да могат да поемат работата един на друг, но синхронизацията м/у хора се оказва още по-сложен проблем и не подлежащ на автоматизация.

Метод за омекотяване е писането на документация, което па всички го мразят.

[цена]

Оценката кога си струва да се вложат средства, за да се избегне SPOF не винаги е тривиална и е за друг вид лекция. Има неща като risk assessment, гадаене по черва на гълъби, хвърляне на зарчета и статистически анализи, които се използват за целта, но много често и хората, които ги предлагат ги объркват…
(който се интересува от проблемите на анализа на риска, може да зачете Насим Талеб)

Като едно лично правило, гледам системите да нямат в себе си нещо, което е наистина трудно за дистрибутиране, или ако го има, да е максимално подсигурено (хубав хардуер, monitoring, резервни части, някакъв вариант да се реагира).

[state]

И нека се хванем с основния проблем във всички тези неща – състоянието, или state, както му викаме.

От машините на Тюринг насам състоянието е нещо основно в това, което правим. Няма система без някакъв state, и съответно една голяма част от решаването на проблемите със SPOF-овете идват от там (иначе просто щяхме да хвърляме хардуер, докато нещата почнат да изглеждат добре).

Искам да го повторя и да покажа, не съществуват stateless системи.

[примерна не-stateless система]

Ето един често срещан пример – смята се, че ако имаме такава схема, то web сървърите ни са stateless, понеже реално са взаимозаменяеми.

От гледна точка на системата те имат два вида state. По-маловажният са заявките, които се обработват в момента (които не се смятат за важни и съответно дори да се загубят, се смята, че може да се повторят. Важният state е един бит, който казва дали този сървър е активен или не, и дали може да обработва заявки.

Съответно цялата система трябва да е сравнително сихронизирана за този един бит, за да може да работи правилно (т.е. ок е сървърът да работи, и системата да не смята така, не е ок да не работи и системата да се опитва да го ползва).

[решения]

Ето няколкото типа решения на проблема.

[do nothing]

Това е стандартния план – повчето хора не очакват, че нещо лошо ще се случи, носят розови очила и не бива да бъдат допускани да мислят системи.

[backup plan]

Може да не е толкова безсмислен като тоя от слайда :)
Тук решението е да знаем какво правим, ако нещо се счупи. За някои по-малко важни системи например backup plan-а може да е “машината е в гаранция, ако се счупи нещо, обаждаме се на тия от които сме я взели и така”, или “обаждаме се на другарче”.

[cold spare]

Това вече влиза в категорията на решения, които уважаващ себе си админ би приложил. В реалния свят това е да имате резервна гума, някъде в шкафа резервни електрически крушки, или при системите – една готова цяла машина, която може да замести останалите, дискове или някакви други резервни части, за офис – втора internet връзка през някое 3g, която може да се ползва временно, ако наоколо са прекопали някой кабел.

Това е и едно от най-често срещаните решения, понеже доста лесно се прави. От друга страна може да предизвика прилично количество donwtime, докато се “стопли” резервата.

(някъде тук на лекцията се оказа, че има хора, които не държат резервни крушки у тях…)

[hot spare]

Това е също доста често срещано – имате готов топъл spare, който във всеки един момент е синхронизиран с това, което прикрива и при нужда автоматично може да поеме работата на изгорелия компонент.

Това много често се изполва в setup-и с бази данни или подобни неща, при които чистото дистрибутиране (за което ще говоря по-нататък) не може да стане заради CAP теоремата.
(ще намразите cap теоремата след малко)

Тук има един специфичен момент, т.нар. fencing – ако втората система поема работата на главната, трябва по някакъв начин да се гарантира, че главната е спряла и не прави нищо, за да не се стигне до омазване на shared state или нещо такова. За целта има няколко типа решения, някои от които просто спират тока на главната :)

[CAP теорема]

И така, преди да си говорим за най-хубавия начин – да имате N на брой машини, те да вършат едновременно работа и хем да се scale-вате, хем да сте защитени от сривове, да кажа защо това е непостижима мечта…

Теоремата е съвсем проста и гласи следното: една дистрибутирана система може да има най-много две от следните три свойства: Консистентна, винаги достъпна, издържаща разделение.

Консистентна значи, че във всеки един момент една заявка към нея ще даде същия отговор, без значение към коя част от нея се обръщаме, т.е. ако питаме базата “колко реда има в таблица X”, всичките и сървъри ще кажат същото нещо.

Винаги достъпна значи, че дори да са отпаднали някакви компоненти, тя все пак ще продължи да ни отговаря.

Издръжливостта на разделение значи, че не може да се достигне т.нар. split brain ситуация – ако системата се раздели на две части, не може двете да мажат в/у данните и да се получи при тях различна версия.

Това например значи, че не може по някакъв елементарен начин да си направите master-master репликация на базата данни.

[дистрибутиране]

И да си поговорим за мечтата, всичко да е дистрибутирано. Винаги ми се е искало да мога просто да добавям нов хардуер и нещата да работят и на него. Дори за някои неща това сме го постигали …

Това е постижимо, с някои ограничения. Понеже не ми хрумна по-добър начин, ще ви дам няколко примерни системи, които почти успяват да решат проблема :)

[load ballancers + web]

Това е един доста класически случай за повечето сайтове, на които не им се иска да имат downtime. Слагате отпред два load ballancer-а, които знаят кой от web сървърите отзад работи и балансират м/у тях заявките. Това работи много добре, сравнително стандартизирано е и сглабянето му не отнема особено много време. Достатъчно стандартно е, че amazon да предлагат компонентите му като някакъв service.

При отпадане на компоненти системата го усеща и спира да му подава трафик.

RAID масивите са доста близки като идея до това.

[синхронни бази]

По принцип повечето ACID бази данни използват сихнронна репликация, т.е. всяка заявка за писане се счита за завършена (т.е. се казва на клиента) когато всички компоненти от системата са я потвърдили. Това е почти същото като предния вариант.

[hack-ът за eventual consistency]

И има една добавка, като удобен hack при системи, при които има случаи, в които може да се прочетат стари данни, т.нар. eventual consistency.

В общи линии това представлява система, за която операциите за писане са приключили при запис в X компонента, като обикновено X=N/2 + 1. Тогава имаме inconstent четене, което може да чете от 1 компонент, и ако ни трябва консистентно, четем от N-X+1 компонента. Това се използва основно за системи, при които консистетният read е рядка операция.

[sharding + replication]

Това е текущият метод за репликиране на база данни. В общи линии умножавате факторите за на колко искате да разделите данните (за performance) и за redundancy и получавате колко железа ви трябват (в случая са 2X2).

Това обаче върши работа основно за прости заявки. В момента, в който трябва да съберете данни от две машини, за да направите join или нещо такова, нещата започват да се объркват.

2014-03-25 обява за работа

Tuesday, March 25th, 2014

(това може да го приемате и малко като спам)

Тия дни писахме една сравнително хубава обява за работа и я пуснахме в jobs.bg и stackoverflow. До тук няма кандидати, та въпросите ми са:

1) толкова ли е зле обявата?
2) хора ли няма, дето да отговарят?
3) На грешното място ли я пускаме?

Ако 2) е вярно, явно ще трябва да почна да правя деца и да ги уча…

2014-02-27 DKIM

Thursday, February 27th, 2014

Това чак не е интересно.

Ровейки един spam, който един приятел е получил, се загледах в DKIM подписите. Оказва се, че DKIM-а се лови от тривиално replay-ване, т.е.:

Правите си account на някое уважавано място (например gmail, в конкретния случай обаче е abv.bg). Пращате си mail до себе си, който ви генерира едни валидни подписи. Взимате цялото съобщение като source, един ваш smtp сървър, и го пращате на който си искате. От гледна точка на хората, уважавания доставчик е минал през вашия сървър и е пратил съвсем валидно писмо…

DKIM-а не знам кой го е мислил, но ето header-ите му:

DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=abv.bg; s=smtp-out;
	t=1393422571; bh=4dLtPPWnymIO/8L0CLbvGZYxlQ5bZYMBimz0R/Li/JY=;
	h=Date:From:To:Message-ID:Subject:MIME-Version:Content-Type:DKIM;
	b=RQhl7IakYWwDQb70tpH3nG6V7CFcisAs/AyIO9/g0OpaIFD0jJpm8KbGOZ+UvVpK5
	oeSzu2HLUUFOd6/o+8NHJWHTEwPKf80RZXtnkN4Jp2S/OKKBC5TImFupHy+s1uUgjhD
	9yDf3LZES95JquPBNdYbotBZhc6wd9x1dNTJKCM=

Превод в ефир: Ето мой подпис на ето тези полета, които съм си харесал, които са тривиални за фалшификация.

Това е толкова тривиално, че чак българските spamer-и го ползват. Чак се чудя дали това с валидния DKIM подпис е нарочно или просто така е станало…

Интересна работа. Имаме SPF (описване на валидни източници) и DKIM (подписване на header-и от валидните източници), и нямаме свястна комбинация от двата протокола, която ДА ВЪРШИ НЯКАКВА РАБОТА.
(и разбира се, ако сте с валиден DKIM подпис, gmail и разни други мърлячи ще показват в получения ви mail картинки от външни линкове. Ето как тривиално спамерите ще видят дали ви е верен/работещ/четен mail-а)

2014-02-13 bounce processing

Thursday, February 13th, 2014

Понеже няколко пъти се е случвало да решавам тоя проблем или да го разказвам на някой, реших да го напиша.

Проблемът е следният: как да разберем, че не можем да пращаме mail до определено място, като ни дойде bounce от там? Да се parse-ва самото писмо е загубена кауза, понеже няма никакъв ясен формат.

Идеята е сравнително проста: във всеки mail има Return-Path: header, който винаги е първи, и към който се bounce-ва mail-а. Ако всяко съобщение има уникален такъв, може да се познае за кой получател (и може би и за кое съобщение) става въпрос. Самият bounce може да се познае по празният return-path (така че ако някой заблуден spam реши да дойде, да не създаде проблем).
(като всички такива хитрини, и тази е открита от Дан Бернщайн и даже си има нещо като стадарт – Verp)

Има различни начини да се направи, последният вариант, който написахме правеше return-path-а да е във следния формат:
UID_TIMESTAMP_SIGN@bounce.domain.com
където uid беше id-то на потребителя от базата, timestamp си е unix-ки timestamp и sign е sha1 на uid_timestamp_secret, като secret само ние си го знаем и така можем да проверим дали наистина ние сме го генерирали това. За да се избегне един race condition, в който потребителя си е сменил email-а преди ние да получим bounce, може в sign да се включи и оригиналния email адрес, така че bounce просто да не match-не сигнатурата си.
(гледайки сега по стандарта, заради graylist-а може да е добра идея да сменя първото _ с +)

От там нататък просто ви трябва нещо просто, което да засилва цялата поща за @bounce.domain.com към един скрипт, който да прави тривиален анализ на header-ите и да казва “да, тоя mail не е верен”.

2014-01-25 thedaywefightback hackaton

Saturday, January 25th, 2014

Днешния ден може да го броим за полезен.

Изнесохме с Митьо и Петко сайтовете на турнето при мен, подкарахме един setup за ruby приложения (продадох се и аз на хипстърската страна на силата), та там нещата са ок. Остава да припалим (почти за идеята) dnssec на it-tour.bg, ама трябва да видя как може да стане номера (register.bg го предлагат, ама domain-а са го регистрирали през superhosting).

На ludost.net вече има wildcard сертификат за всичко, който се приема (и vasil.ludost.net вече пренасочва само към https). Има валидни сертификати на jabber-а, irc-то, пощенските неща и квото-там-намерих. Тия дни ще си направя и TLSA записи.

Подкарахме https и за initlab.org и cassie.initlab.org, но понеже там Петко взе безплатните сертификати от startssl, трябва да почакаме един ден, докато се update-не OCSP-то.

Около това си преписах скрипта, който генерира config-а на apache на marla (за всички сайтове да има https и v6 vhost-ове). Следва да разцепя още малко конфигурациите, за да могат да разделя .ludost.net нещата от другите и да форсирам https за *.ludost.net. Някъде по пътя – tlsa :)

С това може да борим hackaton-а за thedaywefightback.org за приключен.

2014-01-14 server names

Tuesday, January 14th, 2014

За всички, които имат нужда от имена на сървъри (и да си пазя аз какви съм давал), направих списък на даваните, дадените и бъдещи имена за сървъри, може да е полезен и на още някой.

2013-01-05 tls deployment

Sunday, January 5th, 2014

Около всякаквите неща на конгреса и това, съм си формулирал следния план за действие:

В рамките на следващите 3 месеца:
Ще подкарам dnssec за domain-ите си (вече има за ludost.net, остава да се разбера с registrar-а ми да ми сложат DS записите);
Ще сложа SSHFP и TLSA записи за каквото трябва в dns-а (което ще иска да накарам някои хора да си upgrade-нат bind-овете);
Ще се погрижа за сертификати за всичките domain-и при мен (има за ludost, може би няма да са от cacert);
Ще форсирам tls на входа на jabber сървъра (тва е въпрос на един рестарт);
Ще подкарам tls на каквито ftp неща има при мен;

След това, поетапно:
Ще спра не-tls irc-то, на нормалния порт ще има съобщение “закачете се по ssl на 6697”;
Ще направя http-то да връща само redirect към https, по същия начин за ftp-то;
Ще отрежа на jabber-а не-tls комуникацията с други сървъри;
Ще махна не-криптираните варианти на pop3, imap и smtp submission;

Още не знам какво ще правя със самото междусървърно smtp и още една-две услуги, които търкалям.

2013-10-17 pCloud

Thursday, October 17th, 2013

И малко по работа (почти “минутка за реклама”).

Пуснахме си новия проект – pCloud – преди няколко седмици. Представлява storage на данни, с хубаво API и клиенти.

Около него пускаме и кода на част от клиентите – тези за desktop операционните системи, като той се състои от две части – нещо, което може да mount-не файлова система, и нещо, което графично да си говори с него. Кодът може да се намери в github, в момента е в сравнително beta състояние (т.е. вече файловата система не успяваме да я накараме да гръмне лошо). Целия код там е под BSD лиценз.

2013-03-24 traffic analysis tool

Monday, March 25th, 2013

(докъде стигнах, да качвам код в github)

https://github.com/krokodilerian/trafstat.git

Система за събиране и анализ на трафик, базирано на tcp retransmit-и и bgp routing таблици.

Аз я използвам на няколко места да си анализирам трафика и да го балансирам откъде да минава. Имаме пусната една версия на ts.hahpss.com, на която може да гледате от един български сайт как изглежда трафика към вас.

Системата за мен е много по-хубава от различните варианти с ping от време на време (smokeping, mtr и т.н.), понеже е върху целия трафик на web сървъра, който реално потребителите виждат, а не нещо, което може да има различно поведение и различни shaper-и.

Кодът е леко допипнат, за да става за публична употреба, но има още доста да се желае (например трябва да сложа един __packed__ атрибут на една структура, дето пращам по мрежата). В момента може да се каже, че е в works-for-me версия, но мисля, че повечето админи биха се справили да го подкарат при себе си. Изисква да може да си пипнете web сървъра и да може да вземете отнякъде read-only BGP feed.

Състои се от няколко компонента:

– модул за nginx, който за всеки request взима колко трафик е направен, колко е било mss-то на връзката (за да може да се изчисли броя сегменти) и броя tcp retransmit-и, и го праща до един централен сървър по UDP. Мариян е навит да напише същия модул за apache.

– сървър, който получава udp пакетите и ги пише във файл (реално може да прави директно заявки в базата и може да го оправя в бъдеще).

– cron script, който попълва в базата данни за всички router-и, за които знае системата routing таблиците им (prefix-и и aspath-ове).

– друг cron script, който на колкото-време-му-кажете хваща лога на демона, сдъвква го и вади заявки, с които да запише трафика по префикси и типове.

– още един скрипт, който веднъж на час почиства нулевите редове и архивира данните в една таблица, за да може да се анализират (т.е. дава ви почасови данни).

Има и някакви визуализиращи неща, които ще се появят по-късно.

Не съм решил какъв да е лиценза, защото и вътре има няколко неща, които не са мои (bgpdump от ripe), приемам идеи.

2013-02-28 колко трафик прави един tcp connection?

Thursday, February 28th, 2013

И още един интересен работен проблем.

Имаме следната стандартна задача – да log-нем колко трафик е направил даден HTTP request. Тривиалният начин:

while ( (len=write(...))>0  ) total+=len;

т.е. колкото сме подали на kernel-а, толкова.

Това води до проблем, когато срещу нас стои някой от т.нар. download manager-и. Те дават възможност даден файл да бъде точен с няколко паралелни връзки. Това се реализира с Range header-а в HTTP, и ако например искаме да свалим даден файл от 1MB с две паралелни връзки, едната трябва да подаде range от 0 до 524287, втората – от 524288 до 1048576.
Разбира се, авторите на тоя тип софтуер са идиоти, и вместо това подават request-и от 0 до края и от 524288 до края на файла, като просто прекъсват първата връзка, след като са получили каквото им трябва. Това обаче остава връзката с пълен буфер от данни (в ядрото), който в моя случай се мотае м/у 1MB и 2MB, което от своя страна в повечето случаи брои по 2MB отгоре на всеки такъв request.

Решението на този проблем е едно ioctl:

while ( (len=write(fd, ...))>0  ) total+=len;
ioctl(fd, SIOCOUTQ, &bytesunsent);
total-=bytesunsent;

… което е прекрасно, докато човек не тества с нормална връзка при по-голяма латентност и не открие, че в разни web сървъри всъщност като напишете последните данни и стигнете до логването (т.е. викнете ioctl()-то), буферът е все още пълен и ще log-нете по-малко трафик, отколкото е направен.
На теория можем да хванем момента, в който буферът е празен със SO_LINGER опцията – тогава close() ще block-не, но това не ни решава проблема, понеже пък след това file descriptor-а няма да го има. Има друго решение – с shutdown(), read докато получим 0, и тогава да видим тия данни, което обаче е криво за писане и вероятно има някакъв проблем.
В крайна сметка моето решение е “проверявай буфера само на връзки, които не са завършили нормално”, и това дава горе-долу верни стойности. Някой да му идва по-добра идея?

2013-02-27 inet_ntop

Wednesday, February 27th, 2013

Пишех малко код (опасна работа), съответно стигнах до момента, в който трябваше да изкарам някакъв адрес (ipv4 или ipv6) в четим вид. Тръгнах да ровя и открих, че има inet_ntop(), което поддържа и двете. Без да чета внимателно, написах следното:

struct sockaddr *saddr;

inet_ntop(saddr->sa_family, saddr, msg.ip, 255);

Това за всеки, който е погледнал по-внимателно man-а е ясно, че не работи – трябва да подам не sockaddr, а структурата вътре, я in_addr, я in6_addr – което е криво, понеже трябва да напиша няколко if-а и т.н.. Питах google, не намерих нищо особено полезно, след което отворих Unix Network Programming на Stevens около тая функция и какво открих – човекът е описал тоя проблем, и даже е написал sock_ntop(), който работи директно със sockaddr структурата (и реализира ония няколко if-а).
Ето примерен код как се реализира.

Въпросът е, защо в libc я няма тая функция? Мрън, книгата е вече на 16 години, все някой можеше да се сети и да вкара нещо такова.
(ако някой все пак се сеща за нещо такова в libc, да каже)

2013-02-07 crash в intel-ски мрежови карти

Thursday, February 7th, 2013

Тоя проблем бие по малоумност голяма част от нещата, които съм виждал в последната година.

Kristofer Kielhofner е намерил гаден проблем в Intel 82574L мрежовите карти, който с пакет, в който на специфична позиция пише 0x32 просто crash-ва картата (бъгове в power management-а вероятно), в internet storm center-а има по-съкратена информация.

(това е мрежовата карта по доста от сървърните дъна от последните години)

Решението, което аз виждам (и което вече пуснах) изглежда така:

for i in `cat list-of-ips`; do  do ping -i .001 -c 128 -p 34 -s 1110  $i ; done

(броя пакети съм си го харесал да е толкова, може и да няма нужда от толкова много)
(съответно, смяната на 34 с 32 го прави tool за трепане на машини)

Проблемът не се задейства винаги, вероятно има и разлики при различни firmware-и на разните мрежови карти (ще ми е интересно някой дали е успял да го reproduce-не и в какви условия), но вероятно е добра идея човек да е подготвен.

Update: до тук аз поне не съм успял да го reproduce-на (както и при някои други хора), та може да е сравнително изолиран проблем.
Update 2: Press release от intel по въпроса.

2012-01-18 как пиша

Friday, January 18th, 2013

Появи се въпросът какъв ми е процесът на писане (Стефан ме пита, и той ще пише по темата). Донякъде като продължение на post-а ми работния ми процес.

По принцип широко разпространено е грешното мнение, че ползвам някакъв сръбски bullshit генератор, който ми пише post-овете. Това не е вярно. Македонски е.
(open up with a joke, they said)

По принцип пиша няколко типа неща – blog post-ове, документация (понякога се чувствам като единствения такъв човек на тоя свят), лекции/презентации и описания на системи, които са донякъде като документация.

Първо, аз съм мързелив, съответно много рядко сядам да се мъча в/у нещо. Работя на тласъци (хаха), редовно се прекъсвам с четене на поща, писане на някого, четене на 9gag, къпане и т.н.. Голяма част от идеите и мислите ми идват, когато не съм си пред машината или като правя нещо коренно различно – съответно просто идва момент, в който сядам, написвам всичко което ми е хрумнало и ако е достатъчно, минава редакция и го качвам, ако не, се захващам с други глупости. Повечето ми blog post-ове са написани на един път, защото съм издъвкал цялата идея в главата си предварително.
(например това го захващам за трети път)
(най-много неща ми се изясняват сутрин, докато се къпя)

За да не забравя в/у какво работя, просто си държа отворени прозорците с текстовете. Ако реша, че за нещо няма да имам време, го записвам и затварям и ако ми хрумне след някакво време, го отварям пак. Например идеята ми за debug workshop-а се мотае в няколко файла от поне година и половина и искрено се надявам да успея да я реализирам скоро.

Ако работя в/у нещо по-голямо, си правя план преди това (който рядко си прилича с крайния резултат), служи повече като място, на което да си водя бележки за какво трябва да говоря. Пиша го по максимално прост начин, като под-точките се отбелязват с 8-интервални tab-ове, като в C код – така ако твърде много се забия в нещо, лесно мога да го видя и да го премисля или изнеса в отделна точка/абзац.
Планът ми помага най-вече защото паметта ми е основно асоциативна и трудно мога да си спомня всички неща, свързани с дадена тема без някакво подсказване – например ми е трудно да изброя книгите, които съм чел през годината, но ако ми кажете автор/заглавие, мога да кажа за какво става въпрос в тях.

За някои от лекциите си пиша текст, понеже ми е по-лесно да си ги представя в този вид, за други правя презентация, за трети само план, а понякога като нямам време или съвсем ме мързи, импровизирам. Съответно първите се получават най-добре, последните по принцип най-зле.

При писането и редактирането на текст се старая да следвам правилата на Оруел за писането, от Politics and the English language (някои хора твърдят, че ползвам твърде много passive voice, но според мен там, където го ползвам си е правилно).

По принцип обсъждам бележките си с различни хора, най-вече за да не напиша някоя голяма глупост (помага това, че познавам няколко много цинични човека, които никак не се притесняват да ми обяснят колко съм тъп) и за да имам някакъв frame of reference за публиката. За по-сериозните неща правя поне една редакция, за да оправя текста (основно да махна неща, от които няма нужда), за някои давам текста да го прегледа някой друг. Повечето ми лекции са минавали такава редакция, повечето ми blog post-ове – не.

От известно време използвам git, за да си държа в него лекциите и нещата към тях (даже от време на време давам на някой достъп, така с Яна правихме бележките за лекцията за депресията), но още не съм го използвал за нещо повече от backup и sharing система. Използвам gvim с голям шрифт за писане на текстовете, vim в терминал за писане на бележките, както и вградения spell checker. Имам spell checker и в browser-а и понякога си хващам грешките като paste-вам там.

Като обобщение – аз съм мързелив, разхвърлян и несистемен, направо е чудо, че успявам да свърша нещо.

2012-11-05 “Защо поддържането на 700 сървъра е по-лесно от това на 3”, текст на лекцията

Monday, November 5th, 2012

Ето текста на презентацията ми от Openfest 2012 за това как 700 сървъра се поддържат по-лесно от 3. Оставил съм бележка на кой слайд съм, понеже има няколко полезни картинки из презентацията (pdf, odp).

Update: видео запис.

[слайд 2]
Занимавам се със сървъри в общи линии от малък и винаги ми е било интересно. След като в последните 3 години се занимавах с една голяма система (около 750 машини, 7.5PB място, 260gbps трафик в разни моменти) открих как големите системи са по-лесни за поддръжка, понеже ни карат да правим нещата по правилния начин (иначе просто няма да се справим).
Също така искам да отбележа, че аз съм адски мързелив и не много умен (за последното даже имам издаден документ от МЕНСА) и намирам това за лесно, т.е. според мен всеки, който реши може да се справи:)

[слайд 3]
Това е снимка от едно от първите неща, с които съм се занимавал (за съжаление нямам снимка на първия си сървър, как стоеше до един шкаф с 6-7 модема и това си беше цялата система). Да сравним с

[слайд 4]
тези две снимки, на които отляво можем да видим извънгаранционни гръмнали дискове (около 400бр.), и в дясно пак извънгаранционни гръмнали сървъри (няма как да се направи снимка на работещите машини, която да е достатъчно интересна).

[слайд 5]

Малко бележки, преди да започна – аз различавам три типа “операции”.

Първият тип е малката фирма. Там има един-два-три сървъра, системният администратор поддържа всичко, от климатиците до базите данни и web сървърите, не му дават много време да спи, няма особено голям бюджет и като цяло всичко се прави по неприятен и неефективен начин.

Вторият вид са големите, “enterprise” операции – като пример мога да дам телекомите (които за мен са много повече неприятен начин на мислене, отколкото нещо друго) – това са компании, които разработват и изобщо разбират частично технологията си и основно плащат на външни фирми много пари, които после да могат да поемат вината за проблемите, и да реагират в някакво време (например 2-4 часа) за да оправят счупеното.

Третият вид са тези, за които ще говоря, и които по принцип наричам “порно компании”, поради това, че повечето от по-големите фирми, които се занимават да сервират и т.н. порно по интернет са такива (но и twitter, reddit, github също си приличат с тях). Това са операции, които сами поддържат почти цялата си инфраструктура и продукти, които използват почти ексклузивно open-source софтуер, дописват го за собствени цели и успяват с бюджет, който е с един-два пъти по-малък порядък от enterprise хората да постигнат толкова или повече.

(има четвърти тип, който пропуснах на лекцията, гигантите като facebook и google, от които идват някои от идеите по-долу).

И понеже има шанс да се появи въпросът “тия неща какво значение имат, като всичко ни е в облака”, малък отговор: облакът ни дава нещо, което е много подобно на моите железа, просто няма нужда да си поддържате сами хардуера. Поддръжката на хардуера поне при мен за 700 машини отнема средно по около час-два на седмица. Останалото си важи с пълна сила.

[слайд 6]

Големите системи ни принуждават да научим някои неща, без които никога няма да можем да се справим с натоварването. Разширяването на системите е много по-лесно от разширяването на персонала и доста по-ясно като задача, та ако не се работи правилно, много често админите на някаква система издъхват, преди да е стигнала някакви сериозни размери. Изброил съм доста от полезните уроци, които са ми улеснили много работата – повечето ги има в хубавите книги.
Изобщо, ако ви е интересна темата, идете и прочетете “The practice of system and network administration”. Ще откриете много интересни работи…

[слайд 7]

Да започнем с мониторинга. Лафът “има два типа хора, такива на които им е гърмял хард диск и такива, на които ще им гръмне” ми е толкова любим, че чак го написах в презентацията …
Поддръжката на система без monitoring е подобна на шофирането сляп и глух. Няма да имате идея какво правите, какво се случва и какво го предизвиква и в общи линии ще трябва да гадаете.
Имам една примерна случка от съвсем наскоро – един приятел има лична машина, co-locate-ната някъде, на която има два RAID1 масива с по два диска. Преди около година един диск от единия масив отказал, след това преди 3-4 месеца отказал още един диск, но от другия масив. По някое време един негов приятел минавал през colocation-а и после му казал “абе ти знаеш ли, че на твоята машина отпред светят две червени лампички?” (някъде тук моя приятел твърдеше, че colocation support-а е трябвало да му каже, че има такова нещо, но те няма откъде да знаят това дали е нормално или не, няма стандарт за нотификация от предните панели). Та, тръгнал той да сменя дисковете, но докато се накани му гръмнал още един диск, а докато backup-вал – и последния.
Както би казал Captain Hindsight в такъв случай – “трябвало е да има monitoring и това нямаше да се случи”.

Monitoring-а ви пази от downtime – ще видите гръмналия диск преди да стане бедствие, пълнещата се файлова система преди базата ви данни да спре да може да изпълнява заявки или mail server-а ви да може да приема поща, ще ви каже, че някой service ви е спрял и какво ли не още.
Също така monitoring-ът ще ви даде данни за бъдещо планиране – колко трафик правите, с каква скорост си запълвате ресурсите, в кои периоди може да очаквате повече или по-малко натоварване, и т.н., и т.н..

Аз лично ползвам nagios за всичките си машини, включително и за някои неща по работната ми станция вкъщи.

[слайд 8]

Тук съм показал как изглежда моя системен статус – това е nagios checker, plugin за firefox, който показва постоянно статуса на един или няколко nagios-а (това е редчето най-най-долу) и при on-mouse-over показва по-подробен статус (всичко останало, което се вижда в жълто/червено). На този се вижда как два от ftp сървърите са малко по-натоварени, има 4 дискови масива, които се rebuild-ват, два масива дето са изхвърлили по един диск, един масив, който си мисли по въпроса и един IPMI модул, който изглежда е изгорял.
Има варианти на plugin-а и директно за gnome или каквато работна среда ползвате, всеки както му е удобно. Много хора ползват външен монитор или нещо такова да им стои там целия статус.

[слайд 9]

Може да видите няколко публични примерни monitoring-а – моят публичен nagios, един munin пак за същите машини (страхотен tool, лесен за конфигуриране, прави много добри графики и писането на plugin-и е направо радост за душата), и един пример за великолепно подкаран nagios с много услуги. Моят например има по 7-8 услуги за машина, които се следят, те имат по 20-30 и все подходящо измислени, препоръчвам на всеки да погледне какво и как следят.

[слайд 10]

Това е нещо старо като света, даже го намерих в една книга за писане на бази данни от 1992ра. Идеята е, че за една система не трябва да се налага да се променят няколко различни места, когато се прави промяна по нея – не трябва да се пипнат конфигурациите на 8-9 различни неща и да се направят други 10 действия, понеже хората грешат, ние сме хора и ще сбъркаме нещо. Или ще пропуснем определено действие, или ще объркаме нещо, докато го правим, а ако направим скрипт, който от една централна конфигурация да създаде всичките тия конфигурации и направи действията, първо ще си спестим работа, второ ще си спестим грешки. Скриптовете определено грешат по-рядко от хората…
Този съвет за съжаление рядко е използваем в малки системи.

[слайд 11]

Тук съм дал един мой примерен скрипт, който генерира конфигурация на dhcp сървър. Скриптът е грозен до смърт и съдържа в себе си три езика – bash script, SQL и dhcp config – но съвсем накратко прави следното: генерира един конфигурационен файл, тества дали е различен от текущия, ако да – пробва да рестартира с него, и ако не сработи, ми праща mail и връща старата конфигурация. Елементарно е да се напише, работи като слънце и не ме кара да правя много неща – този скрипт и още няколко се изпълняват от cron-а и всичко се update-ва без никаква човешка намеса.

[слайд 12]

На този слайд съм показал как изглежда при мен базата, в която описвам какво имам. Определено има какво да се желае и част от нещата не са пряко свързани с конфигурирането на машините, но и тази проста схема е съвсем достатъчна, за да мога да си поддържам нещата в ред.
(например ми се иска някой ден да направя пълна инвентаризационна система в това и да мога да следя кой компонент с кой сериен номер ми пробутват обратно, след като съм го върнал за ремонт)

[слайд 13]

Автоматичните инсталации са нещо почти животоспасяващо, а и аз при мен съм решил въпроса по толкова готин начин, че не мога да не се похваля :)

По принцип началната инсталация е мястото с най-много грешки. Във всеки един инсталатор има м/у 20 и 100 избора, които трябва да се направят, особено ако става въпрос за сървър и потенциалът за грешка или просто различна инсталация е огромен. Вероятно няма начин един човек да направи 10 инсталации през debian-ския инсталатор за една седмица и да направи 10те машини еднакви (има шанс и 10те да са съвсем различни). Да си оставяте такава дейност е като да си пречите сами.
(за съжаление и това е безсмислено за по-малки системи, ако имате един сървър, няма от кой да е различен)

Това доста хора го научават бързо, и на местата, където машините се дават preinstalled (като например всичките инстанции по cloud-овете) хората си имат един малък скрипт, който качват на машината и който я довежда до желаното до тях състояние.

При мен инсталацията представлява следното: първо ми монтират машините в rack-овете и ги настройват да boot-нат по мрежа. Машините тръгват, зареждат през pxe/nfs един image, в който тръгва нормална операционна система, на която последният и boot script (/etc/conf.d/local.start, понеже е gentoo) стартира един мой скрипт, който от своя страна се свързва с една централна машина и казва “здрасти, аз съм с mac адрес еди-кой-си”. Централната система проверява този mac адрес на кой switch/port се намира, проверява в таблицата със сървърите (вижте на слайд 12) какво трябва да има там, дали е работещо или не и или казва “не прави нищо, не знам за тая машина/вече е инсталирана”, или дава нужните настройки като hostname, ip, net, gw. Ако има получени настройки, скриптът създава partition-и, прави файлови системи, настройва разни полезни неща като адреси на ipmi контролера и парола за него, разархивира един готов image, сменя по файловата система настройките като за машината, рапортува на централната система, че е готов и рестартира. Централната система си отбелязва, че машината е готова и че трябва да и даде да boot-не нещо друго на следващия път.
След което аз на сутринта си пускам лаптопа и виждам – а, имам още 18 инсталирани машини, хайде да им качвам съдържание (което също се прави с една-две команди). Мисля си, че единственият по-мързелив начин щеше да е да ми ги пращат готови инсталирани.

[слайд 14]
Тук малко ще се отклоня и ще се опитам да обясня колко важна е автоматизацията. Системните администратори сме мързеливи и ТРЯБВА да бъдем – хората, които не ги мързи ще си кажат “защо да автоматизирам това просто нещо, ще ми се налага да го правя само веднъж седмично/веднъж на ден” и в един момент се натрупват достатъчно такива дреболии, че не им остава време да се огледат и се получава “death by a thousand cuts”. Мързелът е важен, и може да видите на

[слайд 16]
програмист, който тренира за системен администратор.

[обратно на слайд 14]

Всичко, което се прави често, трябва да се автоматизира. Всичко, което се повтаря и се прави рядко – също, защото има шанс между две правения да забравим как става. Научете се да пишете код и пишете, това ще ви спаси живота. Няма нужда даже да е добре, ето един мой пример:

[слайд 15]

Това е един много прост скрипт, който проверява кои машини са report-нали, че имат проблеми с дисковите масиви, логва се да види какво се случва и ми вади списък в следния вид:

rack/cage (SD id)               server  port    serial
XXX/DA3:20460 (CUST.YYY)        s333    p9      JPW9H0HQ2XS8AH
XXX/DA3:20460 (CUST.YYY)        s452    p5      JPW9J0HD1J3JMC
XXX/DA3:20460 (CUST.YYY)        s542    p3      JPW9N0HZ0MN8JL

Това аз мога да го пратя на човека през океана, който да иде на място и да ги смени. Не съм направил скрипта и да праща поща, понеже има няколко случая, в които и аз трябва да погледна, преди да съм сигурен, че дисковете може да се извадят спокойно.
(някой ме беше попитал защо там има ssh root и т.н. – първо аз ползвам ssh agent и няма как някой, който се добере до машината да добие лесно достъп до всичките, и второ аз работя само от root – аз admin-ствам тези машини и почти няма команда, която да може да работи от нормален потребител, а да пиша sudo на всеки ред е безсмислено).

[слайд 17]

И една леко религиозна тема – трябва ви хубав naming convention. Това е от нещата, за които просто няма друг начин при големи системи. По принцип важното е имената да са лесни за произнасяне и запомняне (доста хора използват филми/сериали като източник (Simpsons), други използват фентъзи книги (в Толкин има около 200-300 героя, в Малазанска книга на мъртвите – около 1000)). Аз лично за тази система използвам съвсем простата конвенция от една буква, определяща функцията на машината (w – web server, d – db server, s – storage) и номер. Така знам машината какво прави само по името и е съвсем лесно да я кажа на човека отсреща, който се намира в шумния datacenter и около него вият 10-15000 вентилатора.
(от друга страна, личните ми машини имат съвсем random имена, щото са малко и защото успявам да ги запомня – marla, tyler, cassie, lain, alpha…)

[слайд 18]

Резервните пътища са нещо също много важно. Почти всеки, който някога е администрирал каквото и да е отдалечено си е отрязвал клона, на който седи (в слайда има прекрасен пример с ifconfig eth0 down).

Искам да дам три примера от при мен за резервни пътища. Първият е как всеки сървър при мен има IPMI модул, който има отделен мрежов порт, закачен за отделен switch, така че да мога да стигна до машината и да видя какво се случва с нея, ако се налага, както и да мога да я командвам. Това дава възможност да разбера например, че дадена машина е прегряла и се е изключила, вместо да се чудя дали не е проблем в мрежовия и порт.

Второто и най-явното нещо са резервни мрежови връзки, които в общи линии правят “цикъл” в мрежата и не се използват активно, но през тях може да се мине и да се стигне до сървъри, които иначе са недостъпни поради проблем в хардуера, или поради строшена (от мен) конфигурация. Някъде тук искам да кажа, че това е един от уроците, заради които казвам, че системните администратори се учат на гърба на потребителите – това човек не го схваща, докато не му се случи поне няколко пъти.

Третият пример е малко по-странен, но пак подобен – всичките ми машини по принцип boot-ват по мрежа (което улеснява много някои неща), но освен това могат да boot-нат нормалното за тях нещо от диска си, ако мрежата не им отговори на време. Така дори да има проблем със сървъра, от който тръгват или с някой switch по пътя, те пак ще запалят и ще могат да работят. Така най-малкото избягвам старта на цялата система да зависи твърде много от нещо централно.

[слайд 19]

Може би понеже аз съм тръгнал от интернет доставчик ми е странна идеята някой друг да ми оперира мрежата, но това се оказва стандарта в момента – хората си наемат/слагат машини в някой datacenter, от datacenter-а им дават internet и мрежа през един порт на всяка машина и така цялата комуникация между компонентите на една система става 1) през порта, който е и за външния трафик и се бори с него и 2) през мрежа на някой друг, с различни цели и съответно такава, на която не може да се вярва. Мрежата е централен компонент на всяка една система в наши дни и невъзможността да знаете какво се случва в нея и невъзможността да го променяте/контролирате ви ограничава сериозно.
(например моята автоматична инсталация нямаше да има начин да става толкова лесно, ако не си контролирах мрежата)

Една фирма, с която работих преди известно време имаше огромен проблем с това, че не си контролираше мрежата – те са по-големи от това, с което се занимавам (имат около 1800 машини в 4-5 големи datacenter-а) и съответно понеже им се налагаше да репликират mysql през internet, бяха правили някакви страшни и почти гениални изпълнение, за да им работят нещата, а докато бях при тях, основните проблеми идваха от мрежата.

Също така собствената мрежа ви дава възможност да пуснете BGP, да си вземете ASN и за всякакви такива други хубави трибуквени съкращения :) Така може да купувате свързаност от няколко различни доставчика и да не трябва да им търпите проблемите.
Ще говоря накрая и за една много хубава моя система за наблюдение на трафика, която пак щеше да е невъзможна без моя мрежа.

[слайд 20]

Ако някой ден се навия да направя по-голям курс по системна администрация (или цяла магистратура), изпитът на края ще се проведе по следния начин: ще хвана студентите, ще идем да пием някъде, ще ги пратя да спят и след това ще ги събудя в 4-5 сутринта да решат проблем. Оценката им ще бъде на база на това колко часа downtime са имали.

Нещата трябва да се правят просто, защото проблемите винаги ще изникват в най-лошите възможни моменти и трябва да може да се справите без значение в какво състояние се намирате. Това значи и да може да пазите цялата система в главата си, целият и state, което значи и нещата да са максимално унифицирани (защото колкото по-малко неща трябва да помните, толкова по-лесно ще ги запомните).

Препоръчвам на всички да тестват следното – да се напият, да си си легнат към 12 и да са си навили алармата за 4 сутринта, след което да станат и да се опитат да направят нещо просто (например да решат квадратно уравнение или някой прост тест за интелигентност). Вероятно ще има отрезвяващ ефект :)

Нека да цитирам Jim Gray, “Although there are no textbooks on simplicity, simple systems work and complex don’t.”. Това всички го виждат, но никой не иска да го приеме, понеже изглежда простите системи не са готини, и човек не изглежда умен, ако не направи нещо гигантско и сложно (което после се оказва невъзможно за поддръжка). Както при програмирането дебъгването е три пъти по-сложно от писането, така при правенето на системи работата с тях и оправянето на проблеми е доста по-сложно от измислянето и поне според мен хората, които правят много сложни и “умни” системи не са особено умни.

[слайд 21]

Искам да спомена и малко проблеми, които можем да срещнем в големите системи.

Първият е разпределението на натоварванията и събитията. Нека да дам за пример пасивния ми monitoring – той представлява cron скрипт, който веднъж на 5 минути се стартира и праща малко данни към един централен демон, който обработва информацията. Това при достатъчно сървъри би довело до претоварване на централната система и решението е съвсем просто – един sleep за random секунди (м/у 1 и 60), така че събитията да са пръснати във времето.

Другият е премахването на SPOF (single points of failure). Много често като наследство от времената, в които дадена система е била малка се намират разни компоненти, които ако откажат и цялата система спира да работи. В голяма система това трябва да се избягва и като цяло компонентите да могат да се заместват един-друг или да не са толкова важни, понеже колкото повече отделни части имате, толкова по-голям е шанса някоя от тях да откаже. Ако всяка част ви е жизненоважна, то ще трябва през цялото време да тичате след всеки дребен проблем и да нямате време да свършите нещо реално полезно.
Да се направи нещо дистрибутирано е сложна задача – стъпката от една до две машини (или даже от single thread до няколко thread-а) е тежка и по-сложна от тази от две до хиляда, но определено си струва. Ще ви спести будения посред нощите от големи проблеми и ще ви даде допълнително спокойствие.
(например аз почти нямам компоненти, които могат да убият цялата система със срива си, съответно мога да спя спокойно и каквото и да стане, да мога да го оправя на сутринта, като стана)

[слайд 21]

Ето един пример защо е важно да сме дублирани и да не зависим от отделни дребни неща – понеже редките явления в достатъчно голяма система стават нещо нормално. Този screenshot показва как на машина с 12 диска и 12те са гръмнали в един и същи момент.

Това ми се е случвало два пъти.
(първия път сърцето ми прескочи един път:) )

[слайд 22]

Две интересни неща, от големите системи и от при мен по принцип.

Едното е нещо, което много хора според мен не правят правилно. Много често се казва – имаме нов проект, айде да купим още web, db и т.н. сървъри и да направим отделна инфраструктура, вместо просто да се разшири текущата. Така човек се озовава с много малки компонентчета, от които който и да е ако замине, има някакъв downtime на някаква услуга и съответно пожари за гасене. Разширяването на текущите системи, и дистрибутирането (доколкото е възможно) всичко да може да работи от всяка машина дава огромно scalability, издръжливост на атаки и доста по-спокоен сън. Аз лично трябва да гледам внимателно дали някой ни DoS-ва, понеже при нас нещата са достатъчно добре разпределени, че почти да няма кой да ни засили ефективна атака.
Според мен и така трябва да се борят DoS атаките.

Другото хубаво нещо, което написахме и което исках да пусна да се ползва публично, беше система за следене на трафика и загубата на пакети. При нас ползваме web сървър, който е вътрешно производство, и той праща по един пакет статистика за всеки connection, който е завършил, с данни колко байта и пакета са минали, към кой ip адрес, за колко време, тип на трафика и колко TCP retransmit-а е имало. На база на тази статистика и BGP таблицата аз мога да видя почасово към кои мрежи и автономни системи (и през кои пътища) имам повече загуби и да преценя дали искам да изместя част от трафика някъде другаде.
(след конференцията един приятел се нави да port-не нещото за apache и да пуснем колкото можем от него open-source, та може да има новини по темата скоро)

[слайд 24]

Та, ако ви е TL;DR лекцията, какво си струва да запомните:
1) имайте (добър) monitoring
2) правете нещата толкова просто, че да може да ги ремонтирате в 4 сутринта на пияна глава
3) Автоматизирайте
4) Имайте резервни варианти

(и пращайте корекции на тоя текст, че е писан на един път)

2012-08-22 RBL за български спам

Wednesday, August 22nd, 2012

След като много време се каних и не го свърших, Велин направи RBL за източници на български спам. Попълнен е от един списък мои правила и един негов, репликиран е на три машини с добра свързаност и може да се ползва свободно от който си иска (на собствена отговорност, as usual).

Update: Правило за spamassassin:

header FCCF_BG_RBL      eval:check_rbl('fccf_bg','rbl.fccf.net')
describe FCCF_BG_RBL    rbl.fccf.net for sources of Bulgarian spam
score FCCF_BG_RBL       3.5 3.5 3.5

(score-овете вече може да си ги настроите както искате)