Merhaba değerli e-bergi okuyucuları. Bu yazımda size Cloudflare ile nasıl dinamik bir şekilde DNS yönetimi yapabileceğinizi ve bunu nasıl otomatik hale getirebileceğinizi mümkün olduğu kadar kısa ve öz anlatmaya çalışacağım çünkü DNS dünyası çok geniş ve detaylı olduğu için tek bir yazıda hepsini açıklamam mümkün değil

Nedir, Ne Değildir, Neden İhtiyacımız Var?

DNS: "Domain Name System"in kısaltmasıdır. Türkçesi "Alan Adı Sistemi"dir. İnternet adreslerini bölümlendirmeye ve adlandırmaya yarayan sistemdir. En popüler kullanımı bir alan adının, IP adresine yönlendirmesine sağlamaktır. Örneğin; "example.com"a girdiğiniz de internet tarayıcınızın "93.184.216.119" adresine yönlendirmesi ya da "google.com" adresine girmeye çalıştığınızda Google sunucularından birine bağlanmanız bu sistem sayesindedir.

CloudFlare(CF): Güvenlik ve ön bellekleme (cache) gibi özellikler sunan bir içerik dağıtım ağıdır (CDN). Sunduğu özellikler listesini uzatmak mümkün. Örneğin, web sitenize erişilemediği durumlarda, CloudFlare kendi ön belleğini kullanarak sitenizin statik bir kopyasını kullanıcıya aktarır. Böylelikle kısa süreli erişim problemlerinde kullanıcınız sitenizin sunucundaki her hangi bir problemden habersiz - içerik tipinize göre değişebilir - şekilde gezinmeye devam eder.

Crontab: Linux üzerinde zamanlanmış görevleri çalıştırmamızı sağlayacak araç.

Nasıl Yapılır?

Cloudflare Hesabı Alma

Dinamik DNS sistemimizi CF(CloudFlare) DNS sunucuları üzerine kuracağız. CF’yi, DNS işlemlerinde kullanmak için bir çok sebep bulunmakta, bunlardan başlıcalarını şöyle listeleyebiliriz.

● Aktif hizmet süresinin (uptime) oldukça yüksek olması (99.999%)

● "Distributed DNS" hizmeti vermesi. Yani DNS sunucularından biri cevap vermezse başka bir sunucu yanıt verebilir ve sitenize erişim sağlanır.

● Bakımıyla ve güvenliğiyle uğraşmanız gerekmiyor.

● Ücretsiz olması.

Öncelikle hesabınınız yoksa tr.cloudflare.com adresinden ücretsiz bir hesap oluşturuyoruz. Hesabımıza giriş yaptıktan sonra alan adımızı CF’ye kayıt ediyoruz.

İlk adımda bizden DNS kayıtlarını girmemizi isteyecektir. Bunu 3 şekilde yapabiliriz İlki ve en zahmetsizi daha önceden DNS kayıtlarımız var ise CF bunları otomatik olarak bulup size listeliyor, genelde sizde hemen sonraki adıma geçiyorsunuz, İkinci yöntem, BIND sunucunun DNS kayıt dosyasını yüklemek, Üçüncü adım ise bütün kayıtları elle girmek.

Bütün kayıtlarımızı tamamladıktan sonra, CF ayarlarına geçiyoruz. Bu adımı direk devam ederek atlayabilirsiniz, ortalama bir web sitesi için ayar yapmanıza gerek yok. Dilerseniz daha sonra buradaki ayarla oynayarak içeriğinize en uygun ayarı bulabilirsiniz. Son adımda da CF sizden nameserver(NS) adreslerinizi değiştirmenizi isteyecektir. NS adreslerinizi de güncelledikten sonra, DNS sunucunuzu tamamen CF’e taşımış bulunmaktasınız.

IP Güncelleme

DNS sunucumuzdaki bir kaydın dinamikliğini sağlamak için onu belirli aralıklarda ya da gerektiğinde güncellememiz gerekmekte. Bunu basit bir Python scripti ile sağlayacağız. Script’te ise şu an ki IP adresimizi, kayıttaki IP adresi ile karşılaştıracağız. Eğer adresler farklı ise CF API’si üzerinden kaydımızdaki adresi güncelleyeceğiz. Script'in tamamına buradan ulaşabilirsiniz.

Parametreler:

record_id: CF-DNS’inde ki değiştirmek istediğimiz kayıdın ID’si. Bunu nasıl öğrenebileceğiniz için sonraki başlığa bakın.

token: CF hesabınızın API’ye erişmek için kullanacağı anahtar. CF’de “Hesap” sayfasından “API anahtarı” bölümünden alabilirsiniz.

email: CF hesabınızın bağlı olduğu e-posta adresi.

name: Güncellemek istediğiniz kayıdın adı. Benim örneğim için “pi”.

zone: Güncellemek istediğiniz alan adı.

İlk fonksiyonumuz “get_live_ip”yi DNS’deki IP adresini almak için kullanıyoruz. İstediğimiz adrese socket bağlantısı açarak, host adresini alabiliyoruz.

def get_live_ip(self):
    try:
        return socket.gethostbyname(self.name + '.' + self.zone)
    except IOError:
        return Non

İkinci fonksiyonumuz ise “get_current_ip”. Bu fonksiyon için mecburen harici bir web sitesi kullanmak zorundayız. Bir adrese bağlanmadan internet IP’mizi almamız mümkün değil. Bunun için oldukça stabil çalışan ipecho.net adresini seçtim ben. Dilerseniz başka alternatifler deneyebilir ya da herhangi birinin çalışmama durumuna karşılık yedek hizmet olarak bunlardan birini kullanabilirsiniz.

def get_current_ip(self):
    try:
        return urllib.urlopen('http://ipecho.net/plain').read()
    except:
        return None

Son ve asıl script mantığımızı yapan fonksiyon ise “update_record”. Fonksiyonumuz önce güncel ve DNS’deki IP adreslerini alıp, karşılaştırıyor ve iki IP birbirinden farklıysa CF’e güncelleme isteği gönderiyoruz.

def update_record(self):
    cur_ip = self.get_current_ip()
    last_ip = self.get_live_ip()

    if cur_ip is None:
        return False

    if last_ip is None:
        return False

    if cur_ip != last_ip:
        data = urllib.urlencode({
            'a': 'rec_edit',
            'type': 'A',
            'service_mode': '1',
            'ttl': '1',
            'tkn': self.token,
            'id': self.record_id,
            'email': self.email,
            'z': self.zone,
            'name': self.name,
            'content': cur_ip
        })

        try:
            response = urllib.urlopen('https://www.cloudflare.com/api_json.html/?%s' % data)
            result = json.loads(response.read())

        except:
            return False

        if result['result'] == 'success':
            return True
        return False
    return True

Burada benim varsaydığım birkaç ayar var. Bunları kendinize göre ayarlamak isteyebilirsiniz.

type: DNS kayıt tipi. Örnekte ben subdomain olarak kullandığım için ‘A’ tipinde

service_mode: Trafiğin CF üzerinden mi yoksa doğrudan mı bağlanacağı ayarı. Varsayılan CF üzerinden. Kapatmak için 0 yapın.

ttl: DNS kaydının ne kadar süre geçerli kalacağı. Ben genelde bu işi CF’e bırakmayı seviyorum, dilerseniz kendiniz saniye cinsinden süre belirtebilirsiniz.

Ve son olarak scriptimizin son parçasını da yükledikten sonra, bir obje oluşturup gerekli parametreleri göndererek scriptimizi çalıştırmak.

Kayıt ID’sini Öğrenme

Kayıt ID’sini öğrenmek için CF API’sine basit bir POST sorgusu atmamız gerekiyor. Gelen JSON objesinden istediğimiz bilgiye erişebiliriz. Aşağıdaki kodu curl'un kurulu olduğu sisteminizde çalıştırın:

curl https://www.cloudflare.com/api_json.html
-d ‘a=rec_load_all’
-d ‘tkn=8afbe6dea02407989af4dd4c97bb6e25’
-d ‘email=test@obcdn.net’
-d ‘z=obcdn.net’

Malesef gelen JSON yanıtı bizim için pek anlaşılabilir olmayacak. Daha okunaklı hale getirmek için jsonprettyprint.com dan yararlanabilirsiniz

Güzelleştirilmiş JSON’ımız da rahatlıkla görebileceğimiz gibi benim rec_id’im ‘101980879’. Bunu scriptimizde gerekli parametre yerine yazdığımızda scriptimiz çalışma hazır duruma gelmiş oluyor.

Otomatikleştirme

IP güncelleme kısmını hallettiğimize göre, bu işi “crontab” ile otomatiğe bağlayabiliriz. Böylelikle düzenli aralıklarla IP adresimiz kontrol edilip DNS üzerinde güncellenmiş olur. Linux/Unix sistemize girip “crontab -e” komutunu çalıştırıyoruz

onur@raspberrypi ~ $ crontab -e

Komutu çalıştırdığımızda crontab dosyamız açılıyor ve scriptimizi buraya girerek otomatik olarak belirli aralıklarda çalışmasını sağlayacağız. Ben her saat başı çalışmasını yeterli buluyorum. Dilerseniz daha sık ve daha seyrek çalıştırabilirsiniz. Saat başı için ayarlar şöyle

0 */1 * * * /home/pi/ddns/dns.py

Aynı scripti eğer 30 dk’da bir çalıştırmak isterseniz ise ekleyeceğiniz satır şu şekilde değişiyor.

*/30 * * * * /home/pi/ddns/dns.py

Daha farklı ayarlar isterseniz crontab dokümantasyonuna kısaca göz gezdirerek istediğiniz aralıkta ayarlayabilirsiniz.