Organizacja zdalnej pracy dla organizacji SMB na OpenVPN

Sformułowanie zadania

Artykuł opisuje organizację zdalnego dostępu pracowników na produktach z otwartym kodem źródłowym i może być wykorzystany zarówno do budowy całkowicie autonomicznego systemu, jak i okazuje się przydatny do rozszerzenia, gdy w istniejącym komercyjnym systemie występuje niedobór licencji lub jego wydajność okazuje się niewystarczająca.

Celem artykułu jest wdrożenie kompleksowego systemu zapewniania zdalnego dostępu dla organizacji, co jest trochę więcej niż "instalacja OpenVPN w 10 minut".

W rezultacie uzyskamy system, w którym do uwierzytelniania użytkowników będą używane certyfikaty oraz (opcjonalnie) korporacyjny katalog Active Directory. Dzięki temu uzyskamy system z podwójnym czynnikiem weryfikacji - to, co posiadam (certyfikat) i to, co wiem (hasło).

Wskaźnikiem, że użytkownik ma prawo się połączyć, jest jego przynależność do grupy myVPNUsr. Centrum certyfikacji będzie lokalne.

Koszt wdrożenia rozwiązania to tylko niewielkie zasoby sprzętowe i 1 godzina pracy administratora systemu.

Będziemy używać maszyny wirtualnej z OpenVPN i Easy-RSA w wersji 3 na CentOS 7, której na 100 połączeń przypisano 4 vCPU, 4 GiB RAM.

W przykładzie sieć naszej organizacji to 172.16.0.0/16, w której serwer VPN z adresem 172.16.19.123 znajduje się w segmencie 172.16.19.0/24, serwery DNS to 172.16.16.16 i 172.16.17.17, a dla klientów VPN wydzielona jest podsieć 172.16.20.0/23.

Do połączeń zewnętrznych używane jest połączenie przez port 1194/udp, a w DNS dla naszego serwera stworzono rekord A gw.abc.ru.

Kategorycznie nie zaleca się wyłączania SELinux! OpenVPN działa bez wyłączania polityki bezpieczeństwa.

Spis treści

  1. Instalacja systemu operacyjnego i oprogramowania aplikacyjnego
  2. Konfiguracja kryptografii
  3. Konfiguracja OpenVPN
  4. Uwierzytelnianie w AD
  5. Uruchamianie i diagnoza
  6. Wydawanie i unieważnianie certyfikatu
  7. Konfiguracja sieci
  8. Co dalej

Instalacja systemu operacyjnego i oprogramowania aplikacyjnego

Używamy dystrybucji CentOS 7.8.2003. Potrzebujemy zainstalować system operacyjny w minimalnej konfiguracji. Wygodnie jest to zrobić za pomocą kickstart, klonowania wcześniej zainstalowanego obrazu systemu operacyjnego i innych metod.

Po instalacji, przypisaniu adresu do interfejsu sieciowego (zgodnie z zadaniem 172.16.19.123), wykonujemy aktualizację systemu operacyjnego:

$ sudo yum update -y && reboot

Należy również upewnić się, że na naszej maszynie odbywa się synchronizacja czasu.
Aby zainstalować oprogramowanie aplikacyjne, potrzebne są pakiety openvpn, openvpn-auth-ldap, easy-rsa oraz vim jako główny edytor (będzie potrzebne repozytorium EPEL).

$ sudo yum install epel-release
$ sudo yum install openvpn openvpn-auth-ldap easy-rsa vim

Dla maszyny wirtualnej warto zainstalować agenta gościa:

$ sudo yum install open-vm-tools

dla hostów VMware ESXi lub dla oVirt

$ sudo yum install ovirt-guest-agent

Konfiguracja kryptografii

Przechodzimy do katalogu easy-rsa:

$ cd /usr/share/easy-rsa/3/

Tworzymy plik zmiennych:

$ sudo vim vars

zawartości:

export KEY_COUNTRY="PL"
export KEY_PROVINCE="MojeWojewództwo"
export KEY_CITY="MojeMiasto"
export KEY_ORG="ABC Sp. z o.o."
export KEY_EMAIL="admin@abc.pl"
export KEY_CN="allUsers"
export KEY_OU="allUsers"
export KEY_NAME="gw.abc.pl"
export KEY_ALTNAMES="abc-openvpn-server"
export EASYRSA_CERT_EXPIRE=3652

