Praca po pracy czyli bezpieczny zdalny dostęp do sieci wewnętrznej

Zdalny dostęp do komputera i zasobów zabezpieczonej sieci wewnętrznej, a to wszystko prosto, a jednocześnie zgodnie z dobrymi praktykami bezpieczeństwa? Wydaje się niemożliwe, a jednak się da. Jak to osiągnąć tłumaczy Bartosz Feński aka fEnIo.

Porządnie zabezpieczona sieć komputerowa powinna być odseparowana od świata zewnętrznego tak bardzo, jak to tylko możliwe. I często tak właśnie jest to realizowane. Nawet gdy w sieci jest kilkanaście maszyn, które spełniają przeróżne wyznaczone im role w ramach infrastruktury firmowej, to zazwyczaj jedna maszyna stoi przed tym wszystkim i pełni rolę firewalla, a czasem jednocześnie routera.

Przy założeniu, że polityka wewnątrz firmy nie jest zbyt restrykcyjna, to siedząc przy biurku w pracy do takich maszyn mamy swobodny dostęp. Mogą to być przeróżne wewnętrzne serwisy, bazy danych, serwery plików czy cokolwiek innego, co jest potrzebne do funkcjonowania danego przedsiębiorstwa. Co jednak, gdy po pracy, siedząc już w domowych pieleszach, nadal potrzebujemy połączyć się z którymś serwerem, który z zewnątrz dostępny nie jest?

Postaram się opisać kilka rozwiązań, które można zastosować w takiej sytuacji.

SSH ProxyCommand

Załóżmy najprostszy i, z tego, co się orientuję, dość często spotykany scenariusz. W owej wspomnianej już firmie za firewallem stoi drugi serwer, do którego jest dostęp SSH, ale tylko w ramach lokalnej sieci. Może tak być również w sytuacji, gdy router jednocześnie robi NAT, a adresy serwerów za nim są z prywatnych klas adresowych. Tak więc by się do niego zalogować, musimy się najpierw zalogować na firewalla.

Brzmi znajomo? Ile razy zdarzyło Ci się wykonywać analogiczne jak poniższe polecenia?

laptop$ ssh router
[hasło1]
router$ ssh serwer
[hasło2]
serwer$

Ja robiłem to bardzo często, a skoro coś robi się często, to istnieje spora szansa na to, że dla kogoś powtarzanie tej czynności było na tyle frustrujące, że to zautomatyzował. Tak też się stało w przypadku SSH.

Stwórzmy na maszynie laptop plik konfiguracyjny ~/.ssh/config:

Host serwer
ProxyCommand ssh router nc %h %p 2> /dev/null

By taka konfiguracja zadziałała na maszynie router wymagany jest program netcat, ale w większości dystrybucji znajduje się w pakietach o wysokim priorytecie i zazwyczaj jest już zainstalowany. Jak teraz wygląda połączenie z serwerem?

laptop$ ssh serwer
[hasło1]
[hasło2]
serwer$

Wygenerujmy jeszcze komplet kluczy by darować sobie podawanie tych haseł.

laptop$ ssh-keygen
laptop$ ssh-copy-id router
laptop$ ssh-copy-id serwer

Teraz logowanie wygląda już całkiem przyjemnie:

laptop$ ssh serwer
serwer$

Najfajniejszy jednak w tym wszystkim jest fakt, że wraz z możliwością prostego logowania na maszynie do której publicznego dostępu nie ma, dostajemy również całą gamę usprawnień, które niesie ze sobą samo SSH. Nic nie stoi na przeszkodzie by skorzystać z scp, sshfs, forwardowania X-ów, bądź też zestawić jakiś tunel do innej maszyny przez serwer.

A co w sytuacji analogicznej do poniższej?

laptop -> router1 -> router2 -> ... -> routerN -> serwer

Nie ma przeciwwskazań by w ~/.ssh/config wprowadzić kilkanaście maszyn i zautomatyzować proces logowania nawet, gdy by dostać się do docelowej maszyny, trzeba wcześniej zalogować się na kilkunastu pośredniczących. Po prostu dla każdej z maszyn definiujemy odpowiednie polecenie proxy.

SSH SOCKS

Problem SSH mamy rozwiązany, ale co gdy usługą, do której próbujemy się dostać, jest na przykład serwer WWW? Możemy z maszyny, na którą się dostaliśmy, wykorzystać tekstowe przeglądarki, ale to raczej mało wygodne rozwiązanie.

Możemy również wykorzystać wspomniany już port forwarding, który wraz z zautomatyzowanym logowaniem na różne maszyny jest dość elastycznym rozwiązaniem, ale jednak wymaga wprowadzania dla każdej usługi specjalnych poleceń SSH (lub oczywiście konfiguracji we wspomnianym ~/.ssh/config).

Z pomocą przychodzi nam kolejna funkcja SSH. Potrafi ono pracować jako prosty serwer SOCKS.

laptop$ ssh -D 8080 router
[hasło1]
router$

Jeśli poprzednio wygenerowaliśmy klucze, to oczywiście hasła podawać nie trzeba. Teraz wystarczy w przeglądarce WWW ustawić jako serwer SOCKS localhost oraz port 8080. Wszystkie połączenia będą najpierw tunelowane do maszyny router i dla serwera WWW widoczne tak, jakby były z tej maszyny inicjowane.

Nie wszystkie aplikacje umożliwiają jednak korzystanie z serwerów SOCKS. Ale nawet na to jest lekarstwo w postaci tsocks. To dość prosty program, który za pomocą zmiennej LD_PRELOAD sprawia, że programy korzystają z alternatywnych implementacji funkcji connect(), sendto(), socket() i dzięki temu bez potrzeby ich specjalnego konfigurowania mogą korzystać z serwerów pośredniczących wręcz nieświadomie, jeśli można sobie pozwolić na takie określenie w stosunku do tworów zerojedynkowych.

W pliku konfiguracyjnym tsocks wystarczy właściwie tyle:

server = 127.0.0.1
server_type = 5
server_port = 8080

Teraz aplikacje, które chcemy „oszukać” uruchamiamy w ten sposób:

laptop$ tsocks program_bez_obsługi_socks

Jak widać, z pomocą SSH i prostego programiku możemy dość łatwo zorganizować sobie środowisko pracy z pominięciem ograniczeń wprowadzonych przez firewall. Nie rozwiążemy jednakże w ten sposób wszystkich problemów. Choćby stary, poczciwy protokół FTP z racji tego, że do komunikacji wymaga dwóch portów, w taki sposób oszukany być nie może. Poza tym w momencie, gdy za rzeczonym już firewallem mamy 40 usług na 30 maszynach, to konfiguracja SSH, by umożliwić sobie z nimi kontakt będzie strasznie rozbudowana i trudna w utrzymaniu.

Idealnie byłoby mieć rozwiązanie w którym nasz laptop z pewną klasą adresową po prostu łączy się jakimś kanałem tak, by maszyny docelowe wiedziały, że połączenia przychodzą z zaufanej sieci.

OpenVPN

Z pomocą przychodzi nam OpenVPN. W przeciwieństwie do rozwiązań bazujących na SSH, które pracują w warstwie 7 (aplikacji), OpenVPN pracuje w warstwie 3 (sieciowej) lub nawet 2 (transportowej), więc dla oprogramowania jest zupełnie przeźroczysty. Do tego wszystkiego zapewnia nam uwierzytelnianie oraz szyfrowanie, więc praktycznie nic nie tracimy w stosunku do SSH.

Co prawda od wersji 4.3 również OpenSSH doczekało się możliwości tworzenia tuneli w warstwach 2/3, ale konfiguracja do trywialnych nie należy.

OpenVPN umożliwia tworzenie zaawansowanych konfiguracji i przykładowo połączyć bezpiecznie kilkanaście oddziałów firmy. Ja jednak ograniczę się w tym artykule do zapewnienia dostępu w sytuacji opisanej na początku tego tekstu. Laptop będzie klientem, a na routerze skonfigurowany zostanie serwer VPN.

Zakładam, że pakiet openvpn jest już zainstalowany zarówno na laptopie jak i routerze. Wygenerujmy na routerze klucz, który będzie wykorzystywany do szyfrowania i uwierzytelniania transmisji:

router$ openvpn --genkey --secret /etc/openvpn/static.key

Oraz plik konfiguracyjny /etc/openvpn/server.conf:

dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key

Adresy z klasy 10.8.x wykorzystane będą do zestawienia tunelu. Można oczywiście wykorzystać tutaj również jakieś swoje adresy.

Teraz wystarczy uruchomić serwer:

router$ sudo /etc/init.d/openvpn start

Powinien pojawić się dodatkowy interfejs:

tun0      Link encap:UNSPEC  
HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Do tego musimy jeszcze odblokować w regułkach firewalla port 1194.

Stworzony klucz static.key należy przekopiować również na laptopa, a następnie utworzyć plik konfiguracyjny dla klienta /etc/openvpn/client.conf:

remote adres_routera
dev tun
ifconfig 10.8.0.2 10.8.0.1
secret static.key
route 192.168.0.0 255.255.255.0

Podmieniamy adres_routera na jego faktyczny adres. Opcja route sprawi, że automatycznie w tablicy routingu pojawi się wpis i ruch do tej sieci będzie kierowany do zestawionego tunelu.

Teraz wystarczy na laptopie również uruchomić VPN:

laptop$ sudo /etc/init.d/openvpn start

Spójrzmy w tablicę routingu:

10.8.0.1    0.0.0.0    255.255.255.255 UH  0    0    0 tun0
192.168.0.0 10.8.0.1   255.255.255.0   UG  0    0    0 tun0

Tym sposobem zestawiliśmy najprostszą możliwą konfigurację. Oczywiście, ma ona też swoje wady. Choćby fakt, że gdy taki klucz dostanie się w niepowołane ręce, to każdy jego posiadacz będzie miał dostęp do naszej sieci. OpenVPN posiada dużo bardziej wyrafinowane sposoby uwierzytelniania, choćby proste zabezpieczenie klucza hasłem, ale to już wybiega poza ramy tego artykułu. Zainteresowani jak zawsze mogą zgłębić temat samodzielnie.

Komentarze są prywatnymi opiniami dodających je osób. Prosimy o zachowanie kultury wypowiedzi. Komentarze obraźliwe oraz obniżające poziom serwisu będą usuwane. Więcej w regulaminie komentowania.

18 komentarzy

  1. grzempek 6 stycznia 2010 o godz. 22:29 #

    Zaraz, jesli chodzi o SSH ProxyCommand to identycznego (a prostszego) rozwiązania nie osiągniemy poprzez konfigurację VirtualServers na routerze sprzętowym. Chyba wszsytkie routery posiadają tą opcję. Podanie adresu hosta na NATEM oraz podanie portu usługi "uwalnia" nas na zewnątrz. No chyba, że mówimy o routerze linuksowym..

    • fEnIo 8 stycznia 2010 o godz. 18:03 #

      Oczywiście można z tego skorzystać. Fakt, że opisałem takie metody nie oznacza zakazu stosowania innych ;)

      Opcja o której mówisz w najprostszej wersji sprawia, że wjazd mają wszyscy, a nie koniecznie zawsze tego chcemy.

      pozdr,

      fEnIo

      • grzempek 9 stycznia 2010 o godz. 12:23 #

        No dostęp do serwera wewnętrznego rzeczywiście będą mieli wszyscy, ale wystarczy rzetelnie zbudować politykę bezpieczeństwa na tym serwerze(iptables, restrykcyjna konfiguracja usług) zeby dostęp mialy tylko osoby upoważnione. Twoj przykład routera linuksowego, jest o tyle dobry, że stanowi dodatkową warstwę ochrony, którą można mocno konfigurować. Na routerze sprzętowym też jednak można w ograniczonym zakresie blokować dosŧęp osobom nieupowaznionym (firewall, DMZ )

  2. sk 6 stycznia 2010 o godz. 23:40 #

    skad ty wziales te warstwy ;] cos ci sie pomylilo ladnie.

  3. lukasz 7 stycznia 2010 o godz. 2:27 #

    ssh Proxy tylko można użyć jak ktoś ma odblokowane w pliku konfiguracyjnym ssh logowanie na konto root?

    • fEnIo 8 stycznia 2010 o godz. 18:00 #

      Uprawnienia roota nie są wymagane. Dlatego między innymi użyty został port większy niż 1024.

      pozdr,

      fEnIo

  4. skiter 10 stycznia 2010 o godz. 3:14 #

    Mnie tylko zastanawia takowa rzecz, skoro komputer/serwer jest w pracy, a ja jestem w domu, to po jakiego sie tam pchac? :)

    No ale sa rozne sytuacje, bedac _adminem_, czasami trzeba sie zalogowac … chociaz ja bym to osobiscie olal, pracuje od … do, i za to mi placa, nie za czytanie logow po godzinach ;)

    • grzempek 10 stycznia 2010 o godz. 12:10 #

      Tak tyle ze z takim podejsciem zaden pracodawca nie bedzie chciał cię długo trzymać

    • fEnIo 10 stycznia 2010 o godz. 13:04 #

      Różnie bywa. Ja na przykład czasem pełnię dyżur alarmowy mimo siedzenia w domku. No dobra, kiedyś takie pełniłem. Teraz są młodsi ;)

      Cały mój opis nie powstał dlatego, że po pracy mi się w domu nudzi tylko miał rozwiązywać realny problem i dla mnie jest to często pomocne.

      Nawet żeby sprawdzić grafik na przyszły tydzień VPN mi sie przydaje.

      pozdr,

      fEnIo

      • grzempek 24 stycznia 2010 o godz. 18:57 #

        Nie, no ja się w pełni zgadzam. Sam z chaty mam dostęp do wszystkich serwerów jakich uzywamy. Pisząc "dostęp" chodzi mi o to, że zadałem sobie trud wpisania mojego domowego IP w regułki firewalla tak więc dla mnie dostęp z domu jest kluczowy

        • wolvverine 26 stycznia 2010 o godz. 3:06 #

          i źle zrobiłeś, lepiej skonfigurować poprawnie SSH/VPN niż po IP ograniczać, co zresztą jest miernym zabezpieczeniem.

  5. Xeen 16 stycznia 2010 o godz. 10:40 #

    no dobra dobra. wszedzie jakies tunelowanie SSH, proxy ssh, czy Open VPN. a kiedykolwiek ktos na deibanie uruchomil PPTP? dla Windowsowych klientow jest duzo wyogdniejsze, nie wymaga dodatkowego oprogramowania. ja kilkakrotnie probowalem ogarnac PPTP jednak zawsze konczy sie tak samo, tym samym errorem. OpenVPN fajna rzecz, jednak wolalbym PPTP. ALe gdzie kolwiek pojawia sie artykul o VPN, nikt nigdy nie wspomina o PPTP nawet.

  6. wolvverine 26 stycznia 2010 o godz. 3:03 #

    Może dlatego "Najbardziej rozpowszechniona i jednocześnie zawierająca najwięcej podatności na błędy implementacja protokołu PPTP została opracowana przez firmę Microsoft."

    Lepiej użyć IPsec i np: racoon-na po stronie linux-a.

    • Kiełbasa 5 lutego 2010 o godz. 23:59 #

      Można tez użyć L2TP (xl2tpd) + IPSec, czyli zabezpieczenie przez certyfikaty (niestety na windzie tylko dla komputera nie dla usera) plus logowanie (PAP, CHAP, MS-CHAP ITD) ale to i tak jest lipa, bo są marne możliwości automatycznego tworzenia routingów w Windowsie (dlatego jest to wygodne ale tylko do bardzo prostych zastosowań). Można też użyć klienta Shrew Soft VPN Client po stronie Windowsa, który obsługuje mode config i spiąć to z Racoon czy Pluto po stronie Linuxa. Jak ktoś bardzo chce to można też po stronie Windowsa użyć zasad zabezpieczeń IP i skonfigurować ręcznie tunel IPSec… różne rzeczy można.

  7. Steve 28 maja 2010 o godz. 11:45 #

    Kolega nie doczytal o OSI ;)

(wymagane)
URI
Uwaga! Niektóre komentarze, m.in. te dodane przez niezalogowanych i nowych użytkowników, są ręcznie moderowane. Jeśli Twój komentarz nie ukaże się od razu, nie dodawaj go ponownie, tylko cierpliwie poczekaj na akceptację.

Literówki najlepiej zgłaszać mailem: sirmacik@jakilinux.org!

W komentarzach możesz używać prostych znaczników HTML. Przykłady:
  • Link: <a href="jaklinux.org">Linux dla każdego</a>,
  • Wytłuszczenie: <strong>tekst pogrubiony</strong>,
  • Kursywa: <em>tekst pochylony</em>,
  • Przekreślenie: <del>tekst przekreślony</del>,
  • Kod: <code>printf("blok kodu");</code>,
  • Cytat: <blockquote>cytat</blockquote>
Uwaga: jeśli dodasz nieznany znacznik, będzie on niewidoczny, gdyż system filtruje takie znaczniki.