Archiwum kategorii: linux

Serce mi krwawi (heartbleed) gdy widzę efekty pracy lamer adminów

Kilka dni temu świat IT obiegła informacja o bardzo niemiłej podatności w bibliotece OpenSSL. Została ona nazwana Heartbleed.Z grubsza umożliwia ona dostęp do pamięci procesu z którym możemy połączyć się protokołem TLS.

Po przeskanowaniu kilku sieci jestem bardzo zdegustowany poziomem jaki prezentują ladmini. Nie mówię o serwerach, które są całkowicie podatne, ignorowanie aktualizacji bezpieczeństwa może być zarówno wynikiem lenistwa, lamerstwa jak i układów biznesowych. Tacy ladmini nie są zaskoczeniem. Natomiast zauwazyłem jeszcze jedną kategorię, Ci co coś słyszeli o błedzie w OpenSSL i że ich serwery www mogą byc podatne na ten atak. Cóż takiego oni robią? Aktualizują bibliotekę kryptograficzną, restartują demona www i zadowoleni z siebie wylogowują się.
A ten błąd dotyczy wszystkich aplikacji korzystających z OpenSSL, tak, tak, MTA także jest podatny! Jak i demon pop3/imap, itd. Informacja o tym, że na porcie 443 działa serwer z załataną biblioteką ale na porcie 25 już nie wprowadza mnie w stan zażenowania, zażenowania, że ktoś może brać pieniądze za taką amatorszczyznę. Toć to większa amatorszczyzna niż 777 u pseudophpowców.

Nmap scan report for xxx.pl (91.x.y.z)
 Host is up (0.030s latency).
 Not shown: 2 closed ports
 PORT    STATE SERVICE
 25/tcp  open  smtp
 | ssl-heartbleed:
 |   VULNERABLE:
 |   The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. It allows for stealing information intended to be protected b
 y SSL/TLS encryption.
 |     State: VULNERABLE
 |     Risk factor: High
 |     Description:
 |       OpenSSL versions 1.0.1 and 1.0.2-beta releases (including 1.0.1f and 1.0.2-beta1) of OpenSSL are affected by the Heartbleed bug. The bug allows for reading me
 mory of systems protected by the vulnerable OpenSSL versions and could allow for disclosure of otherwise encrypted confidential information as well as the encryption
 keys themselves.
 |
 |     References:
 |       http://cvedetails.com/cve/2014-0160/
 |       http://www.openssl.org/news/secadv_20140407.txt
 |_      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160
 110/tcp open  pop3
 143/tcp open  imap
 443/tcp open  https
  465/tcp open  smtps
 | ssl-heartbleed:
 |   VULNERABLE:
 |   The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. It allows for stealing information intended to be protected b
 y SSL/TLS encryption.
 |     State: VULNERABLE
 |     Risk factor: High
 |     Description:
 |       OpenSSL versions 1.0.1 and 1.0.2-beta releases (including 1.0.1f and 1.0.2-beta1) of OpenSSL are affected by the Heartbleed bug. The bug allows for reading me
 mory of systems protected by the vulnerable OpenSSL versions and could allow for disclosure of otherwise encrypted confidential information as well as the encryption
 keys themselves.
 |
 |     References:
 |       http://cvedetails.com/cve/2014-0160/
 |       http://www.openssl.org/news/secadv_20140407.txt
 587/tcp open  submission
 | ssl-heartbleed:
 |   VULNERABLE:
 |   The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. It allows for stealing information intended to be protected b
 y SSL/TLS encryption.
 |     State: VULNERABLE
 |     Risk factor: High
 |     Description:
 |       OpenSSL versions 1.0.1 and 1.0.2-beta releases (including 1.0.1f and 1.0.2-beta1) of OpenSSL are affected by the Heartbleed bug. The bug allows for reading me
 mory of systems protected by the vulnerable OpenSSL versions and could allow for disclosure of otherwise encrypted confidential information as well as the encryption
 keys themselves.
 |
 |     References:
 |       http://cvedetails.com/cve/2014-0160/
 |       http://www.openssl.org/news/secadv_20140407.txt
 |_      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160
 993/tcp open  imaps
|_      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160

Profilowanie kompilowanych binarek w Gentoo

Gcc, najczęściej używany kompilator w Gentoo (czy ktoś zna inne kompilatory, którymi da się skompilować system dający uruchomić się?) posiada możliwość profilowania kompilowanego kodu. Wykorzystując wcześniej przygotowane dane, stara się on utworzyć kod wykonywalny, który teoretycznie[1] powinien działać szybciej niż kod nieprofilowany.

Odpowiednie flagi gcc to -fprofile-generate oraz -fprofile-use. Program skompilowany z flagą -fprofile-generate będzie tworzył pliki .gcda w katalogu roboczym. Takie tworzenie plików „gdziekolwiek” nie jest zwykle pożądane, lepiej aby te pliki były generowane w określonej lokalizacji. Pomocą służy nam opcja -fprofile-dir= z której pomocą możemy wskazać katalog w którym będą tworzone pliki *.gcda . Musimy jednak wiedzieć, że ta flaga pojawiła się w GCC dopiero od wersji 4.4.0 .
Wiemy już w jaki sposób możemy możemy wybrać miejsce w którym będą tworzone pliki potrzebne do profilowania. Krok do przodu i kolejny problem, czyli możliwość wystąpienia kolizji. Częstą sytuacją jest, że pliki źródłowe mają taką samą nazwę w różnych pakietach. Dobrym rozwiązaniem wydaje się być utworzenie podkatalogów o nazwie tworzonej na podstawie nazwy pakietu. I co? Może mamy dla każdego pakietu zmieniać flagę -fprofile-dir=/sciezka/do/gcda/nazwa_pakietu ? Jest to trochę mało wygodne.
Ciekawe rozwiązanie znalazłem na rosyjskojęzycznym forum dotyczącym Gentoo, użytkownicy stworzyli modyfikacje do helpera o nazwie emake. Cała „obsługa” sprowadza się do ewentualnego ustawienia katalogu bazowego dla plików .gcda , a wybór czy tego czy binarka ma być skompilowana tradycyjnie, z opcją aby tworzyła pliki profilowe lub skompilowana z użyciem tychże plików dokonywany jest poprzez zmienną FEATURES.
Podczas testowania tego rozwiązania natrafiłem na problem, make dosyć często ignorował CFLAGS ustawione jako zmienne środowiskowe (kwestia budowy Makefile?), użycie make w następujący sposób: make CFLAGS=fprofile-use uznaję za zbyt inwazyjne, nadpisuje flagi użytkownika oraz wprowadza flagi, które mogły być usunięte przez ebuild (filter-flags). Uznałem, że lepiej będzie gdy dodatkowe flagi będą dodane do istniejących zanim będzie pakiet konfigurowany (zazwyczaj przed słynnym ./configure). Niektóre pakiety (np.bzip2) nie mają w ogóle fazy src_configure() dlatego umieściłem  ten kod w src_unpack().  Dzięki temu CFLAGI zostaną, z pomocą configure, prawidłowo umieszczone w Makefile. Najlepszym miejscem do modyfikacji portage wydaje się mi plik /usr/lib/portage/bin/ebuild.sh. Dokonałem kilku drobnych zmian do oryginalnego rozwiązania, plik różnicowy wygląda tak:

--- ebuild.sh.orig      2010-09-03 14:23:46.000000000 +0200
+++ ebuild.sh   2010-09-03 14:44:29.400038418 +0200
@@ -453,6 +453,33 @@
 # should be preserved.
 find . -mindepth 1 -maxdepth 1 ! -type l -print0 | \
 ${XARGS} -0 chmod -fR a+rX,u+w,g-w,o-w
