Memblokir akses nama domain yang tidak ada di Nginx

Fokus pembahasan kali ini adalah bagaimana cara memblokir akses atau mencegah Nginx melayankan request nama domain yang tidak dihosting dalam web servernya. Jadi kalau kebetulan anda dapat alamat IPv4 bekas dari pelanggan lain dan ternyata nama domainnya masih mengarah ke server tersebut jelas dalam log Nginx akan banyak errornya. Ya, ini ringkasan kasus yang dialami oleh mas Danny dan ditanyakan lewat email kemarin.

Saya copas isi emailnya dulu dan saya sensor alamat IP dan nama domainnya, tapi esensinya tidak hilang:

Mas Chandra,
Gara2 server VPS di LHC Singapore down seluruh nodenya, kemarin saya beli VPS di Digital Ocean. Website sudah running walaupun propagasi DNS nya belum komplit ke semua DNS Server.

Nah anehnya, ketika saya lihat error.log nginx saya ada error yang aneh:

2016/01/24 09:14:04 [error] 24072#0: *1257 FastCGI sent in stderr: "Unable to open primary script: /var/www/html/wp-login.php (No such file or directory)" while reading response header from upstream, client: 192.169.176.71, server: cloud.example.com, request: "POST /wp-login.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "example.net", referrer: "http://example.net/wp-login.php"

Anehnya adalah example.net itu bukan website saya. Saya check DNS untuk website tersebut, ternyata memang diarahkan ke alamat IP droplet saya.

Kalau saya buka websitenya example.net, eh keluarnya website saya.

Apakah ada setting di webserver saya untuk mengacuhkan request seperti ini?

Request artikel untuk install Ajenti V dong 😉

Secara teknis yang terjadi adalah domainnya (example.net) terlupakan A Record pada DNS hostingnya masih diarahkan ke alamat IP Droplet milik mas Danny. Masalahnya setting Nginx yang terinstall secara default akan melayani permintaan yang masuk dan karena tidak ada virtual hostnya maka akan otomatis dialihkan ke nama domain yang ada (example.com).

Kerugiannya jelas:

  1. Menambah beban kerja Nginx karena melayani permintaan akses ke nama domain yang salah atau tidak ada.
  2. Log catatan bertambah panjang karena kesalahan ini. Ini akan menambah sulit kalau kita ingin mencari hal tertentu dalam catatannya.
  3. Ada resiko dianggap konten duplikat oleh Google.

Solusinya sudah cukup jelas, kita harus menginstruksikan Nginx agar setiap request yang masuk dan tidak cocok terhadap daftar nama domain yang dihosting didalamnya agar diabaikan dan diberikan kode error agar jelas maksud kita apa.

Saya memberikan 2 cara alternatif tapi semuanya membutuhkan modifikasi nginx.conf:

  1. Blokir akses khusus untuk satu nama domain:
    if ($host !~* ^(example.net|www.example.net)$ ) {
    return 444;
    }

    Kode diatas sisipkan didalam blok server ya.

  2. Metode kedua ada variasinya, esensinya sama tapi cuma beda perintah saja:
    server {
      listen 80 default_server;
      return 444;
    }

    atau

    server {
        listen      80;
        server_name "";
        return      444;
    }

    atau

    server {
      server_name  _;  #tanda _ itu maksudnya default server
      return 444;
    }

    Gunakan salah satu saja sudah cukup sebenarnya (atau dari mas Danny malah dikombinasikan jadi satu akhirnya). Jadi yang dilakukan kode ini akan mengecek apakah nama domain yang ingin diakses ada dalam daftar defaultnya. Jika tidak ada maka akan langsung error.

Kode errornya memang benar adalah 444 dan merupakan kode buatan milik Nginx, belum pernah saya tahu ada di web server lain. Nanti yang dialami pengunjung akan muncul tulisan No data received – ERR_EMPTY_RESPONSE pada Google Chrome atau The connection was reset pada Mozilla Firefox saat dibuka website yang salah tadi. Log errornya juga bersih dari kesalahan ini setelahnya.

Dari sisi Nginx kalau hostname yang diminta hasilnya adalah kode 444 maka tidak akan diproses lebih lanjut jadi jelas mengurangi beban kerjanya. CPU, RAM dan Bandwidth masih mahal soalnya, harus kita optimalkan penggunaannya. 😉

Semoga bermanfaat. 😀

2 pemikiran pada “Memblokir akses nama domain yang tidak ada di Nginx

  1. if ($host !~* ^(example.net|www.example.net)$ ) {
    return 444;
    }

    untuk domain diatas apakah diisi dengan domain yang tanpa izin menggunakan server kita, atau disini dengan domain kita ?
    Terus jika memang diisi dengan domain kita, jika satu vps diisi dengan banyak domain bagaimana ?

    Terimakasih banyak.

    • Kode yang itu ditujukan ke nama domain yang tanpa izin mas. Jadi kalau ada banyak ya ditambahkan lagi didalamnya. Gampangnya ini blacklist.

      Solusi alternatifnya dibalik, pakai sistem whitelist dimana Nginx akan ngecek apakah ada dalam daftar virtual hostingnya. Ini untuk metode kedua.

Tinggalkan komentar