As simple as it gets...

Blog

Filozofia UNIXa

Eric S. Raymong w książce „UNIX. Sztuka programowania” (Tao of Unix) http://catb.org/~esr/writings/taoup/html/) wielokrotnie powtarza dlaczego UNIX jest tak lubiany przez programistów. Jedną z zalet jest fakt że bardzo dużo problemów można rozwiązać nie pisząc ani jednej linijki kodu za sprawą potęgi UNIXowego shella, a dokładniej jasne i prosty format tekstowy jako protokół wymiany danych pomiędzy programami, oraz potoki do łączenia różnych programów podstawowych.

Nie raz zdażyło mi się napisać potok skłądający się z 10 czy 15 programów, i taki potok robił coś niesłychanie skomplikowanego. Napisanie potoku zajmuje zwykle kilka minut, jest łatwe do przetestowania, i nie wymaga znajomości wielu algorytmów.

Dobrą anegdotą na temat filozofi pisania potoków możemy znaleśc w tejże książce, którą cytuję poniżej.

Master Foo and the Ten Thousand Lines

Master Foo once said to a visiting programmer: “There is more Unix-nature in one line of shell script than there is in ten thousand lines of C”.

The programmer, who was very proud of his mastery of C, said: “How can this be? C is the language in which the very kernel of Unix is implemented!”

Master Foo replied: “That is so. Nevertheless, there is more Unix-nature in one line of shell script than there is in ten thousand lines of C”.

The programmer grew distressed. “But through the C language we experience the enlightenment of the Patriarch Ritchie! We become as one with the operating system and the machine, reaping matchless performance!”

Master Foo replied: “All that you say is true. But there is still more Unix-nature in one line of shell script than there is in ten thousand lines of C”.

The programmer scoffed at Master Foo and rose to depart. But Master Foo nodded to his student Nubi, who wrote a line of shell script on a nearby whiteboard, and said: “Master programmer, consider this pipeline. Implemented in pure C, would it not span ten thousand lines?”

The programmer muttered through his beard, contemplating what Nubi had written. Finally he agreed that it was so.

“And how many hours would you require to implement and debug that C program?” asked Nubi.

“Many”, admitted the visiting programmer. “But only a fool would spend the time to do that when so many more worthy tasks await him”.

“And who better understands the Unix-nature?” Master Foo asked. “Is it he who writes the ten thousand lines, or he who, perceiving the emptiness of the task, gains merit by not coding?”

Upon hearing this, the programmer was enlightened.

Mój problem

Chciałbym podzielić się właśnie takim potokiem. Pewne zrządzenia losu zmusiły mnie do zaliczenia kursu Algorytmy i Struktury Danych. Jednym z programów zaliczeniowych jest napisanie słownika T9 w sposób dosyć wydajny. Dobre rozwiązanie pewnie będzie wykorzystywać tablice mieszające, albo drzewa trie, czy inne wygibasy. Oto jak rozwiązać to zadanie w 2 linijach shella:

Tworzenie słownika:

$ cat /usr/share/dict/words | tr "ABCDEFGHIJKLMNOQPRSTUVWXYZabcdefghijklmnopqrstuvwxyz'" '22233344455566677778889999222333444555666777788899991' | paste - /usr/share/dict/words | sort -k 1 > words.t9
$

(czas wykonania: 400ms)

Odpytanie słownika o kod 2722537:

$ look 2722537 ./words.t9
272253717	cracker's
272253752257	crackerjacks
27225375225	crackerjack
27225377	crackers
2722537	cracker
$

(czas wykonania: 1ms)

Jako ćwiczenie Czytelników uprasza się o zrozumienie powyższych potoków.

Hint: Manuale: look(1), tr(1), paste(1), sort(1)

Na zakończenie

Jako wytłumaczenie napiszę że napisałem implementacje drzew trie w języku D, i być może jest to trochę szybszy sposób, szczególnie że ułatwia wpisywanie kodu krok po kroku (tak jak w telefonie naciskamy klawisz po klawiszu), i pozwala na szybkie kasowanie poprzednich cyfr, oraz umożliwia podpowiadanie całych rodzin słów na podstawie prefiksu.

Implementacja zajeła 600 linijek kodu, i o dziwo zadziałała praktycznie od zaraz. W C domyślam się że zajeła by około 3 tysięcy linijek kodu, i to bez testów.

Coś więc w tej anegdocie jest.

Konkluzja

C jest dla lamerów. D czasami też.

· %2009/%04/%18 %21:%Apr · Witold Baryluk · 1 Comment

Debian/GNU Linux na pendrivie

Jakiś czas temu zrobiłem sobie z mojego odtwarzacza mp3 (WIWA made in china) który działa również jako pendrive 1GB przenośną instalację Debiana Lenny ze środowiskiem GNOME (w minimalnej postaci dosyć w przypadku 1GB).

W ostatnim czasie używam go coraz cześciej (czy to do testowania cudzego sprzętu, łamania wifi, używania komputerów w kafejkach, czy na uczelni gdzie nie mam konta). Naprawdę wygodna sprawa, szczególnie że na moim pendrivie dane mam zaszyfrowane (choć nie chroni to przed wszystkimi możliwymi atakami, jestem bezpieczny w razie zgubienia pendriva, gdzie mam różne hasła, klucze ssh czy osobiste informacje, historię przeglądania).

Postaram opisać sie jak skonfigurować taki pendrive.

Będzięmy potrzebowali pendrive o rozmiarze minimum 1GB. Może to być player mp3, ale ponieważ potrzebują one do odtwarzania mp3 partycji FAT, z reguły uda się wysupłać tylko 100MB na pliki mp3 na partycji FAT. W/g mnie bardzo wygodnie będzie pracować na pendrivie 4GB (tanie są już po 60zł, a szybkie w rodzaju Cruiser Voyager GT, OCZ Really2 czy OCZ AVT Turbo trochę drożej. ten ostatni super, ale trudno dostepny). Na 4GB uda się znaleść około 800-900MB na partycje FAT gdzie umiścić możemy dane dla głupich Windowsów czy odtwarzaczy MP3, a rozmiar pozwoli nam wpakować jeden obraz ISO (przydatne przy instalacji systemów na dysku). Oczywiście czym więcej tym lepiej. Przy 1GB zdarza mi sie kombinować (np. problem z aktualizacjami bo sie nie mieści wszystko, więc trzeba robić etapami korzystając z /tmp albo sshfs i innego komputera, albo wyrzucanie ręcznie plików z /usr/share/doc/ czy kompresja słowanika języka polskiego w /usr/share/dict )

Na początku musimy przygotować partycję oraz sam dysk. Ponieważ będziemy używać szyfrowania (naprawdę warto, a spadek wydajności jest pomijalny) najlepiej robić to na świeżo kupionym pendrivie. Jeśli pendrive był już przez Ciebie używany, to niestety nie istnieją dobre sposoby na upewnienie się że dane zostaną usuniętę, a to m.in. z powodu sprzętowych mechanizmu wearliving chroniących przed zniszczeniem pamięci flash w przypadku częstych nadpisań. W razie czego warto zrobić

badblocks -vv -w /dev/sdX # sprawdź 4 razy czy dysk jest sprawny, niszczy dane
wipe /dev/sdX # "wyczyść" dysk przy pomocy 30 wzorców do niszczenia