Tutaj opisano parametry dla przykładowej organizacji ABC Sp. z o.o., można je poprawić na rzeczywiste lub zostawić z przykładu. Najważniejsza w parametrach jest ostatnia linia, określająca okres ważności certyfikatu w dniach. W przykładzie użyta została wartość 10 lat (365*10+2 lata przestępne). Wartość tę należy dostosować przed wydaniem certyfikatów dla użytkowników.

Następnie konfigurujemy autonomiczny centrum certyfikacji.

Konfiguracja obejmuje eksport zmiennych, inicjalizację CA, wydanie klucza głównego i certyfikatu CA, klucz Diffiego-Hellmana, klucz TLS oraz klucz i certyfikat serwera. Klucz centrum certyfikacji należy starannie chronić i przechowywać w tajemnicy! Wszystkie parametry przy zapytaniach można pozostawić domyślne.

cd /usr/share/easy-rsa/3/
. ./vars
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa gen-dh
./easyrsa gen-req myvpngw nopass
./easyrsa sign-req server myvpngw
./easyrsa gen-crl
openvpn --genkey --secret pki/ta.key

Na tym główna część konfiguracji mechanizmu kryptograficznego jest zakończona.

Konfiguracja OpenVPN

Przechodzimy do katalogu OpenVPN, tworzymy katalogi pomocnicze i dodajemy link do easy-rsa:

cd /etc/openvpn/
mkdir /var/log/openvpn/ /etc/openvpn/ccd /usr/share/easy-rsa/3/client
ln -s /usr/share/easy-rsa/3/pki/ /etc/openvpn/

Tworzymy główny plik konfiguracyjny OpenVPN:

$ sudo vim server.conf

o następującej treści

port 1194
proto udp
dev tun
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/myvpngw.crt
key /etc/openvpn/pki/private/myvpngw.key
crl-verify /etc/openvpn/pki/crl.pem
dh /etc/openvpn/pki/dh.pem
server 172.16.20.0 255.255.254.0
ifconfig-pool-persist ipp.txt
push "route 172.16.0.0 255.255.255.0"
push "route 172.17.0.0 255.255.255.0"
client-config-dir ccd
push "dhcp-option DNS 172.16.16.16"
push "dhcp-option DNS 172.16.17.17"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append  /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
username-as-common-name
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so /etc/openvpn/ldap.conf

Kilka uwag dotyczących parametrów:

  • jeśli przy wydawaniu certyfikatu podano inne imię — wskaź je;
  • pul adresów podaj zgodnie ze swoimi potrzebami*;
  • tras i serwerów DNS może być jeden lub więcej;
  • 2 ostatnie linijki są potrzebne do realizacji uwierzytelniania w AD.

*Wybrany w przykładzie zakres adresów pozwala na jednoczesne połączenie do 127 klientów, ponieważ wybrana jest sieć /23, a OpenVPN tworzy dla każdego klienta podsieć o masce /30.
W przypadku szczególnej potrzeby port i protokół mogą być zmienione, jednak należy pamiętać, że zmiana numeru portu wiąże się z koniecznością dostosowania SELinux, a użycie protokołu tcp zwiększy narzut, gdyż kontrola dostarczania pakietów tcp już odbywa się na poziomie pakietów enkapsulowanych w tunelu.

**Jeśli uwierzytelnienie w AD nie jest potrzebne, skomentuj je, pomiń następny dział, a w szablonie usuń linię auth-user-pass..

Uwierzytelnianie w AD

Do obsługi drugiego czynnika użyjemy weryfikacji konta w AD.

Potrzebujemy konta w domenie z uprawnieniami przeciętnego użytkownika oraz grupy, której członkostwo będzie określać możliwość połączenia.

Tworzymy plik konfiguracyjny:

/etc/openvpn/ldap.conf

o następującej treści

URL             "ldap://ldap.abc.pl"
        BindDN          "CN=bindUsr,CN=Users,DC=abc,DC=pl"
        Password        b1ndP@SS
        Timeout         15
        TLSEnable       no
        FollowReferrals yes


        BaseDN          "OU=allUsr,DC=abc,DC=pl"
        SearchFilter    "(sAMAccountName=%u)"
        RequireGroup    true
        
                BaseDN          "OU=myGrp,DC=abc,DC=pl"
                SearchFilter    "(cn=myVPNUsr)"
                MemberAttribute "member"

Podstawowe parametry:

  • URL "ldap://ldap.abc.pl" — adres kontrolera domeny;
  • BindDN "CN=bindUsr,CN=Users,DC=abc,DC=pl" — kanoniczna nazwa do wiązania z LDAP (UŻ — bindUsr w kontenerze abc.pl/Users);
  • Password b1ndP@SS — hasło użytkownika do wiązania;
  • BaseDN "OU=allUsr,DC=abc,DC=pl" — ścieżka, z której zaczynamy wyszukiwanie użytkownika;
  • BaseDN "OU=myGrp,DC=abc,DC=pl" — kontener grupy uprawniającej (grupa myVPNUsr w kontenerze abc.pl/myGrp);
  • SearchFilter "(cn=myVPNUsr)" — nazwa grupy uprawniającej.

Uruchamianie i diagnoza

Teraz możemy spróbować włączyć i uruchomić nasz serwer:

$ sudo systemctl enable openvpn@server.service
$ sudo systemctl start openvpn@server.service

Sprawdzanie uruchomienia:

systemctl status openvpn@server.service
journalctl -xe
cat /var/log/messages
cat /var/log/openvpn/*log

Wydawanie i unieważnianie certyfikatu

Ponieważ oprócz samych certyfikatów potrzebne są klucze i inne ustawienia, bardzo wygodnie jest umieścić to wszystko w jednym pliku profilu. Plik ten jest następnie przekazywany użytkownikowi, a profil jest importowany na kliencie OpenVPN. W tym celu stworzymy szablon ustawień oraz skrypt generujący profil.

Do profilu należy dodać zawartość plików certyfikatu głównego (ca.crt) oraz klucz TLS (ta.key).

Przed wydaniem certyfikatów użytkowników nie zapomnij ustawić wymaganego okresu ważności certyfikatów w pliku parametrów. Nie należy ustawiać go zbyt dużego, zalecam ograniczenie do maksymalnie 180 dni.

vim /usr/share/easy-rsa/3/vars

...
export EASYRSA_CERT_EXPIRE=180

vim /usr/share/easy-rsa/3/client/template.ovpn

client
dev tun
proto udp
remote gw.abc.ru 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
verb 3
auth-user-pass


-----BEGIN CERTIFICATE-----
WSTAW SWÓJ CERTYFIKAT CA (ca.crt) TUTAJ
-----END CERTIFICATE-----


key-direction 1

-----BEGIN OpenVPN Static key V1-----
WSTAW SWÓJ KLUCZ TA (ta.key) TUTAJ
-----END OpenVPN Static key V1-----

Uwagi:

  • linie WSTAW SWÓJ… zmieniamy na zawartość swoich certyfikatów;
  • w dyrektywie remote podaj nazwę/adres swojego bramy;
  • dyrektywa auth-user-pass jest używana do dodatkowej zewnętrznej autoryzacji.

W katalogu domowym (lub innym wygodnym miejscu) tworzymy skrypt do żądania certyfikatu i tworzenia profilu:

vim ~/make.profile.sh

#!/bin/bash

if [ -z "$1" ] ; then
 echo Missing mandatory client name. Usage: $0 vpn-username
 exit 1
fi

#Set variables
basepath=/usr/share/easy-rsa/3
clntpath=$basepath/client
privpath=$basepath/pki/private
certpath=$basepath/pki/issued
profile=$clntpath/$1.ovpn

#Get current year and lowercase client name
year=`date +%F`
client=${1,,}
echo Processing $year year cert for user/device $client

cd $basepath

if [  -f client/$client* ]; then
    echo "*** ERROR! ***"
    echo "Certificate $client already issued!"
    echo "*** ERROR! ***"
    exit 1
fi

. ./vars
./easyrsa --batch --req-cn=$client gen-req $client nopass
./easyrsa --batch sign-req client $client

#Make profile
cp $clntpath/template.ovpn $profile

echo "<key>" >> $profile
cat $privpath/$1.key >> $profile
echo "</key>" >> $profile

echo -e "n" >> $profile
openssl x509 -in $certpath/$1.crt -out $basepath/$1.crt

echo "<cert>" >> $profile
cat $basepath/$1.crt >> $profile
echo "</cert>" >> $profile
echo -e "n" >> $profile

#remove tmp file
rm -f $basepath/$1.crt

echo Complete. See $profile file.

cd ~

Nadajemy plikowi uprawnienia wykonawcze:

chmod a+x ~/make.profile.sh

I możemy wydać nasz pierwszy certyfikat.

~/make.profile.sh my-first-user

Revokacja

W przypadku kompromitacji certyfikatu (utrata, kradzież) należy cofnąć ten certyfikat:

cd /usr/share/easy-rsa/3/
./easyrsa revoke my-first-user
./easyrsa gen-crl

Przeglądanie wydanych i odwołanych certyfikatów

Aby wyświetlić wydane i odwołane certyfikaty, wystarczy przejrzeć plik indeksu:

cd /usr/share/easy-rsa/3/
cat pki/index.txt

Wyjaśnienia:

  • pierwsza linia zawiera certyfikat serwera;
  • pierwszy znak
    • V (Valid) — ważny;
    • R (Revoked) — odwołany.

Konfiguracja sieci

Ostatnie kroki — konfiguracja sieci transmisyjnej — routingu i zapór ogniowych.

Zezwolenie na połączenia w lokalnej zaporze ogniowej:

$ sudo firewall-cmd --add-service=openvpn
$ sudo firewall-cmd --add-service=openvpn --permanent

Następnie włączamy routowanie ruchu IP:

$ sudo sysctl net.ipv4.ip_forward=1
$ sudo echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/50-sysctl.conf

W środowisku korporacyjnym z pewnością istnieje podział na podsieci i musimy poinformować router(-y), jak przesyłać pakiety kierowane do naszych klientów VPN. W wierszu poleceń wykonujemy polecenie w stylu (zależy od używanego sprzętu):

# ip route 172.16.20.0 255.255.254.0 172.16.19.123

i zapisujemy konfigurację.

Oprócz tego na interfejsie brzegowego routera, gdzie obsługiwany jest zewnętrzny adres gw.abc.ru, należy zezwolić na przechodzenie pakietów udp/1194.

W przypadku, gdy w organizacji obowiązują surowe zasady bezpieczeństwa, na naszym serwerze VPN konieczne jest również skonfigurowanie zapory. Moim zdaniem, największą elastyczność daje konfiguracja łańcuchów FORWARD w iptables, chociaż ich ustawienie jest mniej wygodne. Trochę więcej na temat ich konfiguracji. W tym celu najwygodniej jest używać „bezpośrednich reguł” — direct rules, przechowywanych w pliku /etc/firewalld/direct.xml. Aktualną konfigurację reguł można sprawdzić w następujący sposób:

$ sudo firewall-cmd --direct --get-all-rule

Przed edytowaniem pliku wykonaj jego kopię zapasową:

cp /etc/firewalld/direct.xml /etc/firewalld/direct.xml.`date +%F.%T`.bak

Przykładowa zawartość pliku wygląda następująco:


  
    -i tun0 -o ens192 -p udp --dport 53 -j ACCEPT
  
    -i tun0 -o eth0 -p tcp -d 172.16.19.200 --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
    -i tun0 -o eth0 -p tcp -d 172.16.19.201 --dport 443 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
  
    -i tun0 -o eth0 -p udp -d 172.16.19.100 --dport 7000 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
  
    -i tun0 -o eth0 -j LOG --log-prefix 'forward_fw '

Wyjaśnienia

Można powiedzieć, że są to zwykłe reguły iptables, inaczej spakowane po wprowadzeniu firewalld.

Interfejs docelowy przy ustawieniach domyślnych to tun0, a zewnętrzny dla tunelu może być inny, np. ens192, w zależności od używanej platformy.

Ostatnia linia służy do rejestrowania odrzuconych pakietów. Aby rejestrowanie działało, w konfiguracji firewalld należy zmienić poziom debugowania:

vim /etc/sysconfig/firewalld
FIREWALLD_ARGS=--debug=2

Zastosowanie ustawień — polecenie firewalld do ponownego odczytu ustawień:

$ sudo firewall-cmd --reload

Odrzucone pakiety można sprawdzić w ten sposób:

grep forward_fw /var/log/messages

Co dalej

Na tym konfiguracja się kończy!

Pozostaje na stronie klienta zainstalować oprogramowanie klienckie, zaimportować profil i połączyć się. Dla systemów Windows dystrybucja jest dostępna na stronie twórcy.

Na koniec podłączamy nasz nowy serwer do systemów monitorowania i archiwizacji, i nie zapominamy regularnie instalować aktualizacji.

Stabilnego połączenia!

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster