Postawienie zadania
Artykuł opisuje organizację zdalnego dostępu pracowników opartego na produktach open source i może być wykorzystany zarówno do budowy w pełni autonomicznego systemu, jak i do rozbudowy istniejącego systemu komercyjnego, gdy brakuje licencji lub jego wydajność jest niewystarczająca.
Celem artykułu jest wdrożenie kompleksowego systemu zapewnienia zdalnego dostępu dla organizacji, co stanowi nieco więcej niż «instalacja OpenVPN w 10 minut».
W efekcie uzyskamy system, w którym do uwierzytelniania użytkowników będą wykorzystywane certyfikaty oraz (opcjonalnie) korporacyjny katalog Active Directory. Uzyskamy w ten sposób system z podwójną weryfikacją — co posiadam (certyfikat) i co wiem (hasło).
Oznaką, że użytkownik ma prawo do połączenia, jest jego członkostwo w grupie myVPNUsr. Centrum certyfikacji będzie używane autonomicznie.
Koszt wdrożenia rozwiązania to jedynie 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, z 4 vCPU i 4 GiB RAM przydzielonymi na 100 połączeń.
W przykładzie nasza sieć organizacji ma adres 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 przydzielona jest podsieć 172.16.20.0/23.
Do połączeń zewnętrznych używany jest port 1194/udp, a dla naszego serwera w DNS stworzono rekord A gw.abc.ru.
Niezdecydowanie zaleca się wyłączanie SELinux! OpenVPN działa bez wyłączania polityk bezpieczeństwa.
Zawartość
Instalacja systemu operacyjnego i oprogramowania aplikacyjnego
Używamy dystrybucji CentOS 7.8.2003. Potrzebujemy minimalnej konfiguracji do instalacji systemu operacyjnego. Wygodnie jest to robić za pomocą , klonowania wcześniej zainstalowanego obrazu systemu operacyjnego i innych metod.
Po instalacji i przydzieleniu adresu interfejsowi sieciowemu (zgodnie z wymaganiami zadania 172.16.19.123), przeprowadzamy aktualizację systemu operacyjnego:
$ sudo yum update -y && reboot
Należy również upewnić się, że synchronizacja czasu działa na naszej maszynie.
Aby zainstalować oprogramowanie, 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
W przypadku maszyny wirtualnej warto zainstalować agenta gościa:
$ sudo yum install open-vm-toolsdla 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 varso następującej treś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 opisane zostały parametry dla fikcyjnej organizacji "ABC Sp. z o.o.", można je zmienić na rzeczywiste lub pozostawić z przykładu. Najważniejsza w parametrach jest ostatnia linia, określająca czas ważności certyfikatu w dniach. W przykładzie użyto wartości 10 lat (365*10+2 lata przestępne). Tę wartość należy skorygować przed wydaniem certyfikatów użytkowników.
Następnie konfigurujemy autonomiczny centrum certyfikacji.
Konfiguracja obejmuje eksport zmiennych, inicjalizację CA, wydanie klucza korzeniowego oraz certyfikatu CA, klucz Diffiego-Hellmana, klucz TLS, a także klucz i certyfikat serwera. Klucz centrum certyfikacji należy starannie chronić i przechować w tajemnicy! Wszystkie parametry w 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 podstawowa część konfiguracji mechanizmu kryptograficznego została zakończona.
Konfiguracja OpenVPN
Przechodzimy do katalogu OpenVPN, tworzymy katalogi robocze 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.confo 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 inną nazwę — podaj ją;
- zakres adresów dostosuj do swoich potrzeb*;
- może być jeden lub więcej tras i serwerów DNS;
- 2 ostatnie linie są potrzebne do realizacji uwierzytelniania w AD**.
*Wybrany w przykładzie zakres adresów pozwoli na jednoczesne połączenie do 127 klientów, ponieważ wybrano sieć /23, a OpenVPN tworzy dla każdego klienta podsieć o masce /30.
W wyjątkowych przypadkach port i protokół mogą zostać zmienione, jednak należy pamiętać, że zmiana numeru portu pociągnie za sobą konieczność dostosowania SELinux, a użycie protokołu TCP zwiększy obciążenie, ponieważ kontrola dostarczania pakietów TCP jest już realizowana na poziomie pakietów enkapsulowanych w tunelu.
**Jeśli uwierzytelnianie w AD nie jest potrzebne, skomentuj je, a następny rozdział — pomiń, a w szablonie usuń linię auth-user-pass..
Uwierzytelnianie w AD
Aby wspierać drugi czynnik, będziemy korzystać z weryfikacji konta w AD.
Potrzebujemy konta w domenie z uprawnieniami użytkownika ogólnego oraz grupy, której członkostwo będzie definiować możliwość połączenia.
Tworzymy plik konfiguracyjny:
/etc/openvpn/ldap.confo następującej treści
URL "ldap://ldap.abc.ru"
BindDN "CN=bindUsr,CN=Users,DC=abc,DC=ru"
Password b1ndP@SS
Timeout 15
TLSEnable no
FollowReferrals yes
BaseDN "OU=allUsr,DC=abc,DC=ru"
SearchFilter "(sAMAccountName=%u)"
RequireGroup true
BaseDN "OU=myGrp,DC=abc,DC=ru"
SearchFilter "(cn=myVPNUsr)"
MemberAttribute "member"
Główne parametry:
- URL „ldap://ldap.abc.ru” — adres kontrolera domeny;
- BindDN «CN=bindUsr,CN=Users,DC=abc,DC=pl» — kanoniczna nazwa do wiązania z LDAP (Użytkownik — bindUsr w kontenerze abc.pl/Users);
- Hasło b1ndP@SS — hasło użytkownika do wiązania;
- BaseDN «OU=allUsr,DC=abc,DC=pl» — ścieżka, z której rozpoczynamy wyszukiwanie użytkownika;
- BaseDN «OU=myGrp,DC=abc,DC=pl» — kontener grupy uprawnień (grupa myVPNUsr w kontenerze abc.plmyGrp);
- SearchFilter "(cn=myVPNUsr)" — nazwa grupy uprawnień.
Uruchamianie i diagnostyka
Teraz możemy spróbować 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
Wydanie i unieważnienie certyfikatu
Ponieważ oprócz samych certyfikatów potrzebne są klucze i inne ustawienia, bardzo wygodnie jest to wszystko zamknąć w jednym pliku profilu. Plik ten jest następnie przekazywany użytkownikowi, a profil importowany jest na kliencie OpenVPN. W tym celu stworzymy szablon ustawień oraz skrypt formują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 go zbyt wydłużać, 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.ovpnclient
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-----
PUT YOUR CA CERT (ca.crt) HERE
-----END CERTIFICATE-----
key-direction 1
-----BEGIN OpenVPN Static key V1-----
PUT YOUR TA KEY (ta.key) HERE
-----END OpenVPN Static key V1-----
Uwagi:
- linie PUT YOUR… 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 prawa do wykonywania:
chmod a+x ~/make.profile.shI możemy wydać nasz pierwszy certyfikat.
~/make.profile.sh my-first-userUnieważnienie
W przypadku kompromitacji certyfikatu (zgubienie, kradzież) konieczne jest jego unieważnienie:
cd /usr/share/easy-rsa/3/
./easyrsa revoke my-first-user
./easyrsa gen-crl
Podgląd wydanych i unieważnionych certyfikatów
Aby zobaczyć wydane i unieważnione certyfikaty, wystarczy sprawdzić plik indeksowy:
cd /usr/share/easy-rsa/3/
cat pki/index.txt
Wyjaśnienia:
- pierwsza linia to certyfikat serwera;
- pierwszy znak
- V (Valid) — ważny;
- R (Wstrzymany) — anulowany.
Konfiguracja sieci
Ostatnie kroki — konfiguracja sieci przesyłowej — routingu i zapór sieciowych.
Zezwolenie na połączenia w lokalnej zaporze:
$ 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, dlatego musimy poinformować router(y), w jaki sposób przekazywać pakiety adresowane do naszych klientów VPN. W wierszu poleceń wykonujemy polecenie zgodnie z używanym sprzętem:
# ip route 172.16.20.0 255.255.254.0 172.16.19.123i zapisujemy konfigurację.
Ponadto na interfejsie brzegowym routera, który obsługuje zewnętrzny adres gw.abc.ru, należy zezwolić na przechodzenie pakietów udp/1194.
Jeśli w organizacji obowiązują rygorystyczne zasady bezpieczeństwa, na naszym serwerze VPN należy również skonfigurować zaporę sieciową. Moim zdaniem największą elastyczność zapewnia konfiguracja łańcuchów iptables FORWARD, chociaż ich konfigurowanie jest mniej wygodne. Trochę więcej o ich konfiguracji. Najwygodniej jest używać tzw. „bezpośrednich reguł” — direct rules, przechowywanych w pliku. /etc/firewalld/direct.xmlAktualną konfigurację reguł można poznać w następujący sposób:
$ sudo firewall-cmd --direct --get-all-rulePrzed wprowadzeniem zmian w pliku wykonaj jego kopię zapasową:
cp /etc/firewalld/direct.xml /etc/firewalld/direct.xml.`date +%F.%T`.bakPrzykładowa zawartość pliku może być następująca:
-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
W istocie są to standardowe reguły iptables, zapakowane inaczej po wprowadzeniu firewalld.
Interfejs docelowy w domyślnych ustawieniach to tun0, a interfejs 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ń — to standardowe polecenie firewalld do ponownego wczytania ustawień:
$ sudo firewall-cmd --reloadOdrzucone pakiety można przeglądać w ten sposób:
grep forward_fw /var/log/messages
Co dalej
Konfiguracja zakończona!
Pozostaje tylko zainstalować oprogramowanie klienckie na stronie klienta, zaimportować profil i połączyć się. Dla systemów Windows, pakiet jest umieszczony na .
Na koniec podłączamy nasz nowy serwer do systemów monitorowania i archiwizacji, pamiętając o regularnym instalowaniu aktualizacji.
Stabilnego połączenia!
Źródło: habr.com