+
+       # New implementation with profiling on compilation support
+       # source "${PORTAGE_BIN_PATH}/isolated-functions.sh"  &>/dev/null
+       PROFILE_DIR="${PROF_DIR:-/var/tmp/profile}"
+       PROFILE_SUBDIR="${PROFILE_DIR}/${CATEGORY}/${PF}"
+       GCC_VERSION=$(gcc --version | awk '{print $3;exit}')
+       if has profile ${FEATURES} ; then
+                       if [[ ${GCC_VERSION} < 4.4.0 ]]; then
+                               ewarn "\nGCC version is too old to use compilation with profile usage."
+                               ewarn "GCC 4.4.0 or higher required."
+                               ewarn "Falling back to compilation w/o profile usage.\n"
+                       elif has profile-use ${FEATURES} ; then
+                               if [[ -d ${PROFILE_SUBDIR} ]] ; then
+                                       einfo "\nCompiling with profiling data usage.\n"
+                                       CFLAGS+=" -fprofile-use -fprofile-dir=${PROFILE_SUBDIR} -Wcoverage-mismatch -fprofile-correction"
+                                       CXXFLAGS="${CFLAGS}"
+                               else
+                                       ewarn "\nNo directory with profiling data. Did you run fist stage and then program itself?\n"
+                               fi
+                       else
+                               einfo "\nCompiling with profiling data gathering support.\n"
+                               mkdir -m 777 -p "${PROFILE_SUBDIR}"
+                               CFLAGS+=" -fprofile-generate -fprofile-dir=${PROFILE_SUBDIR}"
+                               CXXFLAGS="${CFLAGS}"
+                               LDFLAGS+=" -fprofile-arcs"
+                       fi
+       fi
 }

 strip_duplicate_slashes() {

Alternatywą jest pobranie pliku-patcha z adresu: http://repoz.mejor.pl/svn/gentoo/distfiles/ebuild-2.1.8.3-profile.patch.
Lista nowych opcji jakie możemy ustawić w /etc/make.conf:
PROFILE_DIR=< ścieżka do katalogu, poniżej którego będę tworzone pliki profilujące>, domyślna wartość to /var/tmp/profile
W FEATURES można ustawić:
profile – kompilacja z ustawieniem flagi aby tworzyć pliki służące profilowaniu
profile-use – kompilacja z użyciem plików profilujących, aby ta flaga działała musi być również ustawiona opcja profile

To co? Wszystko jest omówione? A co jeśli program zostanie uruchomiony najpierw przez roota, a potem zwykły śmiertelnik będzie chciał także go uruchomić? Wtedy dostanie listę komunikatów z serii permission denied dla wszystkich plików .gcda , i tyle byłoby z profilowania.
Rozwiązałem to z użyciem ACL, czyli musimy pamiętać aby partycja, na której będę zbierane te pliki (nie są duże) była zamontowana z obsługą ACL.
# getfacl profile/
# file: profile/
# owner: root
# group: root
user::rwx
group::rwx
other::rwx
default:user::rwx
default:group::rwx
default:other::rwx

Tak nadajemy te uprawnienia:
setfacl -d -m g::rwx /var/tmp/profile
setfacl -d -m o::rwx /var/tmp/profile
setfacl -m g::rwx /var/tmp/profile
setfacl -m o::rwx /var/tmp/profile

[1] – ktoś pokusi się i sprawdzi na ile takie profilowanie przyśpiesza wykonywanie programu? I zaprezentuje zarówno pozytywne jak i negatywne wyniki testów pomiarów szybkości ;)

P.S. Właśnie zauważyłem, że ta funkcja nie działa przy live ebuildach.

Poprawa interaktywności desktopa z linuxem

W gentoowskim drzewku Portage pojawił się nowy ebuild o nazwie zen-sources . Jest to zestaw łatek na vaniliowego kernela (jakich to sprawdźcie sami, ale jedna chyba z najważniejszych to łatka z nowym brainfuck schedulerem od Cona Kolivasa ). Przy komiplacji kernela miałem problem ze sterownikiem DRI do Radeona. Normalnie byłby to duży problem, ponieważ DRI ma wpływ na obciążenie procesora analgocznie jak DMA dla operacji dyskowych. W moim przypdku jest coś nie halo z ati-drivers i tak czy siak xorg-server nie używał DRI. Tutaj więc nic nie straciłem.