Ostatnie może potrwać wieki (kilka dni).

Po przygotowaniu sprzetowym dysku, warto skopiować obraz pendriva do pliku na dysk, wykonanie wszystkiego z emulatora qemu a potem z powrotem wgranie na pendriva. Tak jest znacznie szybciej, ponieważ pendrive jest naprawdę wolny, a w dodatku używana jest często operacja sync, a to zabija wydajność podczas instalacji (ja się niedoczekałem).

dd if=/dev/sdX of=./obraz_pendrive.img

Potrwa to jakieś 2-3 godzinki, jak masz większy niż 4GB pendrive możesz pokombinować.

Następnie odpalamy albo instalację przy pomocy zwykłego instalatora z cd/dvd czy co tam chcesz (ja lubię CD-bussinescard ponieważ jest mała i ściąga odrazu najświeższe pakiety) przy pomocy qemu, albo przy pomocy debootstrap. To ostatnie jest o tyle nie wygodne że będziesz musiał się trochę znać na konfiguracji LVM oraz szyfrowania.

qemu -hda ./obraz_pendrive.img -cdrom ./debian-500-CD-bussinescard.iso -m 256

Jak ktoś jest cierpliwy może zamiast obrazu .img stosować odrazu /dev/sdX, albo jak ma pod ręką komputer którego może nie używać przez powiedzmy jeden-dwa dni to zrobić normalna ludzką instalację na komputerze. Ja wolę przez qemu, szybko i nie trzeba sie podnosić z krzesła.

Wybieramy instalacje eksperta w języku Polskim.

Partycje:

Partycja Cel 1GB 4GB
sdX1 (vfat) pliki dla playera MP3, czy Windowsa 100MB 900MB
sdX2 (ext2) /boot z jądrem, grubem, initrd 25MB 60MB
sdX3 (luks) LVM z / (ext2) 810MB 3000MB

Mały jest sens robienia katalogu /home na oddzielnej partycji czy robienia partycji wymiany swap. Można spróbować zrobić partycje ext3, ale zalecałbym wyłączyć journaling (ale chyba ext3 tego nie supportuje), ponieważ journaling zabijć może pendriva (i jest powolne przez sync), ale ext3 jest troche szybszy (np. dzięki dir_index). Jak ktos ma dużo zaparcia to kompilacja nowszego jądra (2.9.29 lub .30) i odpalenie ext4 bez journalingu (to już jest wspierane), mogła by dużo przynieść. JFFS nie mam pojęcia jak skonfigurować. Dlatego na początek, ext2, może ext4+nojournal. W każdym wypadku warto włączyć opcje noatime oraz user_xattr zapewne. (A na partycji vfat dodatkowo nodev,nosuid)

Po skonfigurowaniu i zainstalowaniu systemu bazowego (nic więcej, ponieważ zainstaluje się nam za dużo softu), musimy przedewszystkim zmienić fstab i crypttab aby uzywały UUIDów. Niestety są pewne błędy w Lennym związane, ale da się je obejść.

proc                                        /proc           proc    defaults           0       0
# see bug #287879 in Ubuntu
/dev/disk/by-uuid/0a678c87-e490-4f74-90e6-9c175102cd96   /               ext2    noatime,user_xattr,errors=remount-ro 0       1
UUID=eadd15af-4c80-45ad-b676-ccccf51b83f3   /boot           ext2    noatime,ro         0       2
/dev/cdrom                                  /media/cdrom0   udf,iso9660 user,noauto    0       0
UUID=8B4F-24B3                              /mnt/wbpen1fat  vfat    rw,nosuid,nodev,uid=1000,gid=100,noatime,fmask=0133,dmask=0022,iocharset=iso8859-2         0       0
tmpfs                                       /tmp            tmpfs   defaults           0        0

Prawidłowe wartości UUID można znaleść najszybciej w katalogu /dev/disk/by-uuid/

Pakiety i inne informacje

Tu narazie są pewne wskazówki. Zredaguję to dokładniej.

# dobre prendrive; OCZ Really2, albo costam Voyager

mkfs.ext2 -L WB_PEN1_EXT2 /dev/sdc2_jakis
mount /dev/sdc2_jakis /mnt/pendrive
# debootstrap i insalacje najlepiej odpalic na dysku,
# a dopiero potem przegrac wszystko
deboostrap lenny /mnt/pendrive
mount --bind /dev/ /media/WB_PEN1_EXT2/dev/
chroot /mnt/pendrive
mount /proc
apt-get clean
echo "deb http://ftp.pl.debian.org/debian lenny main contrib non-free" > /etc/apt/sources.list
apt-get update
apt-get install locales # d-i: nie potrzebne, instalowany domyslnie
export LC_ALL=pl_PL.UTF-8 # d-i: nie potrzebne
export LANG=pl_PL.UTF-8 # d-i: nie potrzebne
apt-get install localepurge deborphan # do usuwania zbędnych śmieci
localepurge

# to sie przydaje w apt.conf
# moze zmniejszyszc i ulatwic instalacje gnome (z 160MB do 60MB)
APT::Install-Recommends "false";
APT::Install-Suggests "false";

# jak ktos chce, moze zrobic nastepujące, aby pytał się dokładniej
dpkg-reconfigure debconf # i zmienic na low

apt-get install bash-completion # d-i: nie potrzebne

. /etc/bash_completion

apt-get install dash mc sshfs

apt-get install linux-image-2.6.26-1-686 unionfs-modules-2.6.26-1-686 squashfs-modules-2.6.26-1-686 # d-i: nie potrzebne
# trzeba wybrac "No" w debconf po drodze
apt-get install unionfs-tools squashfs-tools grub live-initrams # d-i: nie potrzebne


apt-get install mc bzip2 unzip xpdf links file less openssh-client  # d-i: nie potrzebne file, less, openssh-client

# generalnie w/g uznania
dpkg --purge vim-tiny vim-common tasksel tasksel-data ed nano
dpkg --purge liblzo2-2 libgnutls13 libconsole libsigc++-1.2-5c2 libldap-2.3-0 man-db
dpkg --purge info manpages dgroff-base libsasl2 cyrus-sasl2-doc
dpkg --purge aptitude libsigc++-2.0-0c2a libcwidget3
dpkg --purge libept0 libttf2 libxapian15 perl-doc

# 78MB
apt-get install xserver-xorg-video-vesa xserver-xorg-video-nv xserver-xorg-input-wacom xserver-xorg-input-all- xbase-clients libgl1-mesa-dri mesa-utils xfonts-biznet-75dpi xfonts-base

# 15 MB
apt-get install wireless-tools
apt-get install lvm2 pciutils attr sshfs nfs-common ntfs-3g reiserfsprogs reiser4progs xfsprogs jfsutils ntfsprogs dosfstools rdesktop xvnc4viewer # d-i: nie potrzeba: pciutils, nfs-common
apt-get install nmap tcpdump telnet # d-i: nie potrzeba: telnet

# w tym miejscu, mozemy sobie przeniesci /var/cache/apt/archives na jakis komputer w sieci (np. po sshfs), co ulatwia i przyspiesza zabawe
# mozna to zrobic wczesniej jak ktos chce, lub chce podmontowac cache / pool przez nfs, czy co tam
# oprocz przyszpieszania procesu, oszczedza to zywotnosc pendriva
# jak mamy duzo ramu to zrobić to w /tmp (w tmpfs), będziemy musieli zrobić apt-get update co reboot, ale śmiga.

# 70 MB (normalnie 160MB, localepurge usuwa 46 MB dokumentacji!, lacznie 24MB)
apt-get install epiphany-browser aspell-pl gamin gnome-keyring
# +30MB
apt-get install gdm mplayer netselect fping # uwaga instalacja gdm jest niebezpieczna w qemu (bedzie problem ze zmienianiem konsol)
# +100MB
apt-get install gnome-panel gnome-keyring gnome-keyring-manager nautilus metacity
# +84MB
apt-get install alsa-utils alsa-base gnome-terminal rxvt-unicode-lite tcsh gnome-themes gnome-applets gnome-netstatus-applet cpufreqd lm-sensors gnome-system-monitor alsa-oss
apt-get install ca-certificates empathy claws-mail lastfm gedit evince openoffice.org-impress openoffice-writer
apt-get install psi libqca2-plugin-gnupg libqca2-plugin-ossl
apt-get install xserver-xephyr
apt-get install gqview
apt-get install xserver-xorg-video-{intel,nv,vesa}
apt-get install alsa-oss alsa-base

# sieć
apt-get install network-manager-gnome network-manager-openvpn-gnome gnome-network-admin
apt-get install wireshark aircrack-ng wpasupplicant wodim
apt-get install ipw2200-firmware madwifi-tools

apt-get install ttf-dejavu msttcorefonts ttf-liberation xfonts-biznet-75dpi
apt-get install ntpdate # przydaje sie jak podlaczym sie do maszyny z windowsem

# instalcja innych debianów
apt-get install debootstrap

# z non-free / contrib. Z flasha można zrezygnować, niestety gnash jeszcze średnio działa
apt-get install unrar flashplugin-nonfree 
# 217MB
apt-get install sun-java6-jre

apt-get clean

# d-i: nie potrzebne
echo "movax-pen1" > /etc/hostname # d-i: nie potrzebne

# d-i: nie potrzebne
cat >>/etc/network/interfaces <<-EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

# d-i: nie potrzebne
cat >>/etc/fstab <<-EOF
proc                    /proc   proc    defaults                0       0
unionfs                 /       unionfs rw,noatime              0       0
LABEL=WB_PAN1_EXT2      /boot   ext2    rw,noatime              0       0
tmpfs                   /tmp    tmpfs   rw                      0       0
EOF

echo > /etc/motd.tail

apt-get --purege remove cron
# wylaczyc atd i cron

# wylaczyc sysklog log
# eydtowac rzeczy w /etc/default

# doinstalowac zfs-fuse

# zmienic /etc/fstab z sztywnych urzadzen na UUID lub LABEL, lub /dev/disk/by-uuid/ (lepiej to ostatnie)
# poddodawac labele przy pomocy e2label
# zmienic /etc/crypttab na /dev/disk/by-uuid, nazwe zmienic na UUID rozszyfrowany
# zmienic /boot/grub/menu.lst na UUID= (dodac rowniez vga=791)

cdn

· %2009/%04/%13 %19:%Apr · Witold Baryluk · 0 Comments

Rozproszone ataki na serwery SSH

Kilka dni temu miał miejsce pierwszy atak typu DDoS na setki serwerów z dostępem SSH na porcie 22. Atak polegał na próbie logowania się na konto „root” z różnymi popularnymi hasłami (zapewne).

Dowiedziałem się tego jakieś 10 godzin po rozpoczęciu ataku dzięki programowi denyhosts zainstalowanemu na wszystkich maszynach którymi adminuje. (Program loguje nieudane próby logowań, a przy przekroczeniu pewnych limitów blokuje dane IP, i wysyła do centralnej bazy danych).

Zaraz po przejrzeniu mojej skrzynki okazało się że ataków było prawie 300 z całego świata, średnio każde połączenie przed zablokowaniem sprawdziło około 3 haseł. Co sprytne każde połączenie sprawdzało inny zakres słownika, więc denyhosts nie jest wystarczająco bezpiecznym rozwiązaniem, ponieważ atakujący ma do dyspozycji olbrzymią ilość komputerów i adresów IP (skompromitowane komputery z Windowsem, albo serwery pocztowe, boje się co będzie z IPv6). Tak więc blokowanie po 1 nieudanej próbie nawet nie wystarczy, a jest upeirdliwe dla normalnych ludzi (jak ja). Zalecane jest zmiana portu SSH na dziwny, zmiana konta roota na inną nazwę, używanie mocnego hasła, albo logowanie tylko przy pomocy kluczy RSA.

Zaraz po przeglądnieciu skrzynki i upewnieniu się że to normalne, zajrzałem na http://stats.denyhosts.net/stats.html A, tam dnia 8 kwietnia (dzień ataku), piękny pik, około 30 krotny wzrost ruchu. Również inni administratorzy zauważyli wzmożone ataki SSH ( http://isc.sans.org/diary.html?storyid=6148)

Ponieważ właśnie zauważyłem powtórkę z rozrywki, a być może nawet jeszcze większy atak, apeluję wszystkich którzy czytają o zmianę portu SSH, i zainstalowanie koniecznie denyhosts (apt-get install deny-hosts; a potem droba konfiguracja aby wysyłało informacje do centralnej bazy). Dzięki temu uchronimy swój komputer (serwer) jak i inne osoby korzystające z bazy.

Pozdrawiam.

Filtrowanie poczty i różne takie

Ponieważ Internet, a szczególnie poczta elektroniczna pełne są SPAMu, trzeba z nim jakoś walczyć aby nie spędzać pół dnia w celu znalezienia normalnej korespondencji w naszej skrzynce.

Do tej pory używałem filtrowania w programie Sylpheed. Edycja regułek jest całkiem prosta.

W ciągu lat nabrało mi się tam całkiem sporo regułek.

Dodatkowo można użyć uczenia się na podstawie danej wiadomości.

Dodatkowo używam programu bogofilter do filtrowania po słowach przy użyciu różnych technik statystycznych.

Takie połączenie praktycznie elimnuje SPAM, a jeśli się jakiś pojawi, to wystarczy filtr statystyczny douczyć na wiadomościach którym udało się cudem przejść.

Niestety z poczty korzystam teraz w coraz to nowych miejscach i nie zawsze mam dostęp do własnego komputera. Korzystam więc nie tylko z Sylpheed, ale i z Evolution, mutt, pine czy squirellea. I nie zawsze mam czas na synchronizację filtrów i bazy słów bogofiltera.

Dobrym rozwiązaniem wydaje się więc użycie filtrowania po stronie serwera.

Courier i listy

Przed przystąpieniem do dlaszej cześci należy się upewnić, że konfiguracja Couriera spełnia następujące warunki:

  • Połączenia SMTP są szyfrowane
  • Tylko autoryzowani użytkownicy mogą wysłać w świat
  • Stosujemy graylisting
  • Stosujemy czarne listy DNS (m.in. openrelayów i znanych hostów spamowych)
  • Stosujemy whitelisting na dużych ISP (np. google.com sprawia problemy przy graylistingu)
  • Włączona jest obsługa maildropa i/lub .forward/.procmail
Courier i maildrop

Ponieważ na serwerze smp.if.uj.edu.pl używamy Couriera, dobrym pomysłem jest użyć maildrop'a i jego języka filtracji.

Zacząłem więc od prostego pliku ~/.mailfilter (w razie nie skonfigurowanego maildropa można użyć pliku ~/.forward lub ~/.procmailrc i odpalić maildropa). Adresy ludzi usuniętę.

logfile "./.filtrowanie.log"

DEFAULT="./Maildir/"

if (/^Subject:.*[ ]test$/:h)
{
	exception {
		to "./Maildir/.testymaildropa/"
	}
}

if (/^From:.*Mailer-Daemon@smp\.if\.uj\.edu\.pl/:h)
{
	exception {
		to "./Maildir/.AAA_Bledy/"
	}
}

if (/^Subject:.*\[rkhunter\]/:h)
{
	exception {
		to "./Maildir/.Adminowanie.rkhunter/"
	}
}

if (/^Subject:.*\[AppDB\]/:h)
{
	exception {
		to "./Maildir/.Informatyka.Wine/"
	}
}

if (/^Subject:.*DenyHosts/:h)
{
	exception {
		to "./Maildir/.Adminowanie.DenyHosts/"
	}
}

if (/^From:.*Cron Daemon/:h)
{
	exception {
		to "./Maildir/.Adminowanie.Admin SMP Cron/"
	}
}

if (/^From:.*Mail Delivery Subsystem/:h)
{
	exception {
		to "./Maildir/.AAA_Bledy/"
	}
}

if (/^List-Id:.*erlang\.org/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Informatyka.Erlang/"
	}
}

if (/^List-Id:.*erlyweb\.googlegroups\.com/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Informatyka.Erlang/"
	}
}

if (/^From:.*allegro\.pl/:h)
{
	exception {
		to "./Maildir/.Serwisy.Allegro/"
	}
}

if (/^From:.*griddlers\.net/:h)
{
	exception {
		to "./Maildir/.Serwisy.griddlers/"
	}
}

if (/^List-Id:.*jabsterpl\.googlegroups\.com/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Serwisy.Jabster/"
	}
}

if (/^List-Id:.*debian-security-announce\.lists\.debian\.org/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Debian.Security/"
	}
}

if (/^List-Id:.*lists\.debian\.org/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Debian/"
	}
}

if (/^From:.*twojastrona@filmweb\.pl/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Serwisy.Filmweb/"
	}
}

if (/^From:.*mailinglist@ncix\.net/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.Informatyka.NCIX/"
	}
}

if (/^From:.*newsletter@mysql\.com/:h)
{
	exception {
		to "./Maildir/.Informatyka/"
	}
}

if (/^List-Id:.*comp-phys-alps-users\.phys\.ethz\.ch/:h)
{
	exception {
		to "./Maildir/.SMP.Edu.ALPS/"
	}
}

if (/^From:.*noreply@sourceforge\.net/:h)
{
	exception {
		to "./Maildir/.Informatyka.SFnet/"
	}
}

if (/^From:.*forum@smp\.if\.uj\.edu\.pl/:h)
{
	xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -n -e -p"
	exception {
		to "./Maildir/.SMP.Forum/"
	}
}

if (/^From:.*@grono\.net/:h)
{
	exception {
		to "./Maildir/.Serwisy/"
	}
}

if (/^From:.*andrzej@xxxx\.xx/:h)
{
	exception {
		to "./Maildir/.Ludzie.Andrzej/"
	}
}

if (/^From:.*kasia@xx.xxx.xx/:h)
{
	exception {
		to "./Maildir/.Ludzie/"
	}
}

if (/^From:.*jola@xx.xx/:h)
{
	exception {
		to "./Maildir/.Ludzie.Jola/"
	}
}

## TUTAJ DODATKOWE

xfilter "/usr/bin/bogofilter -d /home/baryluk/.bogofilter -u -e -p"
if (/^X-Bogosity: (Spam|Yes), tests=bogofilter/)
{
	exception {
		to "./Maildir/.Spam.SpamBogoDotMailfilter/"
	}
}

Jak widać na początku filtrujemy różne listy dyskusyjne i osoby. W przypadku kiedy żaden filtr nie zadziała, odpalamy bogofiltera w trybie passthrouth z uczeniem. W trybie tym bogofilter dodaje do wiadomości (w potoku) dodatkową linijkę w nagłówku.

W przypadku kilku grup dyskusyjnych na chwilę włączyłem dodatkowo uczenie się HAMu. Są to grupy dyskusyjne na których dzieją się różne dyskusje i słownictwa z nich warto nauczyć bogofiltera. Dodatkowo nie spotykam się tam ze SPAMem więc jest to w miarę bezpieczne.

Na początku bazę bogofitlera warto zrobić ręcznie albo z lini poleceń albo z Sylpheed lub Evolution, a następnie przegrać plik z bazą słów na serwer. 200 wiadomości obu rodzajów to dobry początek. Należy pamiętać aby były to świeże wiadomości oraz twoje własne.

Konwersja z filter.xml do .mailfilter

Ideą jednak jest pełna synchronizacja (przynajmniej w jedną stronę). Do synchronizacji pliku filter.xml z Sylpheeda używam następującego pliku XSLT (Autorstwa mojego, licencja BSD):

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
 
<xsl:template name="string-replace-all"><xsl:param name="text"/><xsl:param name="replace"/><xsl:param name="by"/>
<xsl:choose>
 <xsl:when test="contains($text,$replace)">
  <xsl:value-of select="substring-before($text,$replace)"/><xsl:value-of select="$by"/>
  <xsl:call-template name="string-replace-all">
   <xsl:with-param name="text" select="substring-after($text,$replace)"/>
   <xsl:with-param name="replace" select="$replace"/>
   <xsl:with-param name="by" select="$by"/>
  </xsl:call-template>
 </xsl:when>
 <xsl:otherwise>
  <xsl:value-of select="$text"/>
 </xsl:otherwise>
</xsl:choose>
</xsl:template>
 
<xsl:template match='/'>
# Filtry
<xsl:for-each select='filter/rule'>
# <xsl:value-of select='@name'/>
if (<xsl:for-each select='condition-list'>
  <xsl:variable name="cond" select="@bool"/>
  <xsl:for-each select='*'>
   <xsl:if test='position() &gt; 1'>
    <xsl:if test='$cond = "or"'>&#10;<![CDATA[ || ]]></xsl:if>
    <xsl:if test='$cond = "and"'>&#10;<![CDATA[ && ]]></xsl:if>
   </xsl:if>
   <xsl:variable name="ch1"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="."/><xsl:with-param name="replace" select="'.'"/><xsl:with-param name="by" select="'\.'"/></xsl:call-template></xsl:variable>
   <xsl:variable name="ch2"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="$ch1"/><xsl:with-param name="replace" select="'['"/><xsl:with-param name="by" select="'\['"/></xsl:call-template></xsl:variable>
   <xsl:variable name="ch3"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="$ch2"/><xsl:with-param name="replace" select="']'"/><xsl:with-param name="by" select="'\]'"/></xsl:call-template></xsl:variable>
   <xsl:variable name="ch4"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="$ch3"/><xsl:with-param name="replace" select="'&lt;'"/><xsl:with-param name="by" select="'.'"/></xsl:call-template></xsl:variable>
   <xsl:variable name="ch"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="$ch4"/><xsl:with-param name="replace" select="'&gt;'"/><xsl:with-param name="by" select="'.'"/></xsl:call-template></xsl:variable>
   <xsl:choose>
    <xsl:when test='name() = "match-header"'>/^<xsl:value-of select='@name'/>:\s*<xsl:value-of select="$ch"/>/:h</xsl:when>
    <xsl:when test='name() = "match-any-header"'>/^[^:]+:\s*<xsl:value-of select="$ch"/>/:h</xsl:when>
    <xsl:when test='name() = "match-to-or-cc"'>/^(To|Cc):\s*<xsl:value-of select="$ch"/>/:h</xsl:when>
    <xsl:otherwise>False</xsl:otherwise>
   </xsl:choose>
  </xsl:for-each>
 </xsl:for-each>) {<xsl:for-each select='action-list'>
  <xsl:for-each select='*'>
   <xsl:choose>
   <xsl:when test='name() = "move"'>
    <xsl:variable name="mailbox"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="."/><xsl:with-param name="replace" select="'#imap/SMP/INBOX/'"/><xsl:with-param name="by" select="'/'"/></xsl:call-template></xsl:variable>
    <xsl:variable name="mailbox2"><xsl:call-template name="string-replace-all"><xsl:with-param name="text" select="$mailbox"/><xsl:with-param name="replace" select="'/'"/><xsl:with-param name="by" select="'.'"/></xsl:call-template></xsl:variable>
 exception {
  to "./Maildir/<xsl:value-of select="$mailbox2"/>/"
 }
   </xsl:when>
   </xsl:choose>
  </xsl:for-each>
 </xsl:for-each>
}
</xsl:for-each>
</xsl:template>
 
</xsl:stylesheet>

Po zastosowaniu do następującego pliku filter.xml (cześć usunięta):

<?xml version="1.0" encoding="UTF-8"?>
 
<filter>
    <rule name="spamcop" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">spamcop.net&gt;</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie</move>
        </action-list>
    </rule>
    <rule name="spam" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="Subject">[SPAM</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Spam</move>
        </action-list>
    </rule>
    <rule name="reczny spam" timing="any" enabled="false">
        <condition-list bool="or">
            <match-any-header type="contains">is listed</match-any-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Spam/SpamReczny</move>
        </action-list>
    </rule>
    <rule name="spoj" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">potyczki_algorytmiczne@adbglobal.com</match-header>
            <match-header type="contains" name="From">contact@spoj.sphere.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Informatyka/SPOJ</move>
        </action-list>
    </rule>
    <rule name="allegro" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">@allegro.pl</match-header>
            <match-header type="contains" name="From">@smtp2.allegro.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Serwisy/Allegro</move>
        </action-list>
    </rule>
    <rule name="astro4u" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">&quot;Astro-Forum.org&quot; &lt;adam@procreative.pl&gt;</match-header>
            <match-header type="contains" name="From">&quot;Astronomia Amatorska&quot; &lt;r.ambrozy@pkab.com.pl&gt;</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Serwisy/Astro</move>
        </action-list>
    </rule>
    <rule name="Bledy poczty" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="Subject">Mail delivery failed: returning message to sender</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/AAA_Bledy</move>
        </action-list>
    </rule>
    <rule name="Admin SMP LogSec" timing="any" enabled="true">
        <condition-list bool="and">
            <match-header type="contains" name="From">logcheck@smp.if.uj.edu.pl</match-header>
            <match-header type="contains" name="Subject">Security Events</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie/Admin SMP Security</move>
        </action-list>
    </rule>
    <rule name="Admin LogSys" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">logcheck@smp.if.uj.edu.pl</match-header>
            <match-header type="contains" name="From">logcheck@mpi.int.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie/System Events</move>
        </action-list>
    </rule>
    <rule name="Admin MPI LogSec" timing="any" enabled="true">
        <condition-list bool="and">
            <match-header type="contains" name="From">logcheck@mpi.int.pl</match-header>
            <match-header type="contains" name="Subject">Security Events</match-header>
            <match-header type="contains" name="To">postmaster@smp.if.uj.edu.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie</move>
        </action-list>
    </rule>
    <rule name="Admin SMP Cron" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">root@smp.if.uj.edu.pl (Cron Daemon)</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie/Admin SMP Cron</move>
        </action-list>
    </rule>
    <rule name="Admin MPI Arpwatch" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">arpwatch@mpi.int.pl (Arpwatch paul.mpi.int.pl)</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie/Admin MPI Arpwatch</move>
        </action-list>
    </rule>
    <rule name="Administracja" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="is" name="To">root@smp.if.uj.edu.pl</match-header>
            <match-header type="is" name="To">root@mpi.int.pl</match-header>
            <match-header type="is" name="To">root@localhost</match-header>
            <match-header type="is" name="From">root@mpi.int.pl</match-header>
            <match-header type="is" name="From">root@smp.if.uj.edu.pl</match-header>
            <match-header type="contains" name="From">Cron Daemon</match-header>
            <match-header type="contains" name="Subject">Cron &lt;root@</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie</move>
        </action-list>
    </rule>
    <rule name="mysql" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">root@smp.if.uj.edu.pl</match-header>
            <match-header type="contains" name="Subject">WARNING: mysqlcheck has found corrupt tables</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie</move>
        </action-list>
    </rule>
    <rule name="Debian" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="To">debian-user-polish@lists.debian.org</match-header>
            <match-header type="contains" name="To">@bugs.debian.org</match-header>
            <match-header type="contains" name="List-Id">lists.debian.org</match-header>
            <match-header type="contains" name="From">automat@debian.linux.pl</match-header>
            <match-header type="contains" name="From">@bugs.debian.org</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Debian</move>
        </action-list>
    </rule>
    <rule name="Gniazdo" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="List-Id">gniazdo.smp.if.uj.edu.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/Gniazdo</move>
        </action-list>
    </rule>
    <rule name="TopCoder" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">@topcoder.com</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Informatyka/TopCoder</move>
        </action-list>
    </rule>
    <rule name="Nexenta" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="List-Id">gnusol-devel.lists.sonic.net</match-header>
            <match-header type="contains" name="From">@gnusolaris.org</match-header>
            <match-to-or-cc type="contains">@gnusolaris.org</match-to-or-cc>
            <match-to-or-cc type="contains">@nexenta.org</match-to-or-cc>
            <match-header type="contains" name="From">@nexenta.org</match-header>
            <match-header type="contains" name="List-Id">gnusol-changes.lists.sonic.net</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Informatyka/Nexenta</move>
        </action-list>
    </rule>
    <rule name="Jola" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xxxx@xx/pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Ludzie/Jola</move>
        </action-list>
    </rule>
    <rule name="ALPS" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="List-Id">mailman.phys.ethz.ch</match-header>
            <match-header type="contains" name="List-Id">comp-phys-alps-users.phys.ethz.ch</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/Edu/ALPS</move>
        </action-list>
    </rule>
    <rule name="Racjonalista" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">@racjonalista.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Serwisy/Racjonalista</move>
        </action-list>
    </rule>
    <rule name="Forum SMP" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">forum@smp.if.uj.edu.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/Forum</move>
        </action-list>
    </rule>
    <rule name="lastfm" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">no-reply@mailer.last.fm</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Serwisy/lastfm</move>
        </action-list>
    </rule>
    <rule name="ENEMEF" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">@enemef.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Serwisy/ENEMEF</move>
        </action-list>
    </rule>
    <rule name="AV Theta" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">DrWeb-DAEMON &lt;av-daemon@uj.edu.pl&gt;</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Spam/ZwrotyAV</move>
        </action-list>
    </rule>
    <rule name="KoloSMP (sporo spamu)" timing="any" enabled="true">
        <condition-list bool="or">
            <match-to-or-cc type="contains">vvvv@uj.edu.pl</match-to-or-cc>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/vvvv</move>
        </action-list>
    </rule>
    <rule name="O2 spam" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="Sender">info@o2.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Spam/SpamReczny</move>
        </action-list>
    </rule>
    <rule name="Marcin" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xazkajhd@xxxx.xx</match-header>
            <match-header type="contains" name="From">xazkajhd@xxxx.xxxx</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Ludzie/Marcin</move>
        </action-list>
    </rule>
    <rule name="Andrzej" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">andrzej@xxxx.xx</match-header>
            <match-header type="contains" name="From">xxxxx.xxxx@xxxx.xx</match-header>
            <match-header type="contains" name="From">xxxxx.xxxxx@xxxx.xx</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Ludzie/Andrzej</move>
        </action-list>
    </rule>
    <rule name="zajecia" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">zxczxc.zxczxc@xx.ccc.pl</match-header>
            <match-header type="contains" name="From">fas@cc.vv.ccc.pl</match-header>
            <match-header type="contains" name="From">zxczv@tcc.vv.ccc.pl</match-header>
            <match-header type="contains" name="From">asdk@jacc.vv.ccc.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/Zajecia</move>
        </action-list>
    </rule>
    <rule name="Piotr" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xxxxr@xxxxxxxx.eu</match-header>
            <match-header type="contains" name="From">xxxxr.xxxxxxxx@uxxxxs.xx</match-header>
            <match-header type="contains" name="From">xxxxxxxx@xxx.xx.xx.xxx.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Ludzie/Piotr</move>
        </action-list>
    </rule>
    <rule name="Ludzie z SMP" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xxxxxxxx@xxxxx.com</match-header>
            <match-header type="contains" name="From">xxxxxxxx@xxx.xx.xx.xxu.pl</match-header>
            <match-header type="contains" name="From">xxxxx.xxxxxxxxxi@xxxxa.fr</match-header>
            <match-header type="contains" name="From">xxxxxxxxxxxxxxxx@xxxx.pl</match-header>
            <match-header type="contains" name="From">xxxxxx-xxx@xx.pl</match-header>
            <match-header type="contains" name="From">xxxxx@xx.xx.xxx.pl</match-header>
            <match-header type="contains" name="From">xxxxxxxxx@xxxxx.com</match-header>
            <match-header type="contains" name="From">xxxxx@xxxxxx.fm</match-header>
            <match-header type="contains" name="From">xxxxxxx@xxxxxxx.org</match-header>
            <match-header type="contains" name="From">xxxxxxx@xxx.xx.ux.xxx.pl</match-header>
            <match-header type="contains" name="From">xxxxxx.xxxxxxa@xxxx.xx</match-header>
            <match-header type="contains" name="From">xxxxxx@xxxxxx.fm</match-header>
            <match-header type="contains" name="From">xxxx@sxx.xx.xx.xxu.pl</match-header>
            <match-header type="contains" name="From">xxxxx@x-xx.xxxxxx.pl</match-header>
            <match-header type="contains" name="From">xxxxxxxx@xxxxx.com</match-header>
            <match-header type="contains" name="From">xxxxxu@xxxxx.com</match-header>
            <match-header type="contains" name="From">xxxxxxx@smp.xx.xx.xxu.pl</match-header>
            <match-header type="contains" name="From">xxxxxxxxxx@xxx.xx.xx.xxu.pl</match-header>
            <match-header type="contains" name="From">xxxxxxxxxxx@xx.pl</match-header>
            <match-header type="contains" name="From">xxxxx@xxx.xx.xx.xxu.pl</match-header>
            <match-header type="contains" name="From">xxxxxxa@xx.pl</match-header>
            <match-header type="contains" name="From">xxxxxxx@xxx.xx.xx.xxu.pl</match-header>
            <match-header type="contains" name="From">xxx@xx.xx.xx.xxu.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP</move>
        </action-list>
    </rule>
    <rule name="aw" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">newbeta@astrowars.com</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/Astrowars</move>
        </action-list>
    </rule>
    <rule name="kolo rosji" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">wkolorosji@gmail.com</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/SMP/KoloSMP</move>
        </action-list>
    </rule>
    <rule name="Kuba" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xxxx@xx.xx.xxx.xx</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Ludzie/Kuba</move>
        </action-list>
    </rule>
    <rule name="D" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xxxxxxx@xxxxx.com</match-header>
            <match-header type="contains" name="From">xxxxxxxx@xxxxxx.edu</match-header>
            <match-header type="contains" name="From">d-bugzilla-admin-daemon@puremagic.com</match-header>
            <match-header type="contains" name="From">Charles &lt;xxxxxxxxxxxx@xxxxxxxxk.net&gt;</match-header>
            <match-header type="contains" name="From">d-bugmail@puremagic.com</match-header>
            <match-header type="contains" name="From">wxxxxxxer@gxxxx.com</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Informatyka/D</move>
        </action-list>
    </rule>
    <rule name="Praca" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">@xxxxxx.xxxx.pl</match-header>
            <match-header type="contains" name="From">@xxxxxxxx.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Praca></move>
        </action-list>
    </rule>
    <rule name="Kasia2" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">xxxxx_xxxx@xx.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Ludzie/Kasia2</move>
        </action-list>
    </rule>
    <rule name="mbank" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">kontakt@mbank.pl</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Podejrzane</move>
        </action-list>
    </rule>
    <rule name="bugzilla.gnome.org" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="From">bugzilla-daemon@bugzilla.gnome.org</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Debian/Bugs</move>
        </action-list>
    </rule>
    <rule name="rkhuner" timing="any" enabled="true">
        <condition-list bool="or">
            <match-header type="contains" name="Subject">[rkhunter] Daily run</match-header>
        </condition-list>
        <action-list>
            <move>#imap/SMP/INBOX/Adminowanie/rkhunter</move>
        </action-list>
    </rule>
</filter>

przy użyciu

$ saxonb-xslt -s:./filter.xml -xsl:./sylpheeed_to_mailfilter.xsl

orzymujemy:

<?xml version="1.0" encoding="UTF-8"?>
# Filtry

# spamcop
if (/^From:.*spamcop\.net./:h) {
	exception {
		to "./Maildir/.Adminowanie/"
	}
			
}

# spam
if (/^Subject:.*\[SPAM/:h) {
	exception {
		to "./Maildir/.Spam/"
	}
			
}

# reczny spam
if (/^[^:]+:.*is listed/:h) {
	exception {
		to "./Maildir/.Spam.SpamReczny/"
	}
			
}

# spoj
if (/^From:.*potyczki_algorytmiczne@adbglobal\.com/:h
 || /^From:.*contact@spoj\.sphere\.pl/:h) {
	exception {
		to "./Maildir/.Informatyka.SPOJ/"
	}
			
}

# allegro
if (/^From:.*@allegro\.pl/:h
 || /^From:.*@smtp2\.allegro\.pl/:h) {
	exception {
		to "./Maildir/.Serwisy.Allegro/"
	}
			
}

# astro4u
if (/^From:.*"Astro-Forum\.org" .adam@procreative\.pl./:h
 || /^From:.*"Astronomia Amatorska" .r\.ambrozy@pkab\.com\.pl./:h) {
	exception {
		to "./Maildir/.Serwisy.Astro/"
	}
			
}

# Bledy poczty
if (/^Subject:.*Mail delivery failed: returning message to sender/:h) {
	exception {
		to "./Maildir/.AAA_Bledy/"
	}
			
}

# Admin SMP LogSec
if (/^From:.*logcheck@smp\.if\.uj\.edu\.pl/:h
 &amp;&amp; /^Subject:.*Security Events/:h) {
	exception {
		to "./Maildir/.Adminowanie.Admin SMP Security/"
	}
			
}

# Admin LogSys
if (/^From:.*logcheck@smp\.if\.uj\.edu\.pl/:h
 || /^From:.*logcheck@mpi\.int\.pl/:h) {
	exception {
		to "./Maildir/.Adminowanie.System Events/"
	}
			
}

# Admin MPI LogSec
if (/^From:.*logcheck@mpi\.int\.pl/:h
 &amp;&amp; /^Subject:.*Security Events/:h
 &amp;&amp; /^To:.*postmaster@smp\.if\.uj\.edu\.pl/:h) {
	exception {
		to "./Maildir/.Adminowanie/"
	}
			
}

# Admin SMP Cron
if (/^From:.*root@smp\.if\.uj\.edu\.pl (Cron Daemon)/:h) {
	exception {
		to "./Maildir/.Adminowanie.Admin SMP Cron/"
	}
			
}

# Admin MPI Arpwatch
if (/^From:.*arpwatch@mpi\.int\.pl (Arpwatch paul\.mpi\.int\.pl)/:h) {
	exception {
		to "./Maildir/.Adminowanie.Admin MPI Arpwatch/"
	}
			
}

# Administracja
if (/^To:.*root@smp\.if\.uj\.edu\.pl/:h
 || /^To:.*root@mpi\.int\.pl/:h
 || /^To:.*root@localhost/:h
 || /^From:.*root@mpi\.int\.pl/:h
 || /^From:.*root@smp\.if\.uj\.edu\.pl/:h
 || /^From:.*Cron Daemon/:h
 || /^Subject:.*Cron .root@/:h) {
	exception {
		to "./Maildir/.Adminowanie/"
	}
			
}

# mysql
if (/^From:.*root@smp\.if\.uj\.edu\.pl/:h
 || /^Subject:.*WARNING: mysqlcheck has found corrupt tables/:h) {
	exception {
		to "./Maildir/.Adminowanie/"
	}
			
}

# Debian
if (/^To:.*debian-user-polish@lists\.debian\.org/:h
 || /^To:.*@bugs\.debian\.org/:h
 || /^List-Id:.*lists\.debian\.org/:h
 || /^From:.*automat@debian\.linux\.pl/:h
 || /^From:.*@bugs\.debian\.org/:h) {
	exception {
		to "./Maildir/.Debian/"
	}
			
}

# Gniazdo
if (/^List-Id:.*gniazdo\.smp\.if\.uj\.edu\.pl/:h) {
	exception {
		to "./Maildir/.SMP.Gniazdo/"
	}
			
}

# TopCoder
if (/^From:.*@topcoder\.com/:h) {
	exception {
		to "./Maildir/.Informatyka.TopCoder/"
	}
			
}

# Nexenta
if (/^List-Id:.*gnusol-devel\.lists\.sonic\.net/:h
 || /^From:.*@gnusolaris\.org/:h
 || /^(To|Cc):.*@gnusolaris\.org/:h
 || /^(To|Cc):.*@nexenta\.org/:h
 || /^From:.*@nexenta\.org/:h
 || /^List-Id:.*gnusol-changes\.lists\.sonic\.net/:h) {
	exception {
		to "./Maildir/.Informatyka.Nexenta/"
	}
			
}

# Mama
if (/^From:.*jolnow26@wp\.pl/:h) {
	exception {
		to "./Maildir/.Ludzie.Mama/"
	}
			
}

# ALPS
if (/^List-Id:.*mailman\.phys\.ethz\.ch/:h
 || /^List-Id:.*comp-phys-alps-users\.phys\.ethz\.ch/:h) {
	exception {
		to "./Maildir/.SMP.Edu.ALPS/"
	}
			
}

# Racjonalista
if (/^From:.*@racjonalista\.pl/:h) {
	exception {
		to "./Maildir/.Serwisy.Racjonalista/"
	}
			
}

# Forum SMP
if (/^From:.*forum@smp\.if\.uj\.edu\.pl/:h) {
	exception {
		to "./Maildir/.SMP.Forum/"
	}
			
}

# lastfm
if (/^From:.*no-reply@mailer\.last\.fm/:h) {
	exception {
		to "./Maildir/.Serwisy.lastfm/"
	}
			
}

# ENEMEF
if (/^From:.*@enemef\.pl/:h) {
	exception {
		to "./Maildir/.Serwisy.ENEMEF/"
	}
			
}

# AV Theta
if (/^From:.*DrWeb-DAEMON .av-daemon@uj\.edu\.pl./:h) {
	exception {
		to "./Maildir/.Spam.ZwrotyAV/"
	}
			
}

# KoloSMP (sporo spamu)
if (/^(To|Cc):.*vvvv@uj\.edu\.pl/:h) {
	exception {
		to "./Maildir/.SMP.vvvv/"
	}
			
}

# O2 spam
if (/^Sender:.*info@o2\.pl/:h) {
	exception {
		to "./Maildir/.Spam.SpamReczny/"
	}
			
}

# Marcin
if (/^From:.*xazkajhd@xxxx\.xx/:h
 || /^From:.*xazkajhd@xxxx\.xxxx/:h) {
	exception {
		to "./Maildir/.Ludzie.Marcin/"
	}
			
}

# Andrzej
if (/^From:.*andrzej@xxxx\.xx/:h
 || /^From:.*xxxxx\.xxxx@xxxx\.xx/:h
 || /^From:.*xxxxx\.xxxxx@xxxx\.xx/:h) {
	exception {
		to "./Maildir/.Ludzie.Andrzej/"
	}
			
}

# zajecia
if (/^From:.*zxczxc\.zxczxc@xx\.ccc\.pl/:h
 || /^From:.*fas@cc\.vv\.ccc\.pl/:h
 || /^From:.*zxczv@tcc\.vv\.ccc\.pl/:h
 || /^From:.*asdk@jacc\.vv\.ccc\.pl/:h) {
	exception {
		to "./Maildir/.SMP.Zajecia/"
	}
			
}

# Piotr
if (/^From:.*xxxxr@xxxxxxxx\.eu/:h
 || /^From:.*xxxxr\.xxxxxxxx@uxxxxs\.xx/:h
 || /^From:.*xxxxxxxx@xxx\.xx\.xx\.xxx\.pl/:h) {
	exception {
		to "./Maildir/.Ludzie.Piotr/"
	}
			
}

# Ludzie z SMP
if (/^From:.*xxxxxxxx@xxxxx\.com/:h
 || /^From:.*xxxxxxxx@xxx\.xx\.xx\.xxu\.pl/:h
 || /^From:.*xxxxx\.xxxxxxxxxi@xxxxa\.fr/:h
 || /^From:.*xxxxxxxxxxxxxxxx@xxxx\.pl/:h
 || /^From:.*xxxxxx-xxx@xx\.pl/:h
 || /^From:.*xxxxx@xx\.xx\.xxx\.pl/:h
 || /^From:.*xxxxxxxxx@xxxxx\.com/:h
 || /^From:.*xxxxx@xxxxxx\.fm/:h
 || /^From:.*xxxxxxx@xxxxxxx\.org/:h
 || /^From:.*xxxxxxx@xxx\.xx\.ux\.xxx\.pl/:h
 || /^From:.*xxxxxx\.xxxxxxa@xxxx\.xx/:h
 || /^From:.*xxxxxx@xxxxxx\.fm/:h
 || /^From:.*xxxx@sxx\.xx\.xx\.xxu\.pl/:h
 || /^From:.*xxxxx@x-xx\.xxxxxx\.pl/:h
 || /^From:.*xxxxxxxx@xxxxx\.com/:h
 || /^From:.*xxxxxu@xxxxx\.com/:h
 || /^From:.*xxxxxxx@smp\.xx\.xx\.xxu\.pl/:h
 || /^From:.*xxxxxxxxxx@xxx\.xx\.xx\.xxu\.pl/:h
 || /^From:.*xxxxxxxxxxx@xx\.pl/:h
 || /^From:.*xxxxx@xxx\.xx\.xx\.xxu\.pl/:h
 || /^From:.*xxxxxxa@xx\.pl/:h
 || /^From:.*xxxxxxx@xxx\.xx\.xx\.xxu\.pl/:h
 || /^From:.*xxx@xx\.xx\.xx\.xxu\.pl/:h) {
	exception {
		to "./Maildir/.SMP/"
	}
			
}

# aw
if (/^From:.*newbeta@astrowars\.com/:h) {
	exception {
		to "./Maildir/.SMP.Astrowars/"
	}
			
}

# kolo rosji
if (/^From:.*wkolorosji@gmail\.com/:h) {
	exception {
		to "./Maildir/.SMP.KoloSMP/"
	}
			
}

# Kuba
if (/^From:.*xxxx@xx\.xx\.xxx\.xx/:h) {
	exception {
		to "./Maildir/.Ludzie.Kuba/"
	}
			
}

# D
if (/^From:.*xxxxxxx@xxxxx\.com/:h
 || /^From:.*xxxxxxxx@xxxxxx\.edu/:h
 || /^From:.*d-bugzilla-admin-daemon@puremagic\.com/:h
 || /^From:.*Charles .xxxxxxxxxxxx@xxxxxxxxk\.net./:h
 || /^From:.*d-bugmail@puremagic\.com/:h
 || /^From:.*wxxxxxxer@gxxxx\.com/:h) {
	exception {
		to "./Maildir/.Informatyka.D/"
	}
			
}

# Praca
if (/^From:.*@xxxxxx\.xxxx\.pl/:h
 || /^From:.*@xxxxxxxx\.pl/:h) {
	exception {
		to "./Maildir/.Praca&gt;/"
	}
			
}

# Kasia2
if (/^From:.*xxxxx_xxxx@xx\.pl/:h) {
	exception {
		to "./Maildir/.Ludzie.Kasia2/"
	}
			
}

# mbank
if (/^From:.*kontakt@mbank\.pl/:h) {
	exception {
		to "./Maildir/.Podejrzane/"
	}
			
}

# bugzilla.gnome.org
if (/^From:.*bugzilla-daemon@bugzilla\.gnome\.org/:h) {
	exception {
		to "./Maildir/.Debian.Bugs/"
	}
			
}

# rkhuner
if (/^Subject:.*\[rkhunter\] Daily run/:h) {
	exception {
		to "./Maildir/.Adminowanie.rkhunter/"
	}
			
}

Pozostaje tylko usunąć pierwszą linijkę (użycie sed'a pozostawiam jako prostę ćwiczenię) i wstawić w miejscę oznaczone ”## TUTAJ DODATKOWE” z skryptu z początku strony.

Dokładne zastosowanie tak skonwertowanego pliku zależy od osobistych potrzeb. Warto zaznajomić się dokładnie z dokumentacją: http://www.courier-mta.org/maildrop/maildropfilter.html

Szczególnie polecenie „include” jest warte użycia :)

Zakończenie

Po zastosowaniu tych technik nagle moja poczta stała się nudna. Wszystko samo ląduje w odpowiednich katalogach, a SPAM widzę może kilka razy na tydzień (i tak 100 razy więcej ląduje dzięki filtrom w koszu). SPAM który jednak widzę natychmiast zaznaczam w Sylpheed'zie i nigdy drugi raz spamerzy już mnie nie nabiorą. :)

Z cyklu w Gry czasie i przestrzeni

Pamiętając o Portalu, oraz samym wirusowym memie gry Portal, nie trudno było się domyślić, iż spowoduja one powstanie wielu klonów i innych tworów naśladujących pomysły portalowe. Jednym z ciekawszych jest Epsilon.

Jak to na grę związaną, choćby przez Portal, ze światem Half-Life przystało, zabawa jest osadzona w świecie fizyki wysokich energii, a dokładnie akceleratora LHC w CERN (tam gdzie będą powstawać różowe smoki). W sumie gra nie odbiega trudnością od Portal 2D, jednak graficznie prezentuje się świetnie (jak na flash), i ma kilka ciekawych zaułków i zagadek.

Tym razem dziękuje Jackowi za pokazanie mi tej gry. A Wy na kilka dni napewno będziecie mieć zajęcie. :)

A więc już do gry! Poszukiwać bozonu Higgsa, sprawdzać pętle grawitacyjne, liczyć przekroje czynne, tworzyć czarne dziury, portale czy przechodzić do ukrytych wymiarów…

W imię nauki oczywiście. To jakby ktoś myślał że w Kole nie zajmujemy się nauką.

Wcześniejsze wpisy >>

start: PUSH AX; PUSH CX; MOV AX,0; MOV AL,[CS:lastkey]; CMP AL,128; JNAE check_keys_1; SUB AL,128; MOV CL,0; …

Dyskusja

Enter your comment (wiki syntax is allowed):
If you can't read the letters on the image, download this .wav file to get them read to you.
start.txt · ostatnio zmienione: 2008/03/07 02:14 przez baryluk
attribute-east
Recent changes RSS feed Creative Commons License Donate Driven by DokuWiki