Kurumsal ağlarda VPN kullanıcı yönetimi, sysadminlerin en çok baş ağrıtan konularından biri. Her yeni çalışan için ayrı sertifika üretmek, işten ayrılan birinin erişimini kesmek için sertifika iptal listesini güncellemek… Bunların hepsini zaten var olan Active Directory veya OpenLDAP altyapınızla çözebilirsiniz. Bu yazıda OpenVPN’e LDAP kimlik doğrulamasını nasıl entegre edeceğinizi, gerçek dünya senaryolarıyla birlikte anlatacağım.
Neden LDAP Entegrasyonu?
Sertifika tabanlı kimlik doğrulama güvenli, ama ölçeklenebilirlik açısından sorunlu. 200 kişilik bir şirkette VPN erişimi yönetiyorsanız, her kullanıcı için ayrı .ovpn dosyası üretmek ve dağıtmak gerçek bir operasyonel yük oluşturuyor.
LDAP entegrasyonunun getirdikleri şunlar:
- Kullanıcı, Active Directory veya OpenLDAP şifresiyle bağlanır, ayrı bir VPN şifresi hatırlamak zorunda kalmaz
- Birisi işten ayrıldığında AD hesabını devre dışı bırakmak yeterli, VPN erişimi otomatik kesilir
- Grup bazlı erişim kontrolü: “Sadece IT departmanı VPN’e bağlanabilir” gibi politikalar uygulanabilir
- Merkezi denetim logu, kim ne zaman bağlandı AD loglarıyla birleştirilebilir
Elbette hibrit yaklaşım da mümkün: Sertifika + LDAP şifresi kombinasyonu, her ikisini de zorunlu kılabilirsiniz. Bu yazıda bunu da göstereceğim.
Ön Gereksinimler
Anlatım boyunca şu ortamı varsayıyorum:
- Ubuntu 22.04 LTS üzerinde çalışan OpenVPN sunucu
- Active Directory veya OpenLDAP (her ikisi için de komutlar vereceğim)
openvpn-auth-ldappaketi- OpenVPN 2.5+
Eğer OpenVPN kurulumunuz henüz hazır değilse, önce temel kurulumu tamamlamanız gerekiyor. Bu yazı OpenVPN’in çalıştığını, sadece LDAP entegrasyonunun eksik olduğunu varsayıyor.
openvpn-auth-ldap Kurulumu
openvpn-auth-ldap, OpenVPN için yazılmış bir plugin. Kullanıcı adı ve şifreyi alıp LDAP sunucusuna sorguluyor, sonucu OpenVPN’e bildiriyor.
apt update
apt install openvpn-auth-ldap libldap-2.5-0 ldap-utils
Kurulum sonrası plugin dosyasının yerini kontrol edin:
ls -la /usr/lib/openvpn/openvpn-auth-ldap.so
Dosya orada olmalı. Eğer farklı bir yolda kurulduysa find / -name "openvpn-auth-ldap.so" 2>/dev/null ile bulun.
LDAP Yapılandırma Dosyası
Plugin için ayrı bir yapılandırma dosyası oluşturuyoruz. Bu dosya hem server.conf’tan ayrı tutuluyor, hem de içinde şifre olabileceği için izinleri kısıtlı tutmak önemli.
mkdir -p /etc/openvpn/auth
touch /etc/openvpn/auth/ldap.conf
chmod 600 /etc/openvpn/auth/ldap.conf
chown root:root /etc/openvpn/auth/ldap.conf
Şimdi yapılandırma dosyasını oluşturalım. Önce Active Directory için:
cat > /etc/openvpn/auth/ldap.conf << 'EOF'
<LDAP>
# AD sunucu adresi - birden fazla sunucu için boşlukla ayır
URL ldap://192.168.1.10:389
# TLS kullanıyorsanız:
# URL ldaps://192.168.1.10:636
# AD'ye bind için kullanılacak servis hesabı
BindDN "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
Password "GucluBirSifre123!"
# LDAP sorgu timeout süresi (saniye)
Timeout 15
# TLS sertifika doğrulama
TLSEnable no
# TLSCACertFile /etc/ssl/certs/ca-certificates.crt
# AD genellikle v3 kullanır
# LDAPVersion 3
</LDAP>
<Authorization>
# Kullanıcıların aranacağı OU
BaseDN "OU=Kullanicilar,DC=sirket,DC=local"
# Kullanıcı adını hangi LDAP attribute ile eşleştireceğiz
# AD için sAMAccountName, OpenLDAP için uid kullanılır
SearchFilter "(&(sAMAccountName=%u)(objectClass=user))"
# Bağlantı için kullanıcı DN şablonu (RequireGroup ile birlikte kullanılır)
# AD'de genellikle aşağıdaki gibi çalışır
# Sadece belirli bir grubun üyeleri bağlanabilir
RequireGroup true
<Group>
BaseDN "CN=VPN-Users,OU=Groups,DC=sirket,DC=local"
SearchFilter "(member=%D)"
MemberAttribute member
</Group>
</Authorization>
EOF
OpenLDAP kullanıyorsanız yapılandırma biraz farklı:
cat > /etc/openvpn/auth/ldap.conf << 'EOF'
<LDAP>
URL ldap://192.168.1.20:389
BindDN "cn=vpn-service,dc=sirket,dc=local"
Password "GucluBirSifre123!"
Timeout 15
TLSEnable no
</LDAP>
<Authorization>
BaseDN "ou=people,dc=sirket,dc=local"
SearchFilter "(&(uid=%u)(objectClass=posixAccount))"
RequireGroup true
<Group>
BaseDN "ou=groups,dc=sirket,dc=local"
SearchFilter "(cn=vpn-users)"
MemberAttribute memberUid
</Group>
</Authorization>
EOF
OpenVPN Server Yapılandırması
Mevcut server.conf dosyanıza plugin tanımını eklemeniz gerekiyor:
# /etc/openvpn/server/server.conf dosyasına eklenecekler
# LDAP plugin'i yükle
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/ldap.conf
# İstemciden kullanıcı adı ve şifre iste
auth-user-pass-verify /etc/openvpn/auth/ldap.conf via-file
# Bu satır plugin kullandığımızda gerekli
verify-client-cert none
# Kullanıcı adına göre istemci izolasyonu
username-as-common-name
Dikkat: verify-client-cert none satırını eklediğinizde sertifika doğrulaması devre dışı kalır. Eğer hem sertifika hem LDAP istiyorsanız (önerilir), bu satırı eklemeyin veya verify-client-cert optional kullanın.
Hibrit mod için server.conf şöyle görünmeli:
# Hem sertifika hem LDAP şifresi zorunlu
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/ldap.conf
# verify-client-cert satırı YOK - varsayılan olarak required kalır
username-as-common-name
# İstemci sertifikası da kontrol edilir
tls-auth /etc/openvpn/ta.key 0
LDAP Bağlantısını Test Etme
Yapılandırmayı uygulamadan önce LDAP sorgusunu manuel test edin. Sorun çıktığında nerede olduğunu bilmek, saatlerce log karıştırmaktan kurtarır.
# LDAP sunucusuna erişim testi
ldapsearch -H ldap://192.168.1.10:389
-D "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
-w "GucluBirSifre123!"
-b "OU=Kullanicilar,DC=sirket,DC=local"
"(&(sAMAccountName=ahmet.yilmaz)(objectClass=user))"
sAMAccountName displayName memberOf
Bu komut başarılı sonuç dönüyorsa LDAP tarafı çalışıyor demektir. Eğer ldap_bind: Invalid credentials hatası alıyorsanız servis hesabı şifresi yanlış. ldap_sasl_bind: Can't contact LDAP server alıyorsanız ağ bağlantısı veya firewall sorunu var.
Grup üyeliğini test etmek için:
ldapsearch -H ldap://192.168.1.10:389
-D "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
-w "GucluBirSifre123!"
-b "CN=VPN-Users,OU=Groups,DC=sirket,DC=local"
"(objectClass=group)"
member
İstemci Yapılandırması
İstemci .ovpn dosyasına kullanıcı adı/şifre isteyeceğimizi belirtmeliyiz:
# İstemci .ovpn dosyasına eklenmesi gerekenler
# Bağlanırken kullanıcı adı ve şifre sor
auth-user-pass
# Şifreyi bir dosyadan oku (opsiyonel, scripted bağlantılar için)
# auth-user-pass /path/to/credentials.txt
# Kimlik doğrulama başarısız olursa yeniden deneme
auth-retry interact
Eğer kullanıcılara şifrelerini bir dosyaya kaydetmek yerine her seferinde sormak istiyorsanız (daha güvenli), sadece auth-user-pass satırı yeterli. Bağlantı kurulurken kullanıcı adı ve şifre ekranı açılır.
TLS ile Güvenli LDAP Bağlantısı
Üretim ortamında LDAP trafiğini şifrelemek şart. AD için ldaps:// (port 636) veya STARTTLS kullanabilirsiniz.
Önce AD sertifikasını export edin ve sunucuya kopyalayın:
# Sertifikayı uygun dizine koy
cp ad-ca-cert.crt /etc/ssl/certs/
update-ca-certificates
# Bağlantıyı test et
ldapsearch -H ldaps://192.168.1.10:636
-D "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
-w "GucluBirSifre123!"
-b "DC=sirket,DC=local"
"(sAMAccountName=test)" sAMAccountName
LDAP yapılandırma dosyasını TLS için güncelleyin:
# /etc/openvpn/auth/ldap.conf - TLS bölümü
<LDAP>
URL ldaps://192.168.1.10:636
BindDN "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
Password "GucluBirSifre123!"
Timeout 15
TLSEnable yes
TLSCACertFile /etc/ssl/certs/ad-ca-cert.crt
TLSCACertDir /etc/ssl/certs
</LDAP>
Servis Hesabı Güvenliği
LDAP yapılandırma dosyasında düz metin şifre saklamak zorundayız, ama bunu mümkün olduğunca güvenli hale getirebiliriz.
AD tarafında servis hesabı için minimum yetkiler:
- Sadece okuma (Read) yetkisi
- Şifre değiştirme yetkisi yok
- İnteraktif oturum açma yasak
- Güçlü, uzun bir şifre
Linux tarafında dosya izinleri:
# Dosyayı sadece root okuyabilmeli
chmod 600 /etc/openvpn/auth/ldap.conf
chown root:root /etc/openvpn/auth/ldap.conf
# OpenVPN'in bu dosyayı okuyabilmesi için root olarak çalıştığından emin ol
systemctl cat [email protected] | grep User
Eğer şifreyi environment variable olarak geçmek istiyorsanız, bir wrapper script yazabilirsiniz:
#!/bin/bash
# /etc/openvpn/auth/get-ldap-password.sh
# Bu script şifreyi güvenli bir yerden okur
# Örneğin HashiCorp Vault veya şifreli bir dosyadan
cat /run/secrets/ldap-password
Log ve Sorun Giderme
OpenVPN loglarını gerçek zamanlı izlemek için:
journalctl -u openvpn-server@server -f
Yaygın hata mesajları ve çözümleri:
LDAP bind failed: Servis hesabı kimlik bilgileri hatalı veya hesap kilitli. AD tarafında kontrol edin.
LDAP user lookup failed: BaseDN veya SearchFilter yanlış. ldapsearch ile manuel test yapın.
Group membership check failed: Kullanıcı VPN grubunda değil veya grup DN’i hatalı.
TLS handshake failed: Sertifika doğrulaması başarısız. CA sertifikasını kontrol edin.
Daha ayrıntılı debug için OpenVPN verb seviyesini geçici olarak artırın:
# server.conf'a geçici olarak ekle
verb 9
Bu mod çok fazla log üretir, sorunu bulduktan sonra tekrar verb 3‘e düşürün.
Gerçek Dünya Senaryosu: Departman Bazlı Erişim
Bir müşteride şu durumla karşılaştım: IT ve DevOps ekipleri tam ağa erişebilmeli, muhasebe ekibi sadece belirli sunuculara ulaşabilmeli, diğerleri VPN’e hiç bağlanamamalı.
Bu senaryoyu iki ayrı OpenVPN instance ile çözdük:
# /etc/openvpn/server/vpn-full.conf - IT ve DevOps için
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/ldap-full.conf
port 1194
server 10.8.0.0 255.255.255.0
push "route 0.0.0.0 0.0.0.0"
# /etc/openvpn/server/vpn-restricted.conf - Muhasebe için
plugin /usr/lib/openvpn/openvpn-auth-ldap.so /etc/openvpn/auth/ldap-restricted.conf
port 1195
server 10.9.0.0 255.255.255.0
push "route 192.168.50.0 255.255.255.0"
# Sadece muhasebe sunucularına yönlendirme
Her instance için ayrı LDAP yapılandırması, farklı AD gruplarını kontrol ediyor. ldap-full.conf IT-VPN-Users grubunu, ldap-restricted.conf Muhasebe-VPN-Users grubunu denetliyor.
Systemd ile iki instance başlatmak için:
systemctl enable openvpn-server@vpn-full
systemctl enable openvpn-server@vpn-restricted
systemctl start openvpn-server@vpn-full
systemctl start openvpn-server@vpn-restricted
Şifre Değişikliği Durumu
Kullanıcı AD şifresini değiştirdiğinde aktif VPN bağlantısı kesilmez, ama yeni bağlantı denemesinde yeni şifre gerekir. Bu genellikle beklenen davranış. Ancak şifre süresi dolmuş kullanıcıların VPN’e bağlanmaya çalıştığı durumlar sorun çıkarabilir.
AD’de Account - Password must change at next login seçili olan hesaplar genellikle LDAP bind başarısız olur. Bu tür hesapları tespit için:
ldapsearch -H ldap://192.168.1.10:389
-D "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
-w "GucluBirSifre123!"
-b "OU=Kullanicilar,DC=sirket,DC=local"
"(&(sAMAccountName=*)(pwdLastSet=0))"
sAMAccountName displayName
Bu listeyi düzenli kontrol etmek iyi bir operasyonel alışkanlık. Kullanıcı “VPN bağlanmıyor” diye geldiğinde bu genellikle ilk kontrol edilecek şeylerden biri oluyor.
Failover ve Yüksek Erişilebilirlik
Tek LDAP sunucusu single point of failure oluşturur. openvpn-auth-ldap birden fazla sunucu tanımını destekler:
<LDAP>
# Birincil ve yedek AD DC'leri
URL ldap://dc01.sirket.local:389 ldap://dc02.sirket.local:389
BindDN "CN=vpn-service,OU=ServiceAccounts,DC=sirket,DC=local"
Password "GucluBirSifre123!"
Timeout 5
TLSEnable no
</LDAP>
Birincil sunucuya bağlanamazsa otomatik olarak ikinciye geçer. Timeout değerini düşük tutmak failover süresini kısaltır.
Monitoring ve Alerting
LDAP kimlik doğrulama başarısızlıklarını izlemek için basit bir script:
#!/bin/bash
# /usr/local/bin/check-vpn-auth-failures.sh
# Crontab'a ekle: */5 * * * * /usr/local/bin/check-vpn-auth-failures.sh
THRESHOLD=10
LOG_FILE="/var/log/openvpn/server.log"
ALERT_EMAIL="[email protected]"
FAILURES=$(grep "TLS Error|AUTH_FAILED|LDAP bind failed" $LOG_FILE |
awk -v d="$(date -d '5 minutes ago' '+%Y-%m-%d %H:%M')" '$0 > d' |
wc -l)
if [ "$FAILURES" -gt "$THRESHOLD" ]; then
echo "Son 5 dakikada $FAILURES VPN kimlik doğrulama hatası tespit edildi" |
mail -s "VPN Auth Alert" $ALERT_EMAIL
fi
Bu script 5 dakikada bir çalışır, belirlenen eşiği aşan başarısız kimlik doğrulama sayısı varsa e-posta gönderir. Brute force saldırılarını erken tespit etmek için kullanışlı.
Sonuç
OpenVPN ile LDAP entegrasyonu kurumsal ortamlarda VPN yönetimini ciddi ölçüde kolaylaştırıyor. Anlattıklarımı özetlersek:
openvpn-auth-ldapplugin’i kurulup yapılandırılıyor- AD veya OpenLDAP’a bağlanmak için servis hesabı oluşturuluyor
- Grup bazlı erişim kontrolüyle departman ayrımı yapılabiliyor
- TLS ile LDAP trafiği şifreleniyor
- Failover için birden fazla DC tanımlanabiliyor
En çok yapılan hata, yapılandırmayı doğrudan servise uygulamadan önce ldapsearch ile test etmemek. LDAP DN’leri, attribute isimleri, grup üyelikleri, bunları önce elle doğrulayın, sonra plugin’e bırakın.
Üretim ortamına geçmeden önce şu kontrol listesini işaretleyin: LDAP bağlantısı TLS kullanıyor, servis hesabı minimum yetkiyle çalışıyor, ldap.conf dosyası 600 izniyle korumalı, failover için en az iki DC tanımlı, monitoring scripti devreye alındı.
Sorularınız olursa yorumlarda buluşalım.