Testowałem to na maszynie jednoprockowej z Celeronem, różnica jest szokująca. Przy kernelu gentoo-sources, włączenie jednowątkowej kompilacji z nice 10 powodowało nieprzyjemne mulenie okienek. Większe obciążenie sprawiło, że przywrócenie cięzkiego firefoksa z pasa zadań trwało kilka sekund. Pracując na kernelu zen-sources opóźnienie niewiele zmieniało sę wraz ze wzrostem obciążeia (czy load był ~1 czy ~5) to dało się normalnie pracować w środowisku graficznym.

Komu doskwiera mała interktywność linuxa na desktopie ten powiniem spróbować nowego schedulera i/lub łatek o nazwie zen.

Optymalizacja gcc march=native czyli march=co?

Od kiedy w gcc pojawiła się możliwość podania architektury jako „native”, czyli pozwalamy aby kompilator sprawdził jaki jest typ procesora i wybrał najlepszą możliwą architekturę dla parametru -march (lub -mtune), zastanawiałem się jaką tak naprawdę wybierał. Czy na przykład nie używa zbyt niskiej architektury, a może nie włącza flagi -msse3 mimo, że procesor ją wspiera.

Sposób znalazłem na liście mailowej gcc:

$ touch test.c

$ gcc -fverbose-asm -march=native -S test.c

$ cat test.s

albo:

$ gcc -fverbose-asm -march=native -S test.c -o –

aby otrzymać wynik od razu na ekranie.


(możemy wstawić własne flagi np. -02 aby zobaczyć jakie dodatkowe flagi
optymalizacji zostaną użyte)


Jak odrzucić maila i zostawić sobie jednocześnie jego kopię

Ten post będzie o tym jak zapewnić większą ilość raportów wysyłanych przez SpamCopa do abuse@…

Zwykle (czyli tak jak np. ja miałem ;) ) serwer pocztowy jest tak skonfigurowany, że w momencie uznania iż dany mail jest spamem wysyła komunikat 550 i kończy sesję. Może to się stać zarówno podczas testów samego nagłowka, czyli zwykle jest to sprawdzenie poprawności syntaktycznej nagłówka i przede wszystkim odpytanie RBL, jak i po odebraniu całego maila, wtedy system wykrywający spam ( np. Spamassassin ) analizuje jego treść i oznacza go jako ham/spam.

Tak czy inaczej mail taki zostaje odrzucony, my wiemy, że była próba zaproponowania nam viagry ale nie mamy corpus delicti do zaraportowania.

Uważam, że jeśli nadawca siedzi już w RBLu to są dwa powody aby zakończyć konwersację natychmiast, bez przyjmowania całości maila. Pierwszy powód to taki, że skoro jest już na czarnej liście to znaczy, że został już zgłoszony odpowiednią ilość razy. Drugim jest fakt, że po to korzystam z czarnych list aby zmniejszyć obciążenie łącza jak i samego serwera, ciężkim SpamAssasinem. Czyli wybór prosty, jeżeli mail zostanie odrzucony poprzez antyspama to wtedy chciałbym mieć jego kopię do zaraportowania.

Do zaimplementowania tej funkcji w Eximie wykorzystałem fakereject .

Plan działania jest taki: oznaczam takiego maila zmienną, dodaje nowy router, przed routerem, który normalnie doręczył by maila do maildira. W nim sprawdzam stan zmiennej oznaczającej czy dany mail jest spamem czy nie. Jeśli wynik testu jest pozytywny to kieruje przesyłkę do oddzielnego transportu.

O to szczegóły, kolorem czerwonym oznaczam dodatkowe wpisy obok standardowo występujących.

acl_check_data:

……

deny warn message           = This message scored $spam_score spam points.

spam                  = nobody:true
condition         = ${if >{$spam_score_int}{44}{1}{0}}
set acl_m1        = spam
control              = fakereject/This message scored $spam_score spam points.SC.

