emirhanHCL 1
emirhanHCL
farkmt2official 1
farkmt2official
mannaxxx 1
mannaxxx
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Best Studio 1
Best Studio
TuZaKK 1
TuZaKK
Mt2Hizmet 1
Mt2Hizmet
Hikaye Ekle

[NODE JS] HTTPS Sunucu Oluşturma

  • Konuyu başlatan Konuyu başlatan Silverhand
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 1
  • Görüntüleme Görüntüleme 11

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] HTTPS Sunucu Oluşturma​


Güvenlik artık seçenek değil zorunluluk. Tarayıcılar HTTP üzerinden çalışan siteleri güvensiz olarak işaretliyor, Google sıralamalarda HTTPS'li siteleri kayırıyor. Dolayısıyla bir Node.js geliştiricisi olarak HTTPS sunucu kurmayı bilmeniz şart. Bu yazıda size adım adım HTTPS sunucu oluşturmayı anlatacağım.

HTTPS temelde HTTP protokolünün SSL/TLS katmanıyla şifrelenmiş halidir. İstemci ile sunucu arasındaki tüm iletişim şifrelenir ve üçüncü kişiler bu trafiği okuyamaz. Bunun için sunucunuzda bir SSL sertifikası ve özel anahtar (private key) bulunması gerekiyor. Geliştirme ortamında self-signed sertifika kullanabilirsiniz ama production'da mutlaka Let's Encrypt gibi güvenilir bir sertifika otoritesinden sertifika almanız lazım.

Self-signed sertifika oluşturmak için OpenSSL aracını kullanıyoruz. Terminal'de birkaç komutla kendi sertifikanızı üretebilirsiniz. Ben ilk kez HTTPS sunucu kurarken OpenSSL komutlarını yanlış girmiştim ve sertifika dosyası boş oluşmuştu. Sunucu başlatmaya çalıştığımda "error:0906D06C:PEM routines" gibi kriptik bir hata almıştım. O zamandan beri sertifika oluşturduktan sonra mutlaka dosya içeriğini kontrol ediyorum.

Node.js'te HTTPS sunucu oluşturmak için built-in https modülünü kullanıyoruz. Bu modül http modülüyle neredeyse aynı API'ye sahip. Tek fark sertifika ve key dosyalarını options olarak geçmeniz gerekiyor. fs modülüyle sertifika dosyalarını okuyup https.createServer metoduna veriyorsunuz.

Geliştirme ortamında self-signed sertifika kullandığınızda tarayıcı güvenlik uyarısı gösterecektir. Bu normal bir durum çünkü sertifikayı güvenilir bir otorite imzalamamış. Tarayıcıda "Gelişmiş" veya "Advanced" deyip devam edebilirsiniz. Ama sakın production ortamında self-signed sertifika kullanmayın. Kullanıcılarınız güvenlik uyarısı görür ve sitenizden hemen çıkar.

Production ortamında Let's Encrypt kullanarak ücretsiz SSL sertifikası alabilirsiniz. Certbot aracı bu işlemi otomatik hale getiriyor. Sertifika her 90 günde bir yenileniyor ve certbot bunu da otomatik yapabiliyor. Eğer sunucunuzun önünde Nginx veya Apache gibi bir reverse proxy varsa SSL termination'ı orada yapmanız daha doğru olur. Ama doğrudan Node.js üzerinden SSL sunmak istiyorsanız da gayet yapabilirsiniz.

Bir de HTTP/2 konusundan bahsedeyim. Node.js'in http2 modülü ile HTTPS üzerinden HTTP/2 desteği sağlayabilirsiniz. HTTP/2 multiplexing, header compression ve server push gibi performans iyileştirmeleri sunuyor. Modern tarayıcılar HTTP/2'yi sadece HTTPS üzerinden destekliyor, bu yüzden HTTPS kurmak aynı zamanda HTTP/2 kullanmanın ön koşulu.

PFX formatındaki sertifika dosyalarını da kullanabilirsiniz. PFX dosyası sertifika ve private key'i tek bir dosyada birleştirir. Windows ortamlarında daha yaygın olan bu format Node.js tarafından da destekleniyor. Options objesinde cert ve key yerine pfx ve passphrase kullanırsınız. Ama ben genelde PEM formatını tercih ediyorum çünkü daha yaygın ve debug etmesi daha kolay.

HTTPS sunucu kurarken dikkat etmeniz gereken güvenlik ayarları da var. TLS versiyonunu, cipher suite'leri ve diğer güvenlik parametrelerini doğru yapılandırmanız önemli. Eski TLS versiyonlarını (TLS 1.0, TLS 1.1) devre dışı bırakmanız güvenlik açısından kritik. Node.js varsayılan olarak makul güvenlik ayarları kullanır ama yine de projenizin ihtiyaçlarına göre bunları özelleştirmeniz gerekebilir.

JavaScript:
const https = require('https');
const http = require('http');
const fs = require('fs');
const path = require('path');

// SSL sertifika dosyalarini oku
// Gelistirme ortami icin self-signed sertifika kullaniyoruz
// openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
const sslOptions = {{
  key: fs.readFileSync(path.join(__dirname, 'ssl', 'key.pem')),
  cert: fs.readFileSync(path.join(__dirname, 'ssl', 'cert.pem')),
  // Opsiyonel guvenlik ayarlari
  minVersion: 'TLSv1.2',
  // Cipher suite'leri belirle
  ciphers: [
    'ECDHE-RSA-AES256-GCM-SHA384',
    'ECDHE-RSA-AES128-GCM-SHA256',
    'ECDHE-RSA-AES256-SHA384',
    'ECDHE-RSA-AES128-SHA256',
  ].join(':'),
}};

// HTTPS sunucu olustur
const httpsServer = https.createServer(sslOptions, (req, res) => {{
  res.writeHead(200, {{
    'Content-Type': 'text/html; charset=utf-8',
    'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
    'X-Content-Type-Options': 'nosniff',
    'X-Frame-Options': 'DENY',
  }});

  res.end(`
    <h1>Guvenli HTTPS Sunucu</h1>
    <p>Bu sayfa SSL/TLS ile sifrelenmis bir baglanti uzerinden sunuluyor.</p>
    <p>Protokol: ${{req.socket.encrypted ? 'HTTPS' : 'HTTP'}}</p>
    <p>TLS Versiyon: ${{req.socket.getProtocol?.() || 'Bilinmiyor'}}</p>
  `);
}});

// HTTP -> HTTPS yonlendirme sunucusu
const httpServer = http.createServer((req, res) => {{
  const httpsUrl = `https://${{req.headers.host?.replace(':80', ':443') || 'localhost:443'}}${{req.url}}`;
  console.log(`HTTP -> HTTPS yonlendirme: ${{req.url}} -> ${{httpsUrl}}`);
  res.writeHead(301, {{ 'Location': httpsUrl }});
  res.end();
}});

httpsServer.listen(443, () => {{
  console.log('HTTPS sunucu 443 portunda calisiyor');
}});

httpServer.listen(80, () => {{
  console.log('HTTP sunucu 80 portunda calisiyor (HTTPS yonlendirme)');
}});

// Hata yonetimi
httpsServer.on('error', (err) => {{
  if (err.code === 'EACCES') {{
    console.error('443 portu icin root/admin yetkisi gerekiyor.');
    console.error('Alternatif olarak 8443 portunu deneyin.');
  }} else {{
    console.error('HTTPS sunucu hatasi:', err.message);
  }}
}});

Şimdi de HTTP/2 destekli bir HTTPS sunucu kuralım. HTTP/2 ile özellikle çok sayıda kaynak yükleyen sayfalarda belirgin bir performans artışı göreceksiniz.

JavaScript:
const http2 = require('http2');
const fs = require('fs');
const path = require('path');

// HTTP/2 sunucu olustur (HTTPS gerektirir)
const server = http2.createSecureServer({{
  key: fs.readFileSync(path.join(__dirname, 'ssl', 'key.pem')),
  cert: fs.readFileSync(path.join(__dirname, 'ssl', 'cert.pem')),
  allowHTTP1: true, // HTTP/1.1 ile geriye uyumluluk
}});

// Statik dosyalari serve etmek icin yardimci
const mimeTypes = {{
  '.html': 'text/html',
  '.js': 'application/javascript',
  '.css': 'text/css',
  '.png': 'image/png',
  '.jpg': 'image/jpeg',
  '.json': 'application/json',
}};

server.on('stream', (stream, headers) => {{
  const reqPath = headers[':path'];
  const method = headers[':method'];

  console.log(`${{method}} ${{reqPath}}`);

  if (reqPath === '/') {{
    stream.respond({{
      ':status': 200,
      'content-type': 'text/html; charset=utf-8',
    }});
    stream.end(`
      <html>
        <head><title>HTTP/2 Sunucu</title></head>
        <body>
          <h1>HTTP/2 ile HTTPS Sunucu</h1>
          <p>Bu sayfa HTTP/2 protokolu ile sunuluyor.</p>
          <p>Multiplexing ve header compression destegi aktif.</p>
          <img src="/logo.png" alt="Logo">
          <script src="/app.js"></script>
        </body>
      </html>
    `);

    // Server Push ornegi - tarayici istemeden dosyalari gonder
    try {{
      const pushStream = stream.pushStream({{ ':path': '/app.js' }}, (err, pushStream) => {{
        if (err) return;
        pushStream.respond({{
          ':status': 200,
          'content-type': 'application/javascript',
        }});
        pushStream.end('console.log("Bu dosya server push ile geldi!");');
      }});
    }} catch (e) {{
      // Push desteklenmiyorsa sorun yok
    }}
  }} else {{
    stream.respond({{ ':status': 404 }});
    stream.end('Sayfa bulunamadi');
  }}
}});

server.listen(8443, () => {{
  console.log('HTTP/2 sunucu https://localhost:8443 adresinde calisiyor');
}});

HTTPS sunucu kurarken en sık yapılan hata sertifika dosyalarının yolunu yanlış vermek. Relative path kullanıyorsanız dikkatli olun çünkü çalışma dizini uygulamayı nereden başlattığınıza göre değişir. Ben her zaman path.join ve __dirname kullanıyorum, bu sayede dosya yolu sorunlarıyla karşılaşmıyorum.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst