Nginx Nedir ?

Nginx Rus yazılım mühendisi Igor Sysoev tarafından mail.ru için yapılmış mail sunucusudur, fakat daha sonra geliştirilip tüm platformlarda kullanılabilir hale getirilmiştir.

Peki Ne İşe Yarar ?

Nginx özellikle yüksek trafikli ve yoğun istek girişi olan web siteleri için biçilmiş kaftandır. Apache ve Lighttpd ile karşılaştırıldığında çok daha az cpu kullanır.

Temel Özellikleri ;

  • Reverse Proxy (Ters Vekil Sunucusu),
  • Load Balancing (Yük Dengeleme),
  • Virtual Host (Sanal Sunucu),
  • Statik ve index dosyalarının sunumu, otomatik indeksleme.

Kıyaslama

Nginx’in alternatifi olarak şu anda Apache HTTP Server ve Lighttpd gösterilmekte. Alternatifleri ile karşılaştırıldığında %400 daha performanslı ve hızlı olduğu görülmekte. Ayrıca alternatiflerine göre çok daha az cpu kullanır.

Reverse Proxy (Ters Vekil Sunucusu)

Reverse proxy için istemciden gelen istekleri sunucu adına alan vekil sunucu diyebiliriz. Gelen istekleri karşılayarak sunucuya iletir ve dönen cevapları istemciye iletir.

Sağladığı Avantajlar ;

  • Reverse proxy’ler sunucuların varlığını ve özelliğini gizleyebilir,
  • İstemcileri web tabanlı saldırılara karşı koruyabilir,
  • Reverse proxy’ler Web sunucuları üzerinden yükü azaltarak, web isteklerine hızlı bir şekilde cevap verebilir.

Anlaşılabilirliği artırmak amacı ile local bir örnek yapalım.

  1. İlk olarak nginx kurulumunu yapalım.

Bu örneği macOS üzerinde gerçekleştiriyoruz. Windows , Ubuntu için ilgili linkleri inceleyebilirsiniz.

// Homebrew ile nginx’i kuruyoruz.
brew install nginx
// Nginx'i çalıştırıyoruz.
sudo nginx

Yukarıda ki işlemleri gerçekleştirdikten sonra browserdan http://localhost:8080’i açarak nginx’in çalıştığını görebilirsiniz.

2. Nginx kurulumunu bitirdikten sonra küçük bir node uygulaması oluşturacağız. (Node uygulaması sadece örnek amaçlıdır.)

var express = require('express');
var app = express();
var port = process.env.PORT;
app.get('/', (req, res) => {
res.send(`İsteğin cevaplandığı port: ${port}`)
});
app.listen(port, () => {
console.log(`Running on ${port}`);
});

İstediğimiz portta çalıştırabileceğimiz bir node application oluşturduk. Buradaki amacımız uygulamamıza bir istek yapacağız ve hangi porttan cevaplandığını göreceğiz.

// Uygulamamız 5000 nolu portta çalıştırıyoruz.
PORT=5000 node index.js

Tarayıcımızdan localhost:5000/ ve ya komut satırından “curl http://localhost:5000/;” komutunu çalıştırarak uygulamamıza istek atabiliriz.

Cevap olarak böyle birşeyle karşılaştık.

3. Uygulamamızda hazır olduğuna göre şimdi nginx ayarlarını yapabiliriz

/usr/local/etc/nginx/nginx.conf

Yukarıda belirtilen dizini herhangi bir text editör ile açıyoruz. Burası nginx konfigürasyon dosyası.

server {
listen 5000;
server_name localhost;
access_log /usr/local/var/log/nginx/localhost_5000.access.log main;

location / {
proxy_pass http://localhost:5001;
}
}

Server: Konfigürasyon dosyası içerisindeki server üzerinde çalışılan makineyi işaret ediyor.

Listen: Hangi portun dinleneceğini belirtiyor.

Access_log: Log dosyasının dizinini belirtiyor.

Proxy_pass: Yönlendirilecek adres.

Burada localhost:5000’e gelen istekleri localhost:5001’e yönlendirdik. Şimdi nginx’i restart ettikten sonra ayakta olan uygulamamıza bir istek daha atalım.

// Nginx'i yeniden başlatıyoruz.
sudo nginx -s stop && sudo nginx

Yeniden başlattıkdan sonra localhost:5000’e tekrar bir istek yapıyoruz.

Görüldüğü üzere localhost:5000’e gelen istekler localhost:5001 tarafında cevaplanıyor. Küçük bir reverse proxy örneği oldu, umarım anlaşılır olmuştur.

Load Balancing (Yük Dengeleme)

Load balancing server üzerindeki fazla yükleri diğer serverlara dağıtarak işlemlerin birden fazla makinede kısa sürede çözülmesini sağlar.

Load balancing içinde bir örnek yapalım. Burada da aynı örneğin üzerine koyarak devam edelim.

Bu örnekte bir server’a çok fazla yük bindireceğiz ve nasıl davrandığını inceleyeceğiz ve bunun için Apache Http Server Benchmarking Tool kullanıyorum.

ab -n İstek_Sayısı İstek_Yapılacak_Adres
ab -n 5000 http://127.0.0.1:5000/

Burada localhost:5000 portuna 5000 adet istek yaptık ve sonuçları;

Burada 5000 isteği 18.8 saniyede cevapladı. Bunun kısa bir süre olduğunu düşünebilirsiniz. Ama testi local’de yaptığımızı ve dönen responsun sadece bir text olduğunu unutmayalım. Uzaktaki bir makineye erişmeye çalıştığımızda bu süre çok daha fazla olacaktır.

