Statystyki odwiedzin dla wielu serwisów z AWStats

Co prawda na swojej stronie zrobiłem kilka podstawowych statystyk i coś tam sobie loguję do bazy danych, ale gdyby się chwilę zastanowić to przecież to samo robi serwer www – wrzuca do logów każde zapytanie HTTP, kod błędu, nazwę agenta, itd. Dublowanie tych danych nie jest najbardziej optymalne.
Stąd też chwilę pogooglałem i znalazłem świetny Open Source’owy projekt: AWStats, który jest webowym analizatorem logów dla serwerów HTTP, FTP i SMTP.

Instalacja i konfiguracja

Najpierw instalacja, na moim Debianie leci to tak:

sudo apt-get install awstats

Teraz trzeba się chwilę zastanowić nad konfiguracją serwera i celem, który chcemy osiągnąć:

  • czy staty będą dostępne publicznie?
  • czy tylko dla ograniczonego grona zainsteresowanych (np. w pewnej sieci)?
  • a może zabezpieczenie hasłem?

Wiedząc, że AWStats działają jako skrypt CGI wystawianie takiego serwisu “na świat” nie wydaje mi się bezpiecznym rozwiązaniem. Wolę np. skonfigurować serwis tak aby był dostępny tylko w LAN’ie, gdzie mam większą władzę i szybciej poradzę sobie z namierzeniem i zablokowaniem ewentualnego napastnika 😉

Opiszę tylko dwa pierwsze przypadki (jak ktoś chce hasło to szybko znajdzie jak je ustawić) – pierwsza dla leniwych, druga dla ambitnych 😉

Przygotowania

Bez względu na wybraną metodę konfiguracji (leniwą, bądź nie) do działania serwisu potrzebny jest włączony w Apache moduł CGI. Jest tak w domyślnej konfiguracji ale jeśli nie masz pewności to odpal:

a2enmod cgi

Musi też być zdefiniowany katalog ze skryptami CGI z uaktywnioną interpretacją CGI – domyślnie w pliku /etc/apache2/sites-available w pliku default jest poniższa konfiguracja:

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Order allow,deny
    Allow from all
</Directory>

Na potrzeby metody leniwej jest to wystarczająca konfiguracja, dla ambitnych zalecam trochę inne umiejscowienie tego kodu.

Metoda dla leniwych

Ponieważ pakiet AWStats instaluje się przykładową konfiguracją można bardzo szybko uruchomić staty, wystarczy skopiować jeden plik:

cp /usr/share/doc/awstats/examples/apache.conf /etc/apache2/conf.d/awstats

No i tyle 😉

Metoda dla ambitnych

Ambitnym zalecam nieco inną konfigurację: z ograniczeniem dostępu do statystyk wyłącznie z LAN’u i tak samo z dostępem do skryptów CGI. W moim przypadku żaden z wystawianych przezemnie serwisów nie korzysta z CGI, więc udostępnianie tych skryptów wszystkim “zainteresowanym” nie ma sensu.

Proponuję wykorzystać taki lub podobny plik konfiguracyjny dla hosta serwującego statystyki:

<VirtualHost *:80>
        ServerName staty.domena.pl
        ServerAdmin [email protected]

        DocumentRoot /var/www/stats/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/stats/>
                Options -Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order Deny,Allow
                Deny from all
                Allow from 192.168.1.0/24
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order Deny,Allow
                Deny from all
                Allow from 192.168.1.0/24
        </Directory>

        <Directory /var/lib/awstats>
                Options None
                AllowOverride None
                Order Deny,Allow
                Deny from all
                Allow from 192.168.1.0/24
        </Directory>

        Alias /awstats-icon/ /usr/share/awstats/icon/
        <Directory /usr/share/awstats/icon>
                Options None
                AllowOverride None
                Order Deny,Allow
                Deny from all
                Allow from 192.168.1.0/24
        </Directory>

        ErrorLog /var/log/apache2/error.log
        LogLevel warn

        CustomLog /var/log/apache2/access.log combined

	<IfModule mod_rewrite.c>
		RewriteEngine On
		RewriteCond $1 !^$
		RewriteCond %{REQUEST_URI} !.*cgi-bin
		RewriteCond %{REQUEST_URI} !.*awstats.pl
		RewriteRule /(.*)/? /cgi-bin/awstats.pl?config=$1 [PT]
		RewriteRule ^/awstats.pl(.*?) /cgi-bin/awstats.pl$1 [QSA,R,L]
	</IfModule>
</VirtualHost>

Z ważnych rzeczy do personalizacji:

  • ServerName – wpisz swoją nazwę serwisu,
  • Allow from 192.168.1.0/24 – zamień na adres/adresy, które Tobie odpowiadają,
  • mod_rewrite – ostatnich kilka linijek wykorzystuje mod_rewrite do uproszczenia odwołań do statystyk, wystarczy wtedy wpisać adres np. tak: http://staty.domena.pl/nazwa.domeny.ktora.nas.interesuje.pl
  • plik zapisujemy jako /etc/apache2/sites-available/awstats

Teraz zostało nam uaktywnienie site’a:

a2ensite awstats

Część wspólna konfiguracji

Teraz tworzymy katalog na skrypt, który wypisze nam dostępne statystyki:

mkdir /var/www/stats
chown -R www-data:www-data /var/www/stats/

Właściwa konfiguracja AWStats

Pliki konfiguracyjne AWStats znajdują się w katalogu /etc/awstats. Jest ich dokładnie 2 szt.:

  • awstats.conf
  • awstats.conf.local

Plik awstats.conf zawiera przykładową konfigurację wystarczającą do odpalenia statystyk dla pojedynczego hosta. Z kolei plik awstats.conf.local jest miejscem gdzie można wrzucić wspólną konfigurację dla kilku plików hostów.

Jeżeli mamy wiele hostów (a taki przypadek tutaj omawiam) to wygodniej będzie nam wrzucić cały plik awstats.conf do awstats.conf.local i w kolejnych plikach konfiguracyjnych zmieniać tylko parametry rozróżniające poszczególne hosty. Robimy więc tak:

mv /etc/awstats/awstats.conf.local /etc/awstats/awstats.conf.local.orig
mv /etc/awstats/awstats.conf /etc/awstats/awstats.conf.local

Teraz musimy zmienić kilka linijek w pliku awstats.conf.local:

# musimy odszukać i zakomentować poniższe linie

LogFile="/var/log/apache/access.log"
SiteDomain=""
HostAliases="localhost 127.0.0.1"
Include "/etc/awstats/awstats.conf.local"

# w ten sposób

#LogFile="/var/log/apache/access.log"
#SiteDomain=""
#HostAliases="localhost 127.0.0.1"
#Include "/etc/awstats/awstats.conf.local"

# dodatkowo odszukujemy linię
LogFormat=4
# i zamieniamy na
LogFormat=1

Teraz możemy utworzyć pliki konfiguracyjne dla naszych vhostów raptem w kilku linijkach, np.:

LogFile="/var/log/apache2/access.log"
SiteDomain="domena.pl"
HostAliases="www.domena.pl"

Include "/etc/awstats/awstats.conf.local"

Oczywiście trzeba wpisać własną lokalizację pliku access.log. W powyższym przypadku jest to lokalizacja domyślna, wspólna dla wszystkich vhostów – rozróżnienie ruchu do poszczególnych vhostów następuje dzięki podaniu parametrów SiteDomain (podstawowej domeny danej strony) oraz HostAliases (innych domen wskazujących na tego samego vhosta).

Ostatnim elementem jest załadowanie pliku ze wspólną konfiguracją.

Zmiana uprawnień do logów

Aby umożliwić dostęp AWStats do logów serwera Apache musimy wykonać dwie czynności. Na początek zmiana atrybutu dla aktualnego pliku log:

chmod o+r /var/log/apache2/access.log

Później musimy zadbać aby logi po rotacji przez logrotate również zachowywały atrybuty, oraz aby przed rotacją AWStats wygenerowało statystyki, których nie zebrało wcześniej. W tym celu zmieniamy plik /etc/logrotate.d/apache2 tak by wyglądał jak poniżej:

/var/log/apache2/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 644 root adm
        sharedscripts
        prerotate
            /usr/share/doc/awstats/examples/awstats-update
        endscript
        postrotate
                if [ -f /var/run/apache2.pid ]; then
                        /etc/init.d/apache2 restart > /dev/null
                fi
        endscript
}

Przeładowanie konfiguracji Apache

Po tych wszystkich zmianach w konfiguracji musimy zrestartować Apache:

invoke-rc.d apache2 restart

Testy konfiguracji

Aby sprawdzić konfigurację AWStats spróbujemy wejść na stronę:http://staty.domena.pl/cgi-bin/awstats.pl?config=domena.pl

Jeżeli na żadnym z etapów nie popełniliśmy błedu to naszym oczom powinny ukazać się “wspaniałe i upragnione statystyki” 🙂

Jedyną delikatną wadą awstats jest “brzydki” i długi link z cgi w środku… Nieco mnie to irytowało, więc przysiadłem chwilę przy mod_rewrite i przygotowałem regułki (były podane w konfiguracji dla ambitnych), które pozwalają rozpocząć przeglądanie statystyk z uproszczonego linku postaci:

http://staty.domena.pl/domena.pl

Proste, czyste i klarowne, bez zbędnych śmieci.

Co prawda koniec tutora, ale nie koniec samej konfiguracji – poponuję aby przejrzeć przykładowy plik z konfiguracją i zapoznać się z zawartymi tam opcjami.

Konfiguracja backportów na Debianie

Tak się składa, że Debian ze względu na stosunkowo rzadkie wydawanie kolejnych wersji szybko staje się niezbyt świeży a dostępne w nim pakiety często nie spełaniają naszych oczekiwań. Nie ma najnowszej wersji Subversion… Nie ma mod_security itd, itp…

Rozwiązaniem tego problemu może być instalacja pakietów z testowej gałęzi ale można polec na zależnościach. Można też kompilować ze źródeł… Tak czy siak w obu przypadkach aktualizacja i utrzymanie tak zmodyfikowanego systemu byłoby jak wrzód na zadku.

Na szczęście jest prostsze rozwiązanie. System backportów – czyli repozytorium dostarczające możliwie najnowsze wersje pakietów dla gałęzi stabilnej. Dodając jedno źródło można zainstalować subversion, mod_security i inne, a przy tym równocześnie nie rozwalić sobie systemu.

Konfiguracja – Squeeze

Najpierw trzeba dodać dodatkowe źródło pakietów:

echo "deb http://backports.debian.org/debian-backports \
squeeze-backports main contrib non-free" >> /etc/apt/sources.list

Konfiguracja – Lenny

Najpierw trzeba dodać dodatkowe źródło pakietów:

echo "deb http://backports.debian.org/debian-backports \
lenny-backports main contrib non-free" >> /etc/apt/sources.list

Ponadto w Lennym dostępne jest drugie repozytorium backportów tzw. lenny-backports-sloppy – to repozytorium nie gwarantuje bezproblemowej aktualizacji do Squeeze’a ale powinny się tam znaleźć nowsze wersje pakietów niż w przypadku podstawowego repo.

Dodatkowym krokiem w przypadku Lennego, aczkolwiek zalecanym jest ustawienie tzw. pinningu dla backportów, aby pakiety zainstalowane z nich były aktualizowane. Robimy to wklepując:

echo "Package: *" >> /etc/apt/preferences
echo "Pin: release a=lenny-backports" >> /etc/apt/preferences
echo "Pin-Priority: 200" >> /etc/apt/preferences

Odświeżanie repozytoriów

Teraz odświeżamy repozytoria:

apt-get update

Instalacja pakietów z backportów

Instalacja pakietów z backportów wymaga wymuszenia ich użycia, dzięki czemu jedynie wybrane przez nas pakiety zostaną zainstalowane w nowszych wersjach. Robimy to przykładowo tak:

apt-get -t squeeze-backports install subversion

lub

apt-get -t lenny-backports install subversion

To tyle. Możemy korzystać z aktualnych wersji paczek.

JPGraph, wykresy z PHP’a

Onego czasu próbowałem znaleźć coś co ułatwiłoby mi rysowanie prostych wykresów w PHP’ie inaczej niż z palca w GD. Kumpel polecił mi JPGraph.

JPGraph to świetna sprawa, do generowania statystyk jak chociażby na mojej stronie, ale biblioteka potrafi dużo więcej…

Załóżmy, że ze stronki zbieramy do bazy takie rzeczy jak: datę, adres IP, ilość połączeń z tego adresu. Prosta tabela (przykład w Postgre SQL’u):

CREATE TABLE wizyty
(
  pid serial NOT NULL,
  "data" date NOT NULL DEFAULT ('now'::text)::date,
  odslony integer NOT NULL DEFAULT 1,
  CONSTRAINT visits_pkey PRIMARY KEY (id)
);

Dane z takiej tabeli można łatwo wyciągnąć jednym select’em:

SELECT date_part('day', "data") AS x, sum(odslony) AS y
FROM wizyty
WHERE date > ('today'::date - '30 days'::interval)
GROUP BY "data"
ORDER BY "data"
LIMIT 30

Powyższe zapytanie wyciągnie nam z kolumny z datą tylko dzień miesiąca, który posłuży za etykietę (oś X) oraz sumę odsłon z danego dnia (oś Y), posortowane według daty i tylko z ostanich 30 dni.

W zależności od sposobu dostępu i pobierania wyników, trzeba je ładnie zapisać w dwóch tablicach. Ja to robię w prostej pętli:

foreach ($query->result() as $row) {
	$x[] = $row->x;
	$y[] = $row->y;
}

Mając dane została zabawa z ustawieniem oczekiwanych opcji wykresu:

/* bez tego ani rusz */
include_once 'jpgraph/jpgraph.php';
include_once 'jpgraph/jpgraph_bar.php';

/* szerokość */
$width = 400;

/* wysokość */
$height = 300;

$graph = new Graph($width, $height);

/* oś X tekst, oś Y wartości całkowite */
$graph->SetScale("textint");

/* kolorowa ramka */
$graph->SetFrame(true, '#222222');
$graph->SetMarginColor('#222222');

/* tytuł wykresu, trochę konfiguracji fontów i kolorów */
$graph->title->Set('Sumaryczna liczba odsłon');
$graph->title->SetFont(FF_VERDANA,FS_BOLD,10);
$graph->title->SetColor('#999999');

/* podobnież jak powyżej dla osi X */
$graph->xaxis->SetFont(FF_VERDANA,FS_NORMAL,8);
$graph->xaxis->SetColor('#999999');
$graph->yaxis->SetFont(FF_VERDANA,FS_NORMAL,8);
$graph->yaxis->SetColor('#999999');

/* dodatkowe ozdobniki ;) */
$graph->yscale->ticks->SupressZeroLabel(false);
$graph->yscale->ticks->SetColor('#999999');
$graph->xaxis->SetTickLabels($x);

/* genrujemy właściwy wykres, w tym przypadku słupkowy */
$bplot = new BarPlot($y);
$bplot->SetWidth(0.6);
$bplot->SetFillColor('#[email protected]');
$bplot->SetColor('gray');

/* dodajemy wykres do obiektu $graph (który to może pomieścić
i wyświetlić wiele wykresów, co z resztą pokazane jest poniżej) */
$graph->Add($bplot);

/* teraz wykres liniowy */
$lplot = new LinePlot($y);

/* z wypełnieniem pod wykresem */
$lplot->SetFillColor('[email protected]');
$lplot->SetColor('[email protected]');
$lplot->SetBarCenter();

/* typ znacznika na łącznikach pomiędzy kolejnymi słupkami */
$lplot->mark->SetType(MARK_SQUARE);
$lplot->mark->SetColor('[email protected]');
$lplot->mark->SetFillColor('lightblue');
$lplot->mark->SetSize(6);

/* wrzucamy kolejny wykres do obrazu */
$graph->Add($lplot);

/* a teraz magia... */
$graph->Stroke();

Co to robi… Ano dokładnie taki wykres jak ten poniżej:

 

allvisits

Co prawda ten wykres nie odpowiada w 100% podanemu źródłu. To statystyka z mojej strony, która niebieską linią zaznacza volumen pobranych danych – przykład jest nieco uproszczony.

Na pierwszy rzut oka powyższy skrypt wydaje się dość długi i jest tam dużo nie do końca jasnych opcji, ale najfajniejsze jest to, że tak na prawdę nie trzeba się tego uczyć. Biblioteka domyślnie dostarczana jest z masą przykładów. Wystarczy wybrać wykres podobny do tego, który sami chcemy zrobić – skopiować większość kodu. Znaleźć inne wykresy, których cechy chcemy powielić i po kilku próbach skleimy takiego Frankenstein’a jakiego świat nie widział wcześniej ;-D

Mój wykres akurat ma trochę zmieniony kolor tła ramki i fonty, tak aby lepiej wkomponował się w moją stronę – reszta bazuje na dwóch przykładach z dokumentacji. Na zrobienie pierwszego wykresu z wykorzystaniem JPGraph potrzebowałem ok. godziny. Teraz wystarcza mi 10 minut 🙂

 

Dynamiczne IP i RBL’e

Mój serwer pocztowy działa od jakiegoś czasu na dynamicznym IP (dobre bo tanie…) i przeważnie nie ma z tym problemów. Postarałem się jak mogłem ustawiając SPF’a i DomainKeys aby uwiarygodnić go u większych dostawców poczty.

Niestety wszystko to diabli biorą w momencie gdy wygasa mi leasse DHCP i dostaję nowe IP po jakimś spamerze/zombiaku. Wisi takie w 2-3 większych RBL’ach i o dostarczaniu poczty można zapomnieć. Miło gdy jeszcze zdalny MTA zechce odesłać zwrotkę “zróbta coś bo wisisz w RBL’u takim a takim…”, ale zdecydowania niefajnie gdy wysyłasz pocztę a ona od razu leci do /dev/null 🙁

rblcheck

Poszperałem trochę i znalazłem fajne narzędzie aka rblcheck, które sprawdza domyślnie kilka RBL’i. Można też dodać kolejne jako parametry. Wygląda to mniej więcej tak:

$ rblcheck 89.76.116.114
89.76.116.114 not listed by sbl.spamhaus.org
89.76.116.114 not listed by xbl.spamhaus.org
89.76.116.114 not listed by pbl.spamhaus.org
89.76.116.114 not listed by bl.spamcop.net
89.76.116.114 not listed by list.dsbl.org
89.76.116.114 not listed by dnsbl.njabl.org
89.76.116.114 listed by dul.dnsbl.sorbs.net

Jak widać IP wisi w jednym z RBL’i.

Można odpytać RBL’e o konkretny powód znalezienia się na liście (o ile funkcja taka jest obsługiwana):

$ rblcheck 89.76.116.114 -t
89.76.116.114 not listed by sbl.spamhaus.org
89.76.116.114 not listed by xbl.spamhaus.org
89.76.116.114 not listed by pbl.spamhaus.org
89.76.116.114 not listed by bl.spamcop.net
89.76.116.114 not listed by list.dsbl.org
89.76.116.114 not listed by dnsbl.njabl.org
89.76.116.114 listed by dul.dnsbl.sorbs.net: \
Dynamic IP Addresses See: http://www.sorbs.net/lookup.shtml?89.76.116.114

W tym przypadku nie było się czym przejmować. Ta lista zawiera wszystkie IP dynamiczne, więc nic dziwnego że nasze dynamiczne też tam jest. Nawet jeżeli ktoś będzie korzystać z tej listy to raczej nie na zasadzie odcinania się od dynamicznych IP, ale w ramach punktowania wiarygodności danego adresu. Z naszej strony za bardzo nie jesteśmy w stanie nic z tym zrobić (bo nie zamierzamy dopłacić za statyczne IP), więc tak musi być.

Automatyzacja

Najpierw zainstalowałem rblcheck‘a:

sudo apt-get install rblcheck

Później w /usr/local/sbin/check_rbls.sh utworzyłem skrypt sprawdzający kilka interesujących mnie RBL’i:

#!/bin/bash

IP=`host mojadomena.pl | head -n1  | awk '{print $4}'`
RBLCHECK="rblcheck -t -s dul.dnsbl.sorbs.net \
        -s abuse.rfc-ignorant.org \
        -s postmaster.rfc-ignorant.org \
        -s dsn.rfc-ignorant.org \
        -s ix.dnsbl.manitu.net \
        -s rhsbl.ahbl.org"

$RBLCHECK $IP | awk '{if($2 != "not") print $0 }'

Skrypt ten podlinkowałem aby uruchamiał się co godzinę:

ln -s /usr/local/sbin/check_rbls.sh /etc/cron.hourly/

Dzięki temu prostemu skryptowie jeżeli dostanę IP wiszące w tych kilku RBL’ach to stosunkowo szybko (maksymalnie w ciągu godziny) się o tym dowiem. Jeżeli natomiast IP będzie czyste to nie będę dostawać zbędnych maili. Do tego listę sprawdzanych RBL’i można bardzo łatwo powiększyć o kolejne w razie takiej potrzeby.

Certyfikaty SelfSigned

Certyfikaty oparte o SSL stanowią obecnie podstawę bezpieczeństwa wielu usług sieciowych zaczynając od HTTP, przez POPS, IMAPS, itd… Niestety zakupienie certyfikatu w organizacjach jak VeriSgin czy Thawte jest dość kosztowe, a jeżeli potrzebujemy kilka certyfikatów to często na lokalne potrzeby jest to po prostu nie opłacalne.

Postaram się przedstawić wersję “ekonomiczną” certyfikacji 🙂

Generowanie Certificate Signing Request

Pierwszym etapem generowania certyfikatu jest przygotowanie Certificate Signing Request, czyli czegoś w rodzaju “prośby” o certyfikat. Nasza “prośba” po podpisaniu przez centrum autoryzacyjne stanie się certyfikatem.

Do wygenerowania Request’u potrzebny jest najpierw klucz prywatny, który generujemy np. tak:

openssl genrsa -aes256 -out priv.key 4096

Powyższe polecenie poprosi nas dwa razy o hasło, które trzeba zapamiętać (albo zapisać i zamknąć w sejfie) – zalecam wykorzystanie pseudolosowego ciągu znaków o długości minimum 10 znaków.

Po genrsa możemy użyć kilku opcji wybierając w ten sposób algorytm szyfrujący – do wyboru są: des, des3, aes128, aes192, aes256. Ja wybrałem 256-bitowego AES’a – najmocniejszy z tych algorytmów.

Ostatni parametr do długość klucza. Można użyć innej wartości np. 1024. Klucz wygeneruje się szybciej ale będzie prostszy do złamania. Z moich doświadczeń wynika, że niektóre aplikacje mogą mieć problem z obsługą długiego klucza (np. jak użyty w tym przykładzie), wtedy użycie mniejszej wartości może być konieczne (lepsze słabsze zabezpieczenie niż żadne).

Warto ograniczyć uprawnienia do wygenerowanego klucza prywatnego tak by tylko właściciel miał do niego dostęp:

chmod 400 priv.key

Przy okazji tworzenia klucza prywatnego warto wspomnieć, że jeżeli będziemy chcieli go użyć w tak przygotowanej postaci np. w Apache’m to przy każdym starcie Apache będzie nas prosić o podanie hasła odbezpieczającego klucz prywatny. Niby to bezpieczne ale z drugiej strony przez takie zabezpieczenie Apache nie podniesie się samodzielnie np. po awarii. Rozwiązaniem jest przygotowanie odszyfrowanej wersji klucza prywatnego, z której będzie korzystał Apache. Robi się to tak:

openssl rsa -in priv.key -out priv.unsecure.key
chmod 400 priv.unsecure.key

Klucz priv.unsecure.key podany w konfiguracji programu nie będzie wymagał hasła. Koniecznie należy uniemożliwić dostęp do tego pliku wszystkim z wyjątkiem root’a!

openssl req -new -key priv.key -out request.csr

Co dalej?

Ok. Mamy już request’a, warto w tym miejscu wspomnieć co możemy z nim zrobić:

  1. Możemy taki plik przesłać do centrum autoryzacji (CA) celem podpisania i wygenerowania certyfiaktu. Klucze publiczne CA takich jak Thawte, VeriSign, itp są dołączane do przeglądarek internetowych, OS’ów, etc. dzięki temu strony internetowe (bądź inne usługi) zabezpieczone takimi certyfikatami weryfikują się bez żadnej dodatkowej akcji ze strony użytkownika. Warto wziąć pod uwagę to rozwiązanie, jeżeli np. chcemy zabezpieczyć sklep internetowy – my odpuścimy to rozwiązanie ze względu na koszty 🙂
  2. Drugą opcją jest możliwość samodzielnego podpisania certyfikatu tworząc tzw. SelfSigned Certificate. To zalecana opcja jeżeli mamy tylko jedną stronę/usługę. Użytkownik raz doda sobie nasz certyfikat jako zaufany i będzie mógł korzystać z szyfrowania do woli. Metoda ta robi się problematyczna gdy trzeba zarządzać większą liczbą certyfikatów.
  3. Ostatnia opcja to utworzenie własnego CA (czyli specjalnego certyfikatu), którym będziemy podpisywać wygenerowane przez nas Requesty. Ma to tę zaletę, że wystarczy rozdystrybuować klucz publiczny CA i będzie to wystarczające do weryfikacji wszystkich naszych certyfikatów.

Tworzenie certyfikatów SelfSigned

Zaczniemy od prostszej wersji czyli podpiszemy nasz request wygenerowanym przez nas wcześniej kluczem prywatnym tworzac tzw. SelfSigned Certificate. Aby to zrobić potrzebne jest takie polecenie:

openssl x509 -req -days 365 -in request.csr \
 -signkey priv.key -out certificate.crt

Tak oto wygenerowaliśmy certyfikat certificate.crt ważny przez 365 dni (tutaj dowolność ustawień ale 1 rok to sensowny okres).

Właściwości certyfikatu można sprawdzić np. tak:

openssl x509 -noout -text -in certificate.crt

Tworzenie własnego CA

Najpierw należy utworzyć klucz prywatny naszego CA, robi się to dokładnie tak samo jak w przypadku generowanego wcześniej klucza prywatnego dla serwera. Później musimy wygenerować requesta (analogicznie jak w przypadku certyfikatu SelfSigned). Czyli dwa polecenia:

openssl genrsa -aes256 -out ca.key 4096
openssl req -new -x509 -days 365 \
 -key ca.key -out ca.crt

Skoro mamy już certyfikat naszego CA, możemy podpisać wcześniej wygenerowany Request dla serwera:

openssl x509 -req -days 365 -in request.csr -CA ca.crt \
 -CAkey ca.key -set_serial 01 -out certificate.crt

Ogólnie podpisywanie przebiega podobnie jak przy certyfikatach SelfSigned ale jak widać wykorzystywane są klucze naszego CA i pojawia się nowy parametr: set_serial, którego wartość musi być inna dla każdego podpisanego przez to CA certyfikatu. Najprościej aby serial przyjmował numer kolejno wygenerowanego certyfikatu.

Jeżeli wiemy, że będziemy generować więcej tego typu certyfikatów warto przygotować sobie skrypt, który zadba o prawidłową wartość pola serial.

Podsumowanie

Certyfikaty przygotowane w ten sposób można wrzucić do Apache, postfix’a, itd… i w ten sposób szyfrując ruch.