We wcześniejszej części obiecałem naskrobać trochę więcej na temat “nowości” na Valhalli (i nie tylko). Dziś kolejna część opisująca zmiany. Będzie trochę od dupy strony bowiem w tym wpisie zakładamy, że serwer pocztowy jest już skonfigurowany. Ale spokojnie i o tym coś tam napiszę w niedługim czasie.

Uwaga – tekst będzie długi i niektórzy mogą go uznać za nudny, kontynuujesz czytanie na własną odpowiedzialność ;)

Jaka idea mi przyświecała w czasie tej gimnastyki? A no stworzyć “własne, niezależne google” ;). Co mi ma tam jakiś admin zaglądać w moje maile czy przeglądać moje rozmowy (tak, wiem i tak się od googla nie uwolnimy póki korzystami z androida, ale to inna para kaloszy). Ogólnie chciałem mieć swój, niezależny, w pełni przeze mnie kontrolowany serwer poczty, komunikator, “chmurę”. Zaplecze już było w końcu i tak płacę za neta i prąd do serwera więc czemu by tego nie wykorzystać do czegoś więcej jak tylko maszynka do sesji irca i backupu?

Instalacja czystego ejabberda pod Gentoo jest debilnie prosta, wystarczają praktycznie 2 polecenia + zmiana 2 linijek w konfigu. Ja jednak miałem troszkę udziwnione wymagania (jak zawsze zresztą). Od Ejabberda wymagałem:

  • pełnej obsługi baz danych MySQL (lub zamienników typy PerconaSQL czy MariaDB). W końcu łatwiej zrobić dump bazy danych niż kombinować z tarem żeby spakować miliony pliczków. Do tego dochodzi “oczywista oczywistość” zwana szybkością działania – nie od dziś wiadomo, że wyciągnięcie danych z bazy jest X razy szybsze niż mielenie po dysku w poszukiwaniu/czytaniu/zapisywaniu plików. Co prawda Ejabberd/Erlang posiadają sterowniki ODBC umożliwiające dostęp do dowolnej bazy (MySQL/PostgreSQL/MSSQL), jednak (te domyślne) zostawiają sporo do życzenia (uciekł mi link o tym ale jak tylko znajdę zaktualizuję info), konieczne więc było zassanie sterowników i patchowanie
  • obsługi mod_logdb – czyli tworzenie archiwum rozmów (po stronie serwera), oczywiście w bazie mysql
  • Jorge – frontend w PHP dla mod_logdb aby można było ładnie przeglądać archiwum przez przeglądarkę
  • serwer XMLRPC – wymagany przez Jorge do uwierzytelnienia użytkownika
  • obsługa SSL z indywidualnym certyfikatem dla każdego vhosta
  • uwierzytelnianie użytkowników na podstawie bazy Postfixa/Dovecota. Jeden login i hasło do poczty i do XMPP (tak jak to jest np na GoogleTalk czy kilku innych serwisach).

Lista życzeń dość długa, ale wbrew pozorom stosunkowo prosta do zrobienia. Jeden minus to taki, że wszystko trzeba pociągnąć ręcznie ze źródeł z gita i svna. Co prawda Gentoo ma w głownym drzewie portage ejabberda w interesującej nas wersji 2.1.x ale wymagane przeze mnie modułu coś nie bardzo chciały z nią współpracować.

Będzie to poradnik z serii “nie tylko dla orłów” dzięki czemu (mam nadzieję) unikniesz, Drogi Czytelniku, problemów przy instalacji i konfiguracji, zwłaszcza w momencie napotkania tajemniczych sformułowań typu: “pobierz źródła XXX i nałóż łatkę YYY”. YYY jakie źródła, w której wersji, jaką łatkę, jak ją nakładać (z jakimi parametrami), skąd tą łatkę wziąć i w której wersji ma być ta łatka. Przed przystąpieniem do instalacji i konfiguracji Ejabberda musimy zaopatrzyć się we wszystkie niezbędne zależności, które zainstalujemy w następujący sposób:

echo "dev-lang/erlang odbc kpoll" >> /etc/portage/package.use
emerge dev-vcs/subversion dev-vcs/git dev-lang/erlang

Na początek przechodzimy do katalogu, w którym będziemy pracować. Jako, że kompiluje ze źródeł i lubię mieć porządek w systemie plików to na katalog roboczy wybrałem /usr/local/src. Pierwszym krokiem będzie pobranie wszystkich niezbędnych źródeł, patchy i dumpa bazy Ejabberda.

git clone https://github.com/processone/ejabberd.git
svn co http://svn.process-one.net/ejabberd-modules/mod_xmlrpc
svn co http://svn.process-one.net/ejabberd-modules/jorge/
svn co http://svn.process-one.net/ejabberd-modules/mysql/ ejabberd_mysql_driver
wget http://www.dp.uz.gov.ua/o.palij/mod_logdb/patch-mod_logdb-2.1.12.diff
wget https://raw.githubusercontent.com/processone/ejabberd-
contrib/master/jorge/mod_logdb/erlang-mysql_userflag.diff
wget -O ejabberddb.sql https://raw.githubusercontent.com/processone/ejabberd/master/sql/mysql.sql

Skoro mamy źródła to przygotujmy je. Zaczniemy od ejabberda. Poleceniem

git branch -a

Sprawdzamy jakie są dostępne wersje w sklonowanym repo i przełączymy się na wersję 2.1.x (w dniu kiedy powstawał ten post była to wersja 2.1.13) i przy okazji patchujemy mod_logdb:

cd /usr/local/src/ejabberd
git checkout remotes/origin/2.1.x/
patch -p0 < /usr/local/src/patch-mod_logdb-2.1.12.diff

Teraz sterowniki jabberda dla mysqla. Zmieniamy rewizje na wskazaną przez autora mod_logdb. Oleg Palij pisze u siebie o rewizji co najmniej 850, ale patch jest przygotowany dla r861 więc na taką się przełączymy. Po zmianie rewizji, nałożymy patcha userflag i skopiujemy wymagane pliki do głównego katalogu ze źródłami Ejabberda.

cd /usr/local/src/ejabberd_mysql_driver
svn update -r 861
cd trunk/src
patch -p0 < /usr/local/src/erlang-mysql_userflag.diff
cp * /usr/local/src/ejabberd/src

OK, sterownik mysql już jest zwarty i gotowy do kompilacji, prawda że nie było trudno? ;) Teraz mod_xmlrpc. Pan Zbyszek Żółkiewski, twórca projektu, wymaga użycia rewizji 772. Zatem do dzieła: zmiana rewizji i skopiowanie niezbędnych plików do katalogu ze źródłami jabberda:

cd /usr/local/src/mod_xmlrpc
svn update -r 772
cp trunk/src/mod_xmlrpc.erl /usr/local/src/ejabberd/src

I znów bezboleśnie mamy to co potrzebujemy. No to skoro już wszystko przygotowane, skopiowane w odpowiednie miejsce to czas skompilować Ejabberda. Znów zapowiada się bułka z masłem:

cd /usr/local/src/ejabberd/src
./configure --enable-odbc
make
make install

W zależności od sprzętu jakim dysponujecie kompilacja będzie trwać od kilkudziesięciu sekund do kilku minut. U mnie make trwało 51sekund. Jeśli wszystko dobrze przekopiowałeś to masz już zainstalowanego Ejabberda.

Teraz pasowałoby go skonfigurować. Domyślnie (tak jak i w tym przypadku) konfig znajduje się w pliku

/etc/ejabberd/ejabberd.cfg

. Pierwszy rzut oka na plik konfiguracyjny może przyprawić o zawrót głowy. Niestety składnia erlanga jest, delikatnie rzecz ujmując, dziwna ale można się przyzwyczaić (podobno). Poniżej mój konfig w którym ustawiony jest mod_xmlrpc, mod_logdb dla kilku vhostów (nie wsyzstkie vhosty, które będziemy serwować muszą mieć archiwum!). Komentarz w pliku konfiguracyjnym zaczyna się od %%.

{loglevel, 2}.
%% W następnej linijce definiujemy vhosty, które ejabberd ma obsługiwać u mnie to na razie 3 domeny
{hosts, ["valhalla.org.pl", "nilfheim.eu","munn.in"]}.
{listen,
[
{5222, ejabberd_c2s, [
starttls,
{access, c2s},
{shaper, c2s_shaper},
{max_stanza_size, 65536}
]},
{5269, ejabberd_s2s_in, [
{shaper, s2s_shaper},
{max_stanza_size, 131072}
]},
{5280, ejabberd_http, [
http_bind,
http_poll,
web_admin
]}
]}.
%% Certyfikaty SSL dla poszczególnych vhostów.
{domain_certfile, "valhalla.org.pl", "/etc/ssl/my_certs/valhalla.org.pl/valhalla-xmpp.pem"}.
{domain_certfile, "nilfheim.eu", "/etc/ssl/my_certs/nilfheim.eu/nilfheim-xmpp.pem"}.
%% 2 następne linijki są dla nas bardzo ważne! Zmieniamy sposób uwirzytelniania przez zewnętrzny program!
%% Oraz podajemy ścieżkę do pliku który ma uwierzytelnić użytkownika
{auth_method, external}.
{extauth_program, "/etc/ejabberd/ejabberd-imap-auth.pl"}.
%% Tutaj określamy paramety połączenia do bazy danych ejabberda, w której będą przechowywane m.in lista kontaktów i vCardy
{odbc_server, {mysql, "localhost", "ejabberd", "ejabberd", "HASŁO"}}.
{odbc_pool_size, 5}.
{shaper, normal, {maxrate, 1000}}.
{shaper, fast, {maxrate, 50000}}.
{max_fsm_queue, 1000}.
{acl, admin, {user, "admin", "valhalla.org.pl"}}.
{acl, local, {user_regexp, ""}}.
{access, max_user_sessions, [{10, all}]}.
{access, max_user_offline_messages, [{5000, admin}, {100, all}]}.
{access, local, [{allow, local}]}.
{access, c2s, [{deny, blocked},
{allow, all}]}.
{access, c2s_shaper, [{none, admin},
{normal, all}]}.
{access, s2s_shaper, [{fast, all}]}.
{access, announce, [{allow, admin}]}.
{access, configure, [{allow, admin}]}.
{access, muc_admin, [{allow, admin}]}.
{access, muc_create, [{allow, local}]}.
{access, muc, [{allow, all}]}.
{access, pubsub_createnode, [{allow, local}]}.
{access, register, [{allow, all}]}.
{language, "en"}.
%% Definiujemy moduły, wraz z ewentualnymi parametrami, które mają być obsługiwane globalnie (dla każdego vhosta).
%%Jedną z ważniejszych zmian dopisanie do modułów mod_last, mod_privacy, mod_private, mod_pubsub, mod_roster, mod_vcard końcówki _odbc
%%(w końcu po to kompilowaliśmy sterowniki mysqla żeby ejabberd korzystał z bazy)
{modules,
[
{mod_adhoc, []},
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
{mod_blocking,[]}, % requires mod_privacy
{mod_caps, []},
{mod_configure,[]}, % requires mod_adhoc
{mod_disco, []},
{mod_http_bind, []},
{mod_last_odbc, []},
{mod_offline_odbc, [{access_max_user_messages, max_user_offline_messages}]},
{mod_ping, []},
{mod_privacy_odbc, []},
{mod_private_odbc, []},
{mod_pubsub_odbc, [
{access_createnode, pubsub_createnode},
{ignore_pep_from_offline, true}, % reduces resource comsumption, but XEP incompliant
{last_item_cache, false},
{plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps
]},
{mod_register, [
{welcome_message, {"Welcome!",
"Hi.\nWelcome to this XMPP server."}},
{ip_access, [{allow, "127.0.0.0/8"},
{deny, "0.0.0.0/0"}]},
{access, register}
]},
{mod_roster_odbc, []},
{mod_shared_roster,[]},
{mod_stats, []},
{mod_time, []},
{mod_vcard_odbc, []},
{mod_version, []},
%% Dodajemy moduł mod_xmlrpc i ustawiamy port, na którym ma nasłuchiwać (ja wybrałem 4560)
{mod_xmlrpc, [{port, 4560}]},
%% konfiguracja modułu mod_logdb.
{mod_logdb, [
{dbs, [
{mysql5, [
{user, "ejabberd"},
{password, "HASŁO"},
{server, "localhost"},
{port, 3306},
{db, "jorge"}
]}
]},
{vhosts, [{"valhalla.org.pl", mysql5},{"nilfheim.eu", mysql5}, {"munn.in", mysql5}] },
{groupchat, none},
{purge_older_days, never},
{dolog_default, true},
{poll_users_settings, 5}
]}
]}.

Zainstalowany i skonfigurowany, mogło by się wydawać że można już odpalić serwer XMPP, ale hola hola! To nie wszystko. Jeśli spróbujesz teraz odpalić ejabberda to powita Cię pięknymi komunikatami w stylu “crash report”. Dlaczego? A no dlatego, że jeszcze nie mamy:

  • utworzonej bazy danych dla ejabberda
  • nie mamy utworzonego użytkownika dla tej bazy
  • nie mamy jeszcze skryptu do uwierzytelniania użykowników!

No to zabierajmy się do roboty. Pobieramy skrypt który będzie nas uwierzytelniał:

wget -O /etc/ejabberd/ejabberd-imap-auth.pl http://allgnu.com/ejabberd-imap-auth.txt
chmod 775 /etc/ejabberd/ejabberd-imap-auth.pl

W pliku zamieniamy linijkę

my $server = 'imap.myemailserver.com';

na

my $server = 'localhost';

. Oczywiście nic nie stoi na przeszkodzie, żeby do autoryzacji wykorzystać jakiś zewnętrzny serwer. Skrypt wymaga kilku modułów perla, więc trzeba je doinstalować (na szczęście wszystkie są dostępne w głównym drzewie portage).

echo -e "dev-perl/Net-IMAP-Simple-SSL ~amd64\ndev-perl/EV ~amd64\ndev-perl/Encode-IMAPUTF7 ~amd64\ndev-perl/Net-IMAP-Simple ~amd64\ndev-perl/DateTime-Format-Natural ~amd64\ndev-perl/boolean ~amd64\ndev-perl/Coro ~amd64\ndev-perl/Net-Server-Coro ~amd64\ndev-perl/Guard ~amd64" >> /etc/portage/package.keywords
emerge dev-perl/Net-IMAP-Simple-SSL

Ejabberd – jest, skrypt do uwierzytelnienia – jest, moduły do perla i ejabberda – są. No to zostały jeszcze tylko do założenia 2 bazy danych, użytkownik dla tych baz i instalacja jorege.

mysql -uroot -p
create database jorge;
create database ejabberd;
create user 'ejabberd'@'localhost' identified by 'HASŁO';
grant all on jorge.* to 'ejabberd'@'localhost';
grant all on ejabberd.* to 'ejabberd'@'localhost';
flush privileges
\q
mysql -uejabberd -pHASŁO -Dejabberd < /usr/local/src/ejabberddb.sql
mysql -uejabberd -pHASŁO -Djorge < /usr/local/src/jorge/trunk/install/jorge.sql

I teraz wreszcie można uruchomić ejabberda

/sbin/ejabberdctl start

skonfigurować klienta i można używać własnego jabbera!

I finito!… No prawie jeszcze jorge. Ale na to poświęcę osobny artykuł. Aktualnie przy ustawieniu zewnętrznego uwierzytelniania jorge ma problemy z logowaniem. Najprawdopodobniej coś się dzieje na linii mod_xmlrpc skrypt do uwierzytelnienia. Jestem już w trakcie rozmów z Panem Zbyszkiem więc jak tylko uda się rozwiązać problem wszytko opiszę.

WykopShare