begin routers

dnslookup:

………

spam_fakereject:

driver = accept
condition = ${if eq {$acl_m1}{spam}{true}{false}}
transport = spam_transport

……..

begin transports

spam_transport:

driver = appendfile
directory = /home/spam
maildir_format
delivery_date_add
envelope_to_add

To zapewni nam, że w katalogu /home/spam wyląduje wszystko ze zbyt wysoką punktacją. Teraż możemy sobie poczytać wszelkie oferty ;) oraz zgłosić je komu trzeba.

Jeżeli chcemy automagicznie, bez czytania, wysłać zgłoszenie do SpamCopa to możemy to zrobić poprzez modyfikację transportu tak aby wołaj od razu spamassassina (za pomocą którego będziemy wysyłać raport).

Skorzystamy z drivera pipe

spam_transport:

driver = pipe
command = /usr/bin/spamassassin -r

Potrzebujemy także uaktywnić wymagany plugin w Spamassassinie.

W pliku v310.pre dodajemy:

loadplugin Mail::SpamAssassin::Plugin::SpamCop

a w pliku local.cf podajemy adres do submitowania przypisany do naszego konta na SC:

spamcop_to_address      submit……@…..

Voila.


Migracja systemu Gentoo na LVM2 na raid

Z okazji zmiany dysku na większy chciałem w ramach zyskania nowych doświadczeń przenieść system na LVMa.

Przyjąłem założenie, że LVM zostanie zainstalowany na zdegradowanym raidzie, łatwiej jest potem dołożyć nowy dysk, niż kombinować jak przenieść LVM na raida (chociaż według opisu http://akademia.linuksa.pl/readme/lvm/ nie jest to zbyt problematyczne) . Bootloader GRUB w obecnej, szeroko dostępnej wersji (~0.97) nie obsługuje LVM więc partycja /boot będzie umieszczona bezpośrednio na raidzie. Również poza LVM zostanie umieszczona root partycja czyli / . Wynika to z tego, że mam dużą niechęć do initrd , a jest on niestety niezbędny aby powstał system z główną partycją umieszczoną na LVM.

O to jak to zrobiłem to na gentoo:

( O „emerge lvm2” i „rc-update add lvm boot” nie będe wspominał ;)  )

Dysk ma pojemność 250GB, podzieliłem go na takie partycje:

Device Boot      Start         End      Blocks   Id  System
/dev/sdc1   *           1          73      586341   83  Linux
/dev/sdc2              74       30103   241215975    5  Extended
/dev/sdc5              74       13690   109378521   fd  Linux raid autodetect
/dev/sdc6           13691       29252   125001733+  fd  Linux raid autodetect
/dev/sdc7           29253       29434     1461883+  fd  Linux raid autodetect
/dev/sdc8           29435       30103     5373711   fd  Linux raid autodetect

sdc1 to będzie partycja /boot

sdc5 i sdc6 to będą partycje pod lvm

sdc7  to swap

sdc8 będzie partycją / (przeznaczyłem na nią 5.5G aby nie martwić się jak ją powiększyć,)

I na wszelki wypadek zostawiłem 2.4G wolnego miejsca. Root partycję umieściłem właśnie na końcu i po niej zostawiłem to wolne miejsce dodatkowo po to aby np. właśnie móc powiększyć tą partycję,

Zrobiłem dwie mniejsze partycje LVMowe zamiast jednej dużej, ponieważ nie jestem pewny czy nie najdzie mnie ochota zrobić raida używając mniejszych dysków znajdujących się w szufladzie.

Czytaj dalej Migracja systemu Gentoo na LVM2 na raid

Problemów z Reiserfs ciąg dalszy (not directory or indirect item)

Zawsze byłem zadowolony z tego systemu plików, szybki, nie zauważyłem aby robił mi jakieś świństwa po gwałtownym padzie zasilania. Po prostu sprawdza się na domowym komputerku. Za to przysparza problemów tam gdzie pracuje Firebird 1.5 .  Ma dziwną tendencję do psucia się na partycji /tmp , wrzucając do dmesga następujące komunikaty:

ReiserFS: md2: warning: vs-8115: get_num_ver: not directory or indirect item

Konsekwencje tego są bardzo problematyczne i nieciekawe. Z bazy firebirdowej zaczęły znikać rekordy, a może wyrywkowo nie pojawiały się nowe. Trudno powiedzieć, najważniejsze, że nie było tych danych, które powinny tam być. Jest to kolejny powód dla którego zaczynam odchodzić od tego systemu plików. Moim „idolem” jest na obecną chwilę XFS , niestety nie zawsze mogę go zastosować (nie wszędzie jest UPS).

Uzupełnienie: problem pojawiał mi się na różnych wersjach kerneli, poczynając od aruoxowego 2.6.9-coś tam , poprzez gentoo-sources 2.6.16 , 2.6.18, 2.6.23 . Na innych wersjach jądra nie miałem okazji sprawdzać.

Firebird i Reiserfs

Głównymi bohaterami są Firebird 1.5 oraz system plików reiserfs 3.6 .

Baza danych jest pojedynczym (jak to zwykle przy firebirdzie bywa ;) ) plikiem o wielkości od 1 GB do ~5 GB. Podaje taki przedział ponieważ obserwacji dokonywałem na wielu serwerach dla baz o różnej wielkości. Partycja jest zwykle o wielkości ~15-20 GB czyli jest znacznie większa od wielkości pliku.

Sposób pracy na bazie jest klasyczny, czyli dane są dokładane i to w dosyć sporej ilości.

W efekcie już po kilku tygodniach takiej pracy, plik bazodanowej jest bardzo mocno sfragmentowany. Filefrag zgłasza od kilkudziesięciu do nawet 200-300 tysięcy „extentsów”.

W ramach testów przeszedłem na XFS, efekt? Po kilku tygodniach pracy fragmentacja dla pliku ~2GB wynosi: 3 extents. Różnica jest olbrzymia.

Planuję obserwować jak będzie to zachowywać się na EXT3 w ramach alternatywy dla XFSa. I należałoby dać chyba jeszcze szansę reiserowi i zamontować go z opcją „notail”, być może to będzie miało pozytywny wpływ.

Epilog:

Po 3 tygodniach obserwacji, baza na XFS nadal jest w 3 częściach.

Baza umieszczona na Reiserfs zamontowanego z opcją notail, po kilku dniach zwiększyła ilość swoich kawałków z ponad dwóch tysięcy do ponad czterech tysięcy.

Exim i aliasy z bazy postgresowej

Aliasy trzymam w bardzo prostej tabelce:

CREATE TABLE aliasy
(
id serial NOT NULL,
alias text NOT NULL DEFAULT ”::text,
destination text NOT NULL DEFAULT ”::text,
CONSTRAINT aliasy_pkey PRIMARY KEY (id)
);

CREATE UNIQUE INDEX ind_alias
ON aliasy
USING btree
(alias);

CREATE TRIGGER cleanup_aliases
BEFORE INSERT OR UPDATE
ON aliasy
FOR EACH ROW
EXECUTE PROCEDURE cleanup_aliases();

CREATE OR REPLACE FUNCTION cleanup_aliases()
RETURNS „trigger” AS
$BODY$
DECLARE
BEGIN
NEW.alias := trim(both FROM lower(NEW.alias));
NEW.destination := trim(both FROM lower(NEW.destination));
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql’ VOLATILE;

Do tego jest trigger mający na celu zapisać w bazie dane małymi literami z obciętymi spacjami na początku oraz końcu. Ten trigger jest zapożyczony z blogu depesza.

Sam ruter w eximie wygląda następująco:

aliasy_postgres:
driver = redirect
allow_fail
allow_defer
data = ${lookup pgsql{ SELECT destination FROM aliasy where alias = (’${quote_pgsql:$local_part}@${quote_pgsql:$domain}’) }}