Şimdi nginx.conf ayarlarına giderek load balancing ayarlarını yapalım.

Hatırlayacağınız üzere load balancing bir makinedeki yükü diger makinelere dağıtıyordu. Bunun için 2 yeni makine ayağa kaldırıyoruz.

// 5002 portunda da uygulamamızı başlatıyoruz.
PORT=5002 node index.js
// 5003 portunda da uygulamamızı başlatıyoruz.
PORT=5003 node index.js

Nginx konfigürasyon dosyasını yine bir text editör ile açıyoruz.

/usr/local/etc/nginx/nginx.conf

Burada hangi porta gelen istekleri diger portlara dağıtacağımızı belirteceğiz.

upstream load_balancing_list {
server localhost:5001;
server localhost:5002;
server localhost:5003;
}

server {
listen 5000;
server_name localhost;
access_log /usr/local/var/log/nginx/localhost_5000.access.log main;

location / {
proxy_pass http://load_balancing_list;
}
}

Server bölümünden reverse proxy kısmında bahsetmiştik.

upstream: Burada yönlendirilecek portlar belirtiliyor.

proxy_pass: Buraya ise oluşturduğumuz upstream değişkenini atıyoruz.

Artık localhost:5000’e gelen istekler 5001,5002,5003 portlarına yüklerine göre dağıtıldı.Tekrar bir test yapalım ve tek makine ile 3 makine arasındaki farkı görelim.Tabi daha öncesinde nginx’i tekrar başlatıyoruz. ( Her değişiklikten sonra ayarların uygulanması için nginx’i tekrar başlatmayı unutmayın. )

// Nginx'i yeniden başlatıyoruz.
sudo nginx -s stop && sudo nginx

Son olarak gördüğünüz gibi localhost:5000/ portuna 5000 adet istek yaptık ve bunların hepsini cevaplaması 6.1 saniye sürdü. Önceki testimizde tek makine ile 18.8 saniyede cevapladığımız istekleri nginx’in yardımı ile 3 makineye paylaştırdık ve response time’ı 6 saniyeye kadar indirgedik.

SSL Konfigürasyonu (Secure Sockets Layer)

SSL, server ile alıcı iletişimi esnasında verilerin şifrelenerek yapılması işlemidir. En bilinen kullanımı ise, web sitesindeki veri alışverişi esnasında, server ile internet tarayıcısı arasındaki iletişimi şifrelenmesidir.

Letsencrypt’den ücretsiz ssl alarak bunu web sitemize entegre edeceğiz. (Eğer sahip olduğunuz bir ssl varsa bu adamı atlayabilirsiniz)

Bu örneğimizi digitalocean üzerinde bulunan ubuntu makinede gerçekleştireceğiz.

İlk olarak git olan makinede Letsencrypt reposunu localimize kopyalıyoruz.

git clone https://github.com/letsencrypt/letsencrypt
// letsencrypt dizinine ulaşıyoruz.
cd letsencrypt
// help komutu ile neler yapılabileceğini görebiliriz.
./letsencrypt-auto --help

Letsencrypt’i kurduktan sonra artık ssl oluşturabiliriz.

// ahmtdnz.xyz web sitesi için bir ssl oluşturuyoruz.
./letsencrypt-auto certonly — standalone -d ahmtdnz.xyz -d www.ahmtdnz.xyz — debug

Yukarıda ki komutu çalıştırdıktan sonra bizden email ve kullanım şartlarını kabul etmemizi isteyecek.

Bu şartları kabul ettikten sonra ssl sertifikamızı oluşturuluyor.

Sertifikamızı oluşturduk ama burada dikkat etmemiz gereken bazı şeyler var. Letsencrypt üzerinden oluşturduğumuz ssl sertifikaları 4 aylık bir süreyi kapsıyor. Resimde de görüldüğü gibi expire on 2017–08–09 bu tarihten sonra aynı işlemleri tekrar yapmamız gerekecektir.

Sertifikalarımıza “/etc/letsencrypt/live/domain_name” dizininden ulaşabiliriz. Şimdi nginx konfigürasyonlarını yaparak ssl’i aktif hale getirelim.

server {
// Ssl default portu 443 olduğu için burada bu portu belirttik.
listen 443 ssl;
server_name ahmtdnz.xyz;
// Oluşturmuş olduğumuz ssl sertifikası dizinini belirttik.
ssl_certificate /etc/letsencrypt/live/ahmtdnz.xyz/fullchain.pem;
// Oluşturmuş olduğumuz ssl sertifikası key dizinini belirttik.
ssl_certificate_key /etc/letsencrypt/live/ahmtdnz.xyz/privkey.pem
client_max_body_size 20M;
location / {...}
}
server {
listen 80;
server_name ahmtdnz.xyz www.ahmtdnz.xyz;
return 301 https://ahmtdnz.xyz$request_uri;
}
   listen 80;
server_name ahmtdnz.xyz www.ahmtdnz.xyz;
return 301 https://ahmtdnz.xyz$request_uri;
}

Bu ayarları yaptıktan sonra nginx’i tekrar başlatıyoruz ve belirtmiş olduğumuz server name’i tarayıcımızda açıyoruz.

Sonuç olarak böyle bir şey ile karşılaşıyoruz. Ssl entegrasyonu başarılı bir şekilde sonuçlandı. Ssl’i test etmek için https://www.sslshopper.com/ssl-checker.html ‘i de kullanabilirsiniz.

Bu yazımızda nginx, reverse proxy, load balancing ve ssl konfigürasyonundan bahsetmeye çalıştık. Faydalı olması dileği ile.

Ahmet DENİZ