nginx + ssl

Jakiś czas temu stawiałem wiki, gdzie kolejnym krokiem po tym jak serwis został zablokowany poprzez htaccess było przestawienie całości do pracy z certyfikatem ssl z wykorzystaniem szyfrowania. Konieczność jeżeli mają tam być przechowywane np. hasła rootów.

Certyfikat który podpiąłem jest certyfikatem który sam podpisałem.

generowanie klucza prywatnego

wykonanie następującego polecenia:
openssl genrsa -des3 -out server.key 1024
spowoduje wygenerowanie klucza:
Generating RSA private key, 1024 bit long modulus
.........++++++
..............++++++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

pierwszą wadą tego klucza jest fakt posiadania przez niego hasła, co by oznaczało, że przy każdym restarcie serwera korzystającego z tego klucza, istniała by potrzeba wpisywania tego hasła.

generowanie CSR

Pierwszym elementem prowadzącym do wygenerowania certyfikatu jest wygenerowanie pliku który dopiero potem będzie podpisany przez wcześniej wygenerowany klucz prywatny.

openssl req -new -key server.key -out server.csr

zostaniemy poproszeni o hasło:

Enter pass phrase for server.key:

By potem wypełnić dane:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:PL
State or Province Name (full name) [Some-State]:mazowieckie
Locality Name (eg, city) []:Warszawa
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Firma
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

utworzenie klucza bez hasła

Aby usunąć “wadę” i posiadać klucz bez hasła należy wykonać:
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key

podpisanie CSR’a

Na sam koniec generowania klucza ssl, musimy go podpisać np na rok:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Co daje nam efekt:
Signature ok
subject=/C=PL/ST=mazowieckie/L=Warszawa/O=Firma
Getting Private key

instalacja klucza i certyfikatu

Ponieważ używanym serwerem jest nginx to kopiuję sobie:
cp server.crt /etc/nginx/ssl/cert.pem
cp server.key /etc/nginx/ssl/cert.key
podpinanie do konfiguracji

do konfiguracji dodałem:
listen 443;
ssl on;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;

potem restart i śmiga... prawie.

Okazało się że wiki działa dobrze, ale nie grzeje :D. Całość wiki działa dobrze, oprócz niektórych odnośników. Np. "losowa strona" powoduje przejście na port 80. Kluczem jest zmiana konfiguracji w pliku: LocalSettings.php
$wgServer = "https://serwer...";

Zestawienie VPN’a na serwerze

Założenie miałem bardzo proste.

Jest sobie serwer M który ma mieć tunele z serwerami A i B. Ruch przez tunel ma być skompresowany, a autoryzacja używa certyfikatów SSL.

Pierwszym krokiem było zainstalowanie openvpn’a na wszystkich maszynach, ale ponieważ instalacja szła z pakietów debiana, więc była po prostu nudna, choć samo środowisko w którym rzecz się działa dostarczyło powodów do zastanowienia się. W ramach rozrzucania usług po chrootach, wytworzyłem nowego chroota o dumnej nazwie vpn. Przy okazji grsecurity dał o sobie znać, ponieważ go nie wyłączyłem (jak wyłączyć grsecurity?) to proces zakładanie chroota się nie powiódł.

Po wyłączeniu wszystko poszło jak po maśle i nie było żadnych problemów z dalszą instalacją.

Następnym krokiem jest generacja kluczy. Najprostszym sposobem jest na przygotowanie środowiska jest skopiowanie z katalogu  (podaje cały czas dla ubuntu) :

/usr/share/doc/openvpn/examples/easy-rsa/2.0

w jakąś lokalizację w której łatwo będzie korzystać. Ja przeniosłem ten katalog w takie miejsce:

/etc/openvpn/easy-rsa/

pomijając już “2.0”. W środku znajdziemy narzędzia, które służą do generowania kluczy. Całość zaczynamy od edycji pliku vars, który służy do ustawiania domyślnych wartości dla zmiennych środowiskowych wykorzystywanych w procesie generowania certyfikatów. W moim przypadku uzupełniłem dane związane z wystawiającym oraz zwiększyłem długość klucza do 2048 bajtów, co dokumentacja kwituje krótkim:

Increase this to 2048 if you are paranoid.

Samo generowanie kluczy jest już potem trywialne i sprowadziło się do sekwencji komend:

  • . ./vars – ustawienie zmiennych uwaga na kropkę przed, ja się nadziałem – kilka razy zanim zajarzyłem
  • ./clean-all – przygotowanie katalogu dla kluczy
  • ./build-ca – wygenerowanie klucza CA
  • ./build-key-server <nazwa> – zbudowanie klucza serwera
  • ./build-dh – zbudowanie Diffie Hellman

Kolejną rzeczą potrzebną do zestawienia tunelu zgodnie z założeniami, jest wygenerowanie kluczy dla serwerów, co wykonujemy powtarzając do wyczerpania komendą:

./build-key client1
./build-key client2
...

Do wystartowania nadal konfiguracji serwera, czyli modyfikacja pliku /etc/openvpn/server.conf, który szczęśliwie jest świetnie opisany i na dodatek większości opcji nie dotykam, bo działa na domyślnych. Zmieniam rzeczy związane z konfiguracją:

  • local czyli IP przypisane do tunelu
  • port – żeby na standardowym nie wisiało
  • dev – explicite podaję nazwę device’a żeby się nie losowało, bo ustawianie reguł na firewall’u przy zmieniającej się nazwie interface’u jest możliwe, ale prościej przy zadeklarowanym
  • zmieniam ścieżki do certyfikatów
  • server – wybranie i ustawienie odpowiedniej podsieci dla vpn’a
  • push – zdefiniowanie IP’ków wpychanych klientowi w ramach routingu
  • odkomentowałem comp-lzo w celu zapewnienia kompresji danych w tunelu

Teoretycznie można już wystartować: /etc/init.d/openvpn restart

Start się nie powiódł z powodu błędu z dostępem do /lib/udev/devices/net/tun i nie była to niestety kwestia uprawnień, tylko jak się okazało opcja chroot_deny_mknod nie pozwoliła na dostęp z chroota do tego node’a. Koniec końców chroot został skasowany a openvpn wylądował w głównym systemie.

Kolejna już próba odpalenia servera vpn powiodła się, ale ruch po połączeniu to już nie bardzo. Główną regułą firewall’a jest DROP od której są później wyjątki. I tu przydało się zdefiniowanie nazwy dla interface’u tunelu, bo dzięki temu łatwo dodać regułę: iptables -A INPUT -i tun34 -j ACCEPT dzięki której wszystko co przychodzi z tunelu jest akceptowane.

Kolejne połączenie i wszystko śmiga, czego i Wam życzę.