Two-Factor Auth Destekli OpenVPN Server Kurulumu
Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYIC1ZaZ' (Errcode: 28 - No space left on device) in /usr/share/nginx/html/syslogs/wp-includes/class-wpdb.php on line 2349
IT altyapılarının güvenilirliğini ve bağlı olarak sürekliliğini sağlamak üzere uygulanması gereken süreç disiplinlerinde kritik data içeren mecralara erişimlerde sıkı güvenlik prosedürleri izlenmesi gerekiyor. Bu anlamda özellikle PCI-DSS ya da ISO 27001 standartlarına tabii olan ya da olmak isteyen firmaların, kendi networklerine “dışarıdan” erişim ihtiyacının bulunması durumunda implemente edecekleri VPN çözümlerinin, bahsi geçen güvenlik standartlarına uygun olması gerekiyor. Örnek olarak PCI-DSS uyumluluğu için kullanılan VPN çözümünde kimlik doğrulama işlemi en az iki aşamalı olarak gerçekleştirilmek durumunda. Bu zorunluluk PCS-DSS V3'de şu şekilde tarif edilmiş durumda:
Implement Strong Access Control Measures 8.3 – Incorporate two-factor authentication for remote network access originating from outside the network by personnel (including users and administrators) and all third parties, (including vendor access for support or maintenance). Note: Two-factor authentication requires that two of the three authentication methods (see Requirement 8.2 for descriptions of authentication methods) be used for authentication. 8.2 Authentication methods – Something you know, such as a password or passphrase – Something you have, such as a token device or smart card – Something you are, such as a biometric.
Bu tanıma göre, networkünüze uzaktan erişim sağlayacak her türlü bağlantı için yapılacak kimlik denetimlerinde madde 8.2'de belirtilen metodlardan en az ikisinin kullanılması gerekiyor. Günümüzde yaygın olarak kullanılan SSL VPN çözümlerinde PKI altyapısı kullanılarak, bir username üzerinden key ibraz etmek sureti ile kimlik denetimi gerçekleştirilip bağlantı kuruluyor. Ancak bu tek yönlü kimlik denetimi, anlaşıldığı üzere yeterli değil. Bu nedenle kullandığınız VPN çözümünün username/ password (ya da key) ibraz etmeye ek olarak token ya da bir biometric denetim mekanizmasını destekliyor olması gerekiyor. Biometric denetim mekanizmalarının oldukça sınırlayıcı ve maliyetli çözümler olduğunu düşünürsek, iki yönlü doğrulama için username + token mekanizmalarını birlikte kullanmak konunun pratik çözümü olacaktır. İşte bu konudan hareketle bu yazıda, bir SSL VPN implementastonu olan openvpn ve Google Authenticator kullanılarak two-factor authentication destekleyen bir VPN sunucusu kurulumundan bahsedeceğim. En nihayetinde halihazırda kullandığınız openvpn altyapınıza yazıda anlatıldığı şekli ile google authenticator entegrasyonu da yapabilirsiniz.
Ön Gereksinimler
Kurulumlar 64 bit bir CentOS 6.5 üzerinde yapılacak, bu nedenle aynı sürümde RHEL tabanlı herhangi bir dağıtım kullanmanız yeterli olacaktır. Eğer openvpn sunucunuz NAT arkasında olacaksa dışarıdan UDP 1194 portuna gelecek isteklerin NAT yaptığınız mecradan içerideki OpenVPN sunucunuza yönlendirilmesi (Port Address Translation) gerekecektir.
OpenVPN Server Kurulumu
İlk olarak paket yöneticisine EPEL reposunu ekliyoruz:
# rpm -UvH http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
Ardından gerekli paketleri yüklüyoruz:
# yum install gcc make rpm-build autoconf.noarch zlib-devel pam-devel openssl-devel openvpn easy-rsa -y
OpenVPN Server Yapılandırması
Bu işlemden sonra OpenVPN sunucusunu yapılandırmaya başlıyoruz. /etc/openvpn/ dizini altında server.conf diye bir dosya oluşturalım:
# vi /etc/openvpn/server.conf
ve aşağıdaki direktifleri giriyoruz:
port 1194 proto udp dev tun ca ca.crt cert LinuxAkademi.crt key LinuxAkademi.key dh dh2048.pem server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 8.8.4.4" keepalive 10 120 reneg-sec 0 comp-lzo max-clients 100 user nobody group nobody persist-key persist-tun status openvpn-status.log verb 3
Not: Biz OpenVPN anahtarlarını üretirken LinuxAkademi ismini kullanacağız, siz kendinize göre bir isim vermek isterseniz, conf dosyasındaki LinuxAkademi.crt ve LinuxAkademi.key ibarelerini de buna göre düzenlemeyi unutmayın. Aksi taktirde OpenVPN sunucusu start edilemeyecektir. Ayrıca, server 10.8.0.0 255.255.255.0 ifadesi tünel networkü için kullanılacak ip block'unu ifade ediyor. Bu değeri kendinize göre düzenlemek isteseniz yazının ilerleyen bölümünde iptables'a ekleyeceğimiz NAT kuralında da belirlediğiniz ip block'unu yazmanız icap edecektir. push “redirect-gateway def1 bypass-dhcp” ifadesi ile clientların default gateway olarak OpenVPN sunucusunu kullanabileceklerni belirtiyoruz. Bu şekilde client tarafından üretilen tüm trafik tünel içerisinden geçerek OpenVPN üzerinden pass ediliyor. push “dhcp-option DNS 8.8.8.8” ve push “dhcp-option DNS 8.8.4.4” ifadeleri ile de clientlara atanacak dns sunucuların hangileri olduğunu set ediyoruz. Diğer direktiflerle ilgili tüm açıklamalar için /usr/share/doc/openvpn-2.3.2/sample/sample-config-files/server.conf yolunda bulunan örnek yapılandırma dosyasını inceleyebilirsiniz.
OpenVPN Server Anahtarlarının Oluşturulması
Şimdi OpenVPN sunucusuna ait key'leri oluşturacağız. Bu iş için, -işleri kolaylaştırdığından dolayı- easy-rsa uygulamasını kullanacağız. Öncelikle gerekli easy-rsa yapılandırmasını yapalım:
# mkdir /etc/openvpn/easy-rsa # cp -rf /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa/ # cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf # cd /etc/openvpn/easy-rsa
Sonra da CA için öntanımlı key bilgilerini düzenleyelim. Bu işlem /etc/openvpn/easy-rsa/vars dosyasındaki bir takım değişkeni ihtiyacımıza göre düzenlemekte ibaret. Bu dosyayı açın:
# vi /etc/openvpn/easy-rsa/vars
ve aşağıdaki ibareleri bulup örnekte olduğu gibi düzenleyin.
export KEY_COUNTRY="TR" export KEY_PROVINCE="IST" export KEY_CITY="Istanbul" export KEY_ORG="linux Akademi" export KEY_EMAIL="[email protected]" export KEY_OU="LinuxAkademi" # X509 Subject Field export KEY_NAME="LinuxAkademi"
Dosyayı kaydedip çıktıntan sonra, anahtarları oluşturmaya başlıyoruz. İlk olarak sertifika otoritemizi oluşturalım:
# cd /etc/openvpn/easy-rsa # source ./vars # ./clean-all # ./build-ca
build-ca komutunu verdiğiniz zaman, vars dosyasında tanımladığımız değişkenlere uygun olarak ca anahtarları oluşturulacak ve çıktı aşağıdaki gibi olacaktır.
Generating a 2048 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) [TR]: State or Province Name (full name) [IST]: Locality Name (eg, city) [Istanbul]: Organization Name (eg, company) [linux Akademi]: Organizational Unit Name (eg, section) [LinuxAkademi]: Common Name (eg, your name or your server's hostname) [linux Akademi CA]: Name [LinuxAkademi]: Email Address [[email protected]]:
Sertifika otoritresini yapılandırdıktan sonra, OpenVPN sunucusuna ait anahtarları oluşturuyoruz.
# ./build-key-server LinuxAkademi
Not: build-key-server komutunda kullandığımız LinuxAkademi ismi, server.conf dosyasında server cert ve key parametrelerini LinuxAkademi.crt ve LinuxAkademi.key olarak set ettiğimiz için girilmektedir. Dosyada bu parametreleri kendinize göre düzenlediyseniz, bu komutta verdiğiniz key ismi de aynı olmalıdır. Bu komutun çıktısı ise gene vars dosyasında belirtiğimiz değişkenlere uygun olarak aşağıdaki gibi olacaktır (en sonda sorulan iki soruya “y” olarak cevap vermeniz gerekmektedir.):
Generating a 2048 bit RSA private key .................+++ ............................................................................................................................................................+++ writing new private key to 'LinuxAkademi.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) [TR]: State or Province Name (full name) [IST]: Locality Name (eg, city) [Istanbul]: Organization Name (eg, company) [Linux Akademi]: Organizational Unit Name (eg, section) [LinuxAkademi]: Common Name (eg, your name or your server's hostname) [LinuxAkademi]: Name [LinuxAkademi]: Email Address [[email protected]]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'TR' stateOrProvinceName :PRINTABLE:'IST' localityName :PRINTABLE:'Istanbul' organizationName :PRINTABLE:'Linux Akademi' organizationalUnitName:PRINTABLE:'LinuxAkademi' commonName :PRINTABLE:'LinuxAkademi' name :PRINTABLE:'LinuxAkademi' emailAddress :IA5STRING:'[email protected]' Certificate is to be certified until Oct 26 12:51:11 2024 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Sonra, anahtar değiş tokuşu için kullanılacak Diffie Hellman dosyasını oluşturuyoruz.
./build-dh
Not: Bu komut sonlanana kadar herhangi sisteme herhangi bir girdi (klavyeden input, enter vs.) yapmayın. Aksi halde dosyanın oluşturulması yarıda kalacaktır. script 30 saniye kadar çalışıp aşağıdaki çıktı ile sonlanacaktır:
Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time ...................................................+..............................................+...........+...........................................................................................................................................+.....................+...............+....................................................................................................................................................................................................................+.........................................................................+.............................
Son olarak, ilgili dosyaları yerlerine taşıyalım:
# cd /etc/openvpn/easy-rsa/keys # cp dh2048.pem ca.crt LinuxAkademi.crt LinuxAkademi.key /etc/openvpn/
Bu şekilde sunucu tarafı için gerekli olan tüm anahtarlar oluşturulmuş oluyor. Şimdi son yapılandırma adımlarını tamamlayacağız.
Yapılandırmanın Tamamlanması
Bu aşamada, OpenVPN sunucunun clientlar için router olarak davranması için ip_forwarding'i açıp gerekli NAT kuralını sisteme ekleyip OpenVPN servisinin hizmet vereceği UDP 1194 için izin vereceğiz:
# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf # sysctl -p # iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE # iptables -A INPUT -p udp -m udp --dport 1194 -j ACCEPT # service iptables reload # service iptables save
Ayrıca, SELinux servisini devre dışı bırakalım:
# sed -i "s/SELINUX=enabled/SELINUX=disabled/g" /etc/sysconfig/selinux # setenforce 0
ve son olarak OpenVPN servisini startup'a ekleyip başlatıyoruz:
# chkconfig openvpn on # service openvpn start
Gelinen bu noktada herşey yolunda gittiyse, OpenVPN servisi sorunsuz olarak çalışmış olmalıdır. Şimdi OpenVPN sunucumuza Google Authenticator entegrasyonu yapacağız:
Google Authenticator Entegrasyonu
Google Auth PAM modülünü yüklemek üzere gereksinim paketlerini kuralım:
# yum install -y wget make pam-devel
Ardından modülü download edip, paketi açalım:
# wget https://google-authenticator.googlecode.com/files/libpam-google-authenticator-1.0-source.tar.bz2 # tar jvfx libpam-google-authenticator-1.0-source.tar.bz2
Şimdi modülü derleyeceğiz, bu nedenle ilgili dizine geçelim:
# cd libpam-google-authenticator-1.0
Derleme öncesinde bu dizindeki Makefile dosyasını editleyelim:
# vi Makefile
ve Lisans satırlarından hemen sonraya aşağıdaki ibareyi ekleyelin:
LDFLAGS="-lpam"
Dosyayı kaydettikten sonra kurulumu gerçekleştirelim:
# make && make install
Son olarak /etc/pam.d/ dizini altında openvpn isimli bir dosya açalım:
# vi /etc/pam.d/openvpn
ve içerisine aşağıdaki ibareleri ekleyelim:
#%PAM-1.0 auth required pam_google_authenticator.so nullok account required pam_nologin.so account include system-auth
Sonrasında, /etc/openvpn/server.conf dosyasını açıyoruz:
# vi /etc/openvpn/server.conf
ve dosyanın en altına aşağıdaki satırı ekliyoruz:
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so /etc/pam.d/openvpn
Dosyayı kaydettikten sonra openvpn servisini restart ediyoruz:
# service openvpn start
Bu şekilde GA entegrasyonu tamamlanmış oluyor. Şimdi server üzerinde client için kullanıcı/key oluşturma aşamasına geçeceğiz.
OpenVPN Client Tanımlamaları
OpenVPN server üzerinde kullanıcı oluşturmak üzere /etc/openvpn/easy-rsa dizinindeki build-key-pass scriptini kullanacağız. Örnek olarak myuser isimli bir kullanıcı oluşturalım ve kendisine bir şifre atayalım: (Not bu parola OpenVPN bağlantısı sırasında kullanılacak.)
# cd /etc/openvpn/easy-rsa # source ./vars # ./build-key-pass myuser
Bu komutu verdiğiniz zaman aşağıdaki çıktıda da görüldüğü için myuser kullanıcısı için oluşturulacak key'e bir passphrase belirlemeniz istenecektir. Bu parola belirlendikten sonra sorulacak sorulara yes derseniz ilgili key'ler oluşturulacakır:
Generating a 2048 bit RSA private key ....................+++ ........................................................................................................................+++ writing new private key to 'myuser.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- 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) [TR]: State or Province Name (full name) [IST]: Locality Name (eg, city) [Istanbul]: Organization Name (eg, company) [Linux Akademi]: Organizational Unit Name (eg, section) [LinuxAkademi]: Common Name (eg, your name or your server's hostname) [myuser]: Name [LinuxAkademi]: Email Address [[email protected]]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'TR' stateOrProvinceName :PRINTABLE:'IST' localityName :PRINTABLE:'Istanbul' organizationName :PRINTABLE:'Linux Akademi' organizationalUnitName:PRINTABLE:'LinuxAkademi' commonName :PRINTABLE:'myuser' name :PRINTABLE:'LinuxAkademi' emailAddress :IA5STRING:'[email protected]' Certificate is to be certified until Oct 26 21:37:42 2024 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Bu şekilde /etc/openvpn/easy-rsa/keys/ dizini altında, myuser.crt ve myuser.key isimli genel ve özel anahtar dosyası oluşturulacaktır. Şimdi OpenVPN sunucu üzerinde myuser isimli bir kullanıcı açalım ve bir password tanımlayalım. (Bu password'ü herhangi bir yerde kullanmayacağız. Sadece prosedür gereği şifre tanımlıyoruz.)
# adduser myuser # passwd myuser
Ardından, google authenticator için gerekli tanımlamaları yapalım:
# su - myuser -c 'google-authenticator -t -d -r 3 -R 30 -w 17 -f'
Bu komutta kullandığımız parametreler şu şekildedir: -t: time-based verification (TOTP) kullanacağımızı belirtir. -d: Daha önceden kullanılmış tokenlerin yeniden kullanılmasını engeller. -r 3: brute-force önlemi için rate-limiting. her (N) saniye için max 3 login teşebbüsüne izin ver diyoruz. -R 30: Yukarıdakinin devamı; her 30 saniye için (N) login teşşebbüsüne izin ver demiş oluyoruz. -w 17: Max concurrent token sayısı (Default değer 17) -f: Yapılandırmanın ~/.google_authenticator dosyasına otomatik ekle. (Default olarak izin istenir.) verdiğiniz zaman aşağıdaki gibi bir çıktı alırsınız: Komutun çıktısı ise şu şekilde olacaktır:
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/myuser@VPNServer%3Fsecret%3DY3AG)Q3TM7W5VUFB Your new secret key is: T5AHZQ3ZM9W5TUFT Your verification code is 309214 Your emergency scratch codes are: 24672799 65865901 81640022 24794245 90102518
Çıktıdaki URL'de telefonunuza Android için https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en adresinden ya da iOS için https://itunes.apple.com/en/app/google-authenticator/id388497605?mt=8 erişerek kurabileceğiniz GA uygulaması üzerinden scan edebileceğiniz QRCode bulunmaktadır. Bu code'u scan ettiğiniz zaman kullanıcınıza ait hesap GA uygulamasına eklenecek ve tek kullanımlık tokenler üretebilir duruma geleceksiniz. QRCode kullanmak istememeniz durumunda ise “secret key”‘i girerek kullanıcınıza ait GA hesabını ekleyebilirsiniz. Google Authenticator uygulaması ile ilgili olarak telefonunuzdaki işlemleri yaptıktan sonra, OpenVPN sunucu üzerindeki kullanıcımızın shell'ini /sbin/nologin olarak set ediyoruz:
# usermod -s /sbin/nologin myuser
Böylece kullanıcı oluşturma işlemi tamamlanmış oluyor. Son adım olarak daha önce oluşturduğumuz myuser.crt ve myuser.key dosyası ile ca.crt dosyasını kullanıcıya göndermek üzere paketliyoruz:
# cd /etc/openvpn/easy-rsa/keys # tar cvfz ~/myuser-keys.tgz myuser.crt myuser.key ca.crt
ve bu tgz dosyasını kullanıcımıza gönderelim.
Client Tarafındaki İşlemler
Daha önce sunucu tarafında oluşturduğumuz kullanıcı key'lerini içeren ve home dizinine (/root/ dizinine) kaydettiğimiz tgz paketini kullanıcı bilgisayarında bir dizine açalım ve ardından client bilgisayarda myuser.ovpn isimli bir dosya oluşturup, aşağıdaki ibareleri ekleyelim:
client dev tun proto udp remote SERVER-IP 1194 resolv-retry infinite nobind persist-key persist-tun comp-lzo verb 3 reneg-sec 0 auth-user-pass ca "/path/to/ca.crt" cert "/path/to/myuser.crt" key "/path/to/myuser.key"
Not: Bold ve kırmızı olarak beliritlen SERVER-IP kısmı OpenVPN sunucunuzun ip adresi ve en aşağıda bulunan 3 satırda da tgz paketinden çıkan dosyaların tam yolu belirtilmelidir. Daha sonrasında kaydettiğiniz bu ovpn dosyası üzerinden bağlantı kurabilisiniz. Örnek olarak debian tabanlı linux dağıtımlarında (Ubuntu, Kali Linux, Linux Mint vs.) openvpn sunucusuna şu şekilde bağlantı kurabilirsiniz:
# openvpn --config ~/myuser.ovpn
Not: Sisteminizde openvpn paketi kurulu olmalıdır. “apt-get install openvpn” Bu komutu verdiğiniz zaman ~/myuser.ovpn dosyasında tanımlı openvpn sunucusuna doğru, gene ilgili dosyada belirtilen key'ler kullanılarak bir openvpn bağlantısı kurulacaktır ve önce myuser isimli kullanıcı adını girmeniz ardından da google authenticator uygulamasından ürettiğiniz tek seferlik parolayı girmeniz istenecektir. Bu bilgileri girdikten sonra ikinci doğrulama işlemi olarak key'inize ait passphrase'i girmeniz istenecektir (Bu noktada key ibraz ediyor olduğunuzdan ötürü üçüncü bir doğrulama işlemi de gerçekleşmiş olmaktadır.). Böylece onra openvpn bağlantısı kurulacak ve client tarafından üretilen tüm trafik tunnel içerisinden geçerek internete çıkacatır. Doğrulamak için curl http://ifconfig.me/ip komutu ile ip adresinizin ne olduğunu check edebilirsiniz.
Bu yazılar da ilginizi çekebilir:
- 389 Directory Server (LDAP) Kurulum ve Yapılandırması
- CentOS 7.0 Üzerinde Zimbra Server 8.0 Kurulumu
- DjbDNS ile Caching DNS Server Kurulumu
- CentOS Üzerine MongoDB Kurulumu
- CentOS üzerinde Git Server + Gitweb Kurulumu
Yorumlar
Trackbacks
Yorumda bulunun.
Merhaba,
Bahsettiğiniz gibi kurulumları Centos 7 üzerinde gerçekleştirdim (GA adımlarını yapmadım, GA istemiyorum).
Yaşadığım iki sorun var;
1) OPenVPN servisini çalıştırabilmek için “service openvpn@server start” komutunu girmem gerekti. Aslında bu bir sorun değil, çünkü “service openvpn@server status” komutuyla servisin çalıştığını görüyorum.
2) Mac kullanıyorum ve client tanımlamalarını yaptım. aşağıdaki hatayı alıyorum
2015-01-17 01:08:09 MANAGEMENT: CMD ‘username “Auth” “myuser”‘
2015-01-17 01:08:09 MANAGEMENT: CMD ‘password […]’
2015-01-17 01:08:09 WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
2015-01-17 01:08:09 NOTE: the current –script-security setting may allow this configuration to call user-defined scripts
2015-01-17 01:08:09 MANAGEMENT: Client disconnected
2015-01-17 01:08:09 Error: private key password verification failed
2015-01-17 01:08:09 Exiting due to fatal error
2015-01-17 01:08:11 *Tunnelblick: No ‘post-disconnect.sh’ script to execute
2015-01-17 01:08:11 *Tunnelblick: Expected disconnection occurred.
[Cevapla]
Ben yazıyı CentOS 6.5 için anlatmıştım. 7 sürümünde köklü değişiklikler var bu nedenle bir takım uyumsuzluklar olması normaldir.
[Cevapla]