Czy chciałbyś połączyć się z dowolnego miejsca, najczęściej z otwartej sieci WiFi w mieście, na lotnisku – ze swoją siecią domową ? Virtual Private Network (VPN) to rozwiązanie, które pozwala na zalogowanie się do domowej sieci lokalnej w sposób bezpieczny, ale także pozwala na dostęp do Internetu z naszej sieci lokalnej, co dodatkowo zabezpiecza nas przez problemami z dostępem w publicznych, nieszyfrowanych sieciach WiFi.
Co będzie potrzebne ?
Sprzęt:
- Rapberry Pi (wersja A lub B, czy też B+ albo nawet wersja druga)
- Domowy ruter, który obsługuje Port Forwarding albo Virtual Server czyli praktycznie dowolny
Oprogramowanie:
- Raspbian – czyli standardowa dystrybucja dla Raspberry Pi
- OpenVPN – darmowa wersja serwera dla dystrybucji Rasbian ze standardowego repozytorium
- OpenVPN – klient – dla różnych systemów i urządzeń – Linux, Android, MS Windows etc.
Jak widać – nic wymagającego!
Bezpieczeństwo
Poświęćmy teraz chwilę na uzmysłowienie sobie co powinniśmy wiedzieć o zabezpieczeniu naszego rozwiązania:
- dostęp do Raspberry Pi powinny mieć osoby wyłącznie zaufane (najlepiej tylko Ty)
- dostęp do katalogów w /etc powinien być dla zdrowia – ograniczony do użytkownika z prawami jakiego uruchamiany jest OpenVPN na Raspberry Pi
- Tajny i ważny jest plik z rozszerzeniem .key
- Pliki z certyfikatami kończące się na .crt czy .crs – można rozsyłać emailem, gubić, odwoływać – generować wtedy na nowo etc.
- każde łączące się urządzenie (komputer, smartfon) ma własną parę klucz/certyfikat
Do dzieła!
Logujemy się do naszego raspberry pi przez lokalną konsolę lub ssh i zwyczajowo upewniamy się że jest aktualne:
sudo apt-get update && sudo apt-get upgrade
Teraz instalujemy OpenVPN:
sudo apt-get install openvpn
Wszystkie komendy będziemy praktycznie wykonywać z prawami roota (Administratora), więc sugeruję globalnie wydać:
sudo su -
Następnie przystąpimy do skonfigurowania serwera, ale przede wszystkim – wygenerowania certyfikatów SSL, które pozwolą na zabiezpieczenie połączenia.
Konfigurację i cetryfikaty przechowujemy w /etc, stwórzmy więc zgodnie ze sztuką odpowiedni katalog i skopjujmy przykładowe pliki i skrypty do generacji certyfikatów, które w Raspbianie Wheezy znajdują się w:
cd /etc/openvpn mkdir easy-rsa cp -R /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
W nowszym Jessie, jak zauważa w komentarzach Dom/OloX – katalog z przykładami znajduje się w /usr/share:
cd /etc/openvpn mkdir easy-rsa cp -R /usr/share/easy-rsa/* easy-rsa/
W przykładach do wygenerowania certyfikatu dostaniemy dane z USA. Zapytacie, co? Chodzi tutaj o to, że certyfikat musi mieć informacje o wystawiającym – dzięki czemu przeglądarki, które używają tego samego typu certyfikatów, mogą zaprezentować dane o wystawcy certyfikatu, oraz weryfikować kto go rzeczywiście podpisał. My podpiszem sobie oczywiście sami – w końcu to nasz certyfikat!
Edytujemy dla porządku plik (inaczej wszyscy będziemy z San Francisco…):
sudo nano /etc/openvpn/easy-rsa/vars
Zmiany w miejscach w pliku – dotyczą katalogu z eksportem kluczy, oraz długości klucza asymetrycznego – standardowo w wrześniu 2015 jest to 1024 – ale jeśli jest np: 2048 – to za dużo na mały procesorek Raspberry Pi. Upewniamy się więc, że mamy tam 1024:
export EASY_RSA=”/etc/openvpn/easy-rsa” export KEY_SIZE=1024 export KEY_COUNTRY="US" export KEY_PROVINCE="CA" export KEY_CITY="SanFrancisco" export KEY_ORG="Fort-Funston" export KEY_CN=SerwerOVPN export KEY_ALTNAMES="OVPN"
Kod kraju PL, województwo np: WA i tak dalej – to jest opcjonalne – ale już KEY_CN – należałoby zmienić.
Teraz przygotujmy się do wygenerowania kluczy, uruchamiamy:
cd /etc/openvpn/easy-rsa touch keys/index.txt echo 01 > keys/serial . ./vars # set environment variables ./clean-all
Czas na zbudowanie systemu certyfikującego, uruchamiamy:
./build-ca
W rezultacie, pozostanie odpowiedzieć – potwierdzić ENTER zapisy z pliku vars:
Generating a 1024 bit RSA private key ..........++++++ ..........................++++++ writing new private key to 'ca.key' ----- 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) [PL]
Do katalogu keys trafią pliki ca.key i ca.cert.
Teraz generujemy klucz naszego systemu, komenda:
./build-key-server server
Uwaga – teraz zostaniemy poproszeni o podanie hasła. STOP. Podajemy, ale później będziemy je podawać przy każdym połączeniu. Możemy usunąć to wymaganie i będzie to trochę ukłon w stronę ułatwienia a nie zabezpieczenia, ale… coś za coś!
Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:
Odpowiamy yes na pozostałe pytania i tym razem w katalogu keys pojawią się pliki : server.crt oraz server.key w (/etc/openvpn/easy-rsa/keys/), które to będą podpisane Twoim certyfikatem root.
Teraz budujemy parametry Diffie-Hellmann’a, wymagane do rozmowy pomiędzy serwerem a klientem. Cały proces wymiany jest bardzo ciekawy – polecam poczytać w wolnej chwili https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
./build-dh
To da nam 1024.pem – zmieniamy nazwę na dh1024.pem
Pozostaje teraz zbudować pary dla konkretnego urządzenia:
./build-key client1
…wraz z hasłem do połączenia:
./build-key-pass client1
To już prawie koniec generacji – na koniec wspólny klucz HMAC do TLS:
openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/tls.key
Nasze klucze proponuję skopiować do /etc/openvpn/mojeklucze/
cd /etc/openvpn/easy-rsa/keys mkdir -p /etc/openvpn/mojeklucze cp dh1024.pem /etc/openvpn/mojeklucze cp ca.crt /etc/openvpn/mojeklucze cp server.crt /etc/openvpn/mojeklucze cp server.key /etc/openvpn/mojeklucze cp tls.key /etc/openvpn/mojeklucze
Teraz skonfigurujemy serwer OpenVPN przy użyciu naszych nowych kluczy i certyfikatów.
Tworzymy plik /etc/openvpn/openvpn.conf z następującą zawartościa:
push "redirect-gateway" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 192.168.11.1" server 192.168.22.0 255.255.255.0 dev tun verb 5 proto udp keepalive 10 120 port 1194 dh /etc/openvpn/mojeklucze/dh1024.pem ca /etc/openvpn/mojeklucze/ca.crt cert /etc/openvpn/mojeklucze/server.crt key /etc/openvpn/mojeklucze/server.key user nobody group nogroup persist-key persist-tun status /var/log/openvpn-status.log verb 3 client-to-client log-append /var/log/openvpn
Jeśli popatrzymy na nasz plik, to widać, że będziemy prosić aby po połączeniu, cały ruch wychodzący od klienta do serwera, oczywiście z pominięciem tras statycznych na kliencie – był kierowany przez tunel. Dzięki temu zapewnimy także dostęp do Internetu a nie stracimy połączenia z lokalnymi usługami na kliencie. Jako serwery nazw – podajemy np: popularny rozwiązywacz nazw Google, a jako drugi – nasz domowy, lokalny. Ważna linia to server – który podaje sieć na jakiej zostanie stworzony tunel – wybierzmy coś czego nie używamy nigdzie indziej. Port to 1194 – trzeba będzie pamiętać aby dokonać przeniesienia na ten port usługi (port forwarding) na ruterze głównym (ok, najczęściej jedynym ruterze) w domu – ponieważ na ten port klient zapuka – zróbmy też wyjątek dla niego w ścianie ogniowej naszego rutera (często jest opcja do tego). Łączymy się po UDP jak widać, a nasze klucze mamy po kolei zdefiniowane w plikach, jakie stworzyliśmy – w keys.
Port forwarding
Usługa przekazywania portów z adresu publicznego na prywatny – w większości domowych ruterów nie jest specjalnie skomplikowana w konfiguracji – oto kilka przykładów:
Split-tunnel – bezpieczny dostęp do Internetu przez własny VPN
Aby zapewnić split-tunnel – należy zmienić koniec pliku /etc/rc.local.
U siebie musicie zmienić adres IP – w przykładzie 192.168.11.11 na adres IP Raspberry w Waszej sieci lokalnej, oraz wybrać sieć dla połączenia VPN – tutaj: 192.168.22.0/24
Plik powinien zawierać następujące wpisy:
echo "Enabling routing for proper VPN operation..." echo 1 > /proc/sys/net/ipv4/ip_forward echo "Remote port mapping for VPN service..." iptables -t nat -A INPUT -i eth0 -p udp -m udp --dport 1194 -j ACCEPT echo "SNAT of the VPN addresses to allow split-tunneling..." iptables -t nat -A POSTROUTING -s 192.168.22.0/24 -o eth0 -j SNAT --to-source 192.168.11.11 exit 0
Klient
Czas na konfigurację klienta. Zaczniemy od popularnych Androidów/iOS – a więc urządzeń mobilnych. Pobieramy klienta OpenVPN (uwaga na podróbki!) i po zainstalowaniu – okaze się, że klient chciałby plik .ovpn. A więc – należy go stworzyć:
Przechodzimy więc do konsoli a w pliku jaki stworzymy – zmieniamy IP_ADDRESS_OR_FQDN_OF_THE_SERVER na adres IP naszego serwera OpenVPN:
cd /etc/openvpn/mojeklucze/ echo "client" > client.ovpn echo "verb 4" >> client.ovpn echo "dev tun" >> client.ovpn echo "connect-retry-max 5" >> client.ovpn echo "connect-retry 5" >> client.ovpn echo "resolv-retry infinite" >> client.ovpn echo "proto udp" >> client.ovpn echo "remote IP_ADDRESS_OR_FQDN_OF_THE_SERVER 1194" >> client.ovpn echo "nobind" >> client.ovpn echo "persist-key" >> client.ovpn echo "persist-tun" >> client.ovpn echo "keepalive 10 900" >> client.ovpn echo "inactive 3600" >> client.ovpn echo "set CLIENT_CERT 0" >> client.ovpn echo "<ca>;" >> client.ovpn cat ca.crt | grep -A 100 "BEGIN CERTIFICATE" | grep -B 100 "END CERTIFICATE" >> client.ovpn echo "</ca>" >> client.ovpn echo "<cert>" >> client.ovpn cat client1.crt | grep -A 100 "BEGIN CERTIFICATE" | grep -B 100 "END CERTIFICATE" >> client.ovpn echo "</cert>" >> client.ovpn echo "<key>" >> client.ovpn cat client1.key | grep -A 100 "BEGIN PRIVATE KEY" | grep -B 100 "END PRIVATE KEY" >> client.ovpn echo "</key>" >> client.ovpn
W wyniku otrzymamy plik client.ovpn. Plik należy przeglądnąć, dodać odpowiednio: proto na udp, remote – adres IP lub nazwę gdy używamy zmiennego IP i oraz posiadamy usługę aktualizacji w dynamicznym DNS (DynDNS) – oraz – wpisujemy zakres adresów w server. Usuń odniesienia (jeśli istniały w przykładzie) do plików z ca, cert, key. Gotowy plik przesyłamy i importujemy na naszym urządzeniu.