Compile Nginx Latest Stable Version Dari Source Code

Bukan rahasia umum bahwa sampai saat ini web server yang paling banyak digunakan adalah Apache, tapi bagaimana dengan web server lain? Apakah tidak se-powerful Apache?

Nginx, sebuah web server yang di-develop oleh Igor Sysoev pada tahun 2002 Menjadi sebuah alternatif baru pengganti Apache.

CATATAN: Artikel ini dibuat di tahun 2011, jadi Anda perlu beradaptasi dalam mengikuti tutorial ini. Terelebih lagi, saat ini mayoritas distribusi Linux sudah banyak meninggalkan sysVinit beralih menggunakan SystemD.

Nginx (pengucapan “Engine X”) adalah web server / reverse proxy dan e-mail (IMAP/POP3) proxy yang ringan dengan kinerja tinggi , dilisensikan di bawah lisensi BSD. Berjalan pada UNIX, GNU/Linux, Solaris, Varian BSD seperti Mac OS X, dan Microsoft Windows.

Kenapa Nginx?

  1. Kecepatan: Cukup satu core processor untuk menangani ribuan koneksi, sehingga beban CPU dan konsumsi memory jauh lebih ringan.

  2. Mudah digunakan: Konfigurasi file jauh lebih mudah dimengerti dan dimodifikasi daripada konfigurasi web server lainnya seperti Apache. Beberapa baris saja sudah cukup untuk menciptakan sebuah virtual host yang cukup lengkap.

  3. Plug-in system ( disini disebut sebagai “modules” )

  4. dan yang paling penting, Open Source (BSD-like license)

Beberapa contoh website besar yang menggunakan Nginx entah itu sebagai web server atau sebagai reserve proxy sebagai backend Apache antara lain : kaskus.us, indowebster.com, wordpress.com, sourceforge.net, github.com, dll.

Latar Belakang Melakukan Kompilasi

Dalam proses instalasi web server, dibutuhkan beberapa tools dan parameter yang harus kita putuskan pada saat kompilasi, dan beberapa konfigurasi tambahan yang harus dilakukan dan disesuaikan dengan sistem kita.

Nah, kali ini kita memilih untuk men-download source code aplikasi dan menginstalnya secara manual daripada menginstal menggunakan package manager. Ada beberapa alasan kenapa orang memilih melakukan instalasi secara manual :

  1. Mengenal lebih jauh bagaimana sistem (terutama web server) yang kita gunakan itu bekerja.
  2. (Mungkin) belum tersedia dalam repositori dari distribusi Linux yang sedang digunakan.

Disamping itu jarang repositori yang menawarkan untuk men-download dan menginstall Nginx menggunakan package manager (yum|apt|yast) untuk versi yang terbaru (kecuali pada distribusi rolling-release seperti Arch Linux). Kebanyakan menyediakan versi lama yang kurang up-to-date alias basi. x_x.

Proses Kompilasi Nginx

Berikut ini ada capture screen video yang sudah saya buat sebelumnya. Mungkin bisa membantu dalam proses installasi. (tidak perlu sama persis, yang penting tau proses dan cara kerja-nya)

Download source-code

Pertama, mari kita download web server kita dari http://nginx.org/download/nginx-1.0.5.tar.gz (saat saya menulis artikel ini versi stable terbarunya adalah 1.0.5).

1wget http://nginx.org/download/nginx-1.0.5.tar.gz

setelah itu,copy source tersebut ke /usr/local/src/ kemudian extract.

1sudo cp nginx-1.0.5.tar.gz /usr/local/src/
2cd /usr/local/src/
3sudo tar -xvzf nginx-1.0.5.tar.gz

Catatan:

  1. Sebelum proses installasi, lebih baik cek apakah port 80 sedang digunakan atau tidak. Saya menggunakan distro BackTrack dan secara default Apache menggunakan port 80 pada saat startup. /etc/init.d/apache2 stop atau killall apache2.
  2. Nginx adalah program yang dibuat menggunakan bahasa C, jadi untuk dapat menggunakannya pertama-tama kita harus punya tools seperti GNU Compiler Collection (GCC) pada komputer kita. GCC biasanya sudah terinstall pada kebanyakan Linux distro.

Untuk memastikannya, jalankan saja perintah “gcc” (tanpa quote) melalui terminal. Jika anda mendapatkan output “gcc: no input files” berarti GCC sudah terinstall pada komputer anda. Jika tidak, anda perlu menginstallnya terlebih dahulu.

Oke, lanjott..

./configure dan make install

masuk ke folder nginx-1.0.5 pada direktori /usr/local/src/ dan mulai lakukan kompilasi.

1cd nginx-1.0.5
2./configure

Secara default, HTTP rewrite module onomatis ikut terinstall saat instalasi default Nginx. Module ini memerlukan PCRE (Perl Compatible Regular Expression) library karena Rewrite dan HTTP Core modules dari Nginx menggunakan PCRE sebagai syntax regular expression mereka.

Sekarang tergantung pilihan kita, jika kita :

  1. membutuhkan rewrite module, kita harus install PCRE terlebih dahulu:
1apt-get install libpcre3 libpcre3-dev
  1. jika kita tidak membutuhkannya :
1./configure --without-http_rewrite_module

Pilihan kita jatuh pada opsi pertama karena nantinya kebanyakan situs yang digunakan sangat membutuhkan rewrite module tersebut. Maka setelah melakukan instalasi PCRE, kita harus melakukan konfigurasi kembali.

1./configure

lakukan proses installasi :

1make && make install

proses instalasi default yang kita lakukan di atas akan menempatkan “ruang kerja” Nginx pada direktori /usr/local/nginx

Membuat SysVinit untuk Nginx

buat file dengan nama nginx pada direktori /etc/init.d

1nano /etc/init.d/nginx

kemudian copy paste shell script di bawah ini kemudian save

 1#! /bin/sh
 2### BEGIN INIT INFO
 3# Provides:          nginx
 4# Required-Start:    $all
 5# Required-Stop:     $all
 6# Default-Start:     2 3 4 5
 7# Default-Stop:      0 1 6
 8# Short-Description: starts the nginx web server
 9# Description:       starts nginx using start-stop-daemon
10### END INIT INFO
11
12PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
13DAEMON=/usr/local/nginx/sbin/nginx
14NAME=nginx
15DESC="nginx daemon"
16
17test -x $DAEMON || exit 0
18
19# Include nginx defaults if available
20if [ -f /etc/default/nginx ] ; then
21    . /etc/default/nginx
22fi
23
24set -e
25
26case "$1" in
27    start)
28        echo -n "Starting $DESC: "
29        start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
30            --exec $DAEMON -- $DAEMON_OPTS
31        echo "$NAME."
32        ;;
33    stop)
34        echo -n "Stopping $DESC: "
35        start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
36            --exec $DAEMON
37        echo "$NAME."
38        ;;
39    restart|force-reload)
40        echo -n "Restarting $DESC: "
41        start-stop-daemon --stop --quiet --pidfile \
42            /usr/local/nginx/logs/nginx.pid --exec $DAEMON
43        sleep 1
44        start-stop-daemon --start --quiet --pidfile \
45            /usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
46        echo "$NAME."
47        ;;
48    reload)
49        echo -n "Reloading $DESC configuration: "
50        start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
51            --exec $DAEMON
52        echo "$NAME."
53        ;;
54    *)
55    N=/etc/init.d/$NAME
56    echo "Usage: $N {start|stop|restart|force-reload}" >&2
57    exit 1
58    ;;
59esac
60exit 0

chmod +x supaya script dapat dieksekusi

1chmod +x /etc/init.d/nginx

Setelah ini, maka kita dapat melakukan start, stop, restart atau reload proses Nginx melalui script tersebut. Mari kita coba jalankan Nginx:

1/etc/init.d/nginx start

Maka seharusnya kita mendapatkan pesan sambutan “welcome to nginx!” saat mengakses localhost dari brwoser Anda.

Instalasi dan konfigurasi PHP FAST CGI (spawn-fcgi) dengan Nginx

Download PHP spawn-fcgi

1apt-get install php5-cgi spawn-fcgi

Setelah proses installasi melalui package manager selesai, buat file bernama php-fastcgi pada direktori /etc/init.d

1nano /etc/init.d/php-fastcgi

Copy paste shell init script di bawah ini.

 1#!/bin/bash
 2BIND=127.0.0.1:9000
 3USER=www-data
 4PHP_FCGI_CHILDREN=15
 5PHP_FCGI_MAX_REQUESTS=1000
 6
 7PHP_CGI=/usr/bin/php-cgi
 8PHP_CGI_NAME=`basename $PHP_CGI`
 9PHP_CGI_ARGS="- USER=$USER PATH=/usr/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
10RETVAL=0
11
12start() {
13    echo -n "Starting PHP FastCGI: "
14    start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
15    RETVAL=$?
16    echo "$PHP_CGI_NAME."
17}
18stop() {
19    echo -n "Stopping PHP FastCGI: "
20    killall -q -w -u $USER $PHP_CGI
21    RETVAL=$?
22    echo "$PHP_CGI_NAME."
23}
24
25case "$1" in
26    start)
27        start
28        ;;
29    stop)
30        stop
31        ;;
32    restart)
33        stop
34        start
35        ;;
36    *)
37    echo "Usage: php-fastcgi {start|stop|restart}"
38    exit 1
39    ;;
40esac
41exit $RETVAL

jangan lupa chmod +x supaya script dapat dieksekusi

1chmod +x /etc/init.d/php-fastcgi

Kemudian sebelum menjalankan php-fastcgi tersebut, kita bangun dulu struktur website yang akan kita gunakan. (saya memilih direktori /var/www/nginx)

1mkdir -p /var/www/nginx; cd nginx

buat file dengan nama info.php berisi phpinfo(); (sekedar melakukan testing apakah PHP sudah berjalan atau belum)

1echo "<?php phpinfo(); ?>" > info.php

kemudian edit konfigurasi Nginx agar sesuai dengan struktur website yang sedang kita bangun.

1nano /usr/local/nginx/conf/nginx.conf

Karena root public html kita berada di /var/www/nginx maka konfigurasi sebagai berikut :

  1#user  nobody;
  2worker_processes  1;
  3
  4#error_log  logs/error.log;
  5#error_log  logs/error.log  notice;
  6#error_log  logs/error.log  info;
  7
  8#pid        logs/nginx.pid;
  9
 10
 11events {
 12    worker_connections  1024;
 13}
 14
 15
 16http {
 17    include       mime.types;
 18    default_type  application/octet-stream;
 19
 20    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 21    #                  '$status $body_bytes_sent "$http_referer" '
 22    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 23
 24    #access_log  logs/access.log  main;
 25
 26    sendfile        on;
 27    #tcp_nopush     on;
 28
 29    #keepalive_timeout  0;
 30    keepalive_timeout  65;
 31
 32    #gzip  on;
 33
 34    server {
 35        listen       80;
 36        server_name  localhost;
 37
 38        #charset koi8-r;
 39
 40        #access_log  logs/host.access.log  main;
 41
 42        location / {
 43            root   /var/www/nginx;
 44            index  index.html index.htm;
 45        }
 46
 47        #error_page  404              /404.html;
 48
 49        # redirect server error pages to the static page /50x.html
 50        #
 51        error_page   500 502 503 504  /50x.html;
 52        location = /50x.html {
 53            root   html;
 54        }
 55
 56        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
 57        #
 58        #location ~ \.php$ {
 59        #    proxy_pass   http://127.0.0.1;
 60        #}
 61
 62        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
 63        #
 64        location ~ \.php$ {
 65            root           html;
 66            fastcgi_pass   127.0.0.1:9000;
 67            fastcgi_index  index.php;
 68            fastcgi_param  SCRIPT_FILENAME  /var/www/nginx$fastcgi_script_name;
 69            fastcgi_param  PATH_INFO  $fastcgi_script_name;
 70            include        fastcgi_params;
 71        }
 72
 73        # deny access to .htaccess files, if Apache's document root
 74        # concurs with nginx's one
 75        #
 76        #location ~ /\.ht {
 77        #    deny  all;
 78        #}
 79    }
 80
 81
 82    # another virtual host using mix of IP-, name-, and port-based configuration
 83    #
 84    #server {
 85    #    listen       8000;
 86    #    listen       somename:8080;
 87    #    server_name  somename  alias  another.alias;
 88
 89    #    location / {
 90    #        root   html;
 91    #        index  index.html index.htm;
 92    #    }
 93    #}
 94
 95
 96    # HTTPS server
 97    #
 98    #server {
 99    #    listen       443;
100    #    server_name  localhost;
101
102    #    ssl                  on;
103    #    ssl_certificate      cert.pem;
104    #    ssl_certificate_key  cert.key;
105
106    #    ssl_session_timeout  5m;
107
108    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
109    #    ssl_ciphers  HIGH:!aNULL:!MD5;
110    #    ssl_prefer_server_ciphers   on;
111
112    #    location / {
113    #        root   html;
114    #        index  index.html index.htm;
115    #    }
116    #}
117
118}

perhatikan bahwa saya mengganti konfigurasi root dan fastcgi_param SCRIPT_FILENAME ( video menit 7.00 )

untuk melakukan testing apakah konfigurasi yang kita buat sudah benar maka kita bisa jalankan perintah sebagai berikut :

1/usr/local/nginx/sbin/nginx -t

jika syntax dan test sukses, maka restart Nginx menggunakan file init yang tadi pada awal sudah kita buat.

1/etc/init.d/nginx restart

Test akses file info.php tadi melalui browser http://localhost/test.php

Dari situ kita dapat menentukan apakah nNginx sudah dapat berjalan dan melakukan koneksi ke php-fastcgi atau belum..

Security Issue

Layaknya sebuah aplikasi, pasti tidak akan lepas dari yang namanya bugs. Begitu juga dengan Nginx.

Nginx “no input file specified” PHP fast-cgi 0day Exploit

Setelah Nginx dan PHP CGI berjalan, cobalah test mengakses http://localhost/terserah.php

Jika browser menunjukan “no input file specified”, konfigurasi kita masih rentan dan belum layak dipakai.

Exploit : Buat file apaaja.gif menggunakan GIMP. Pada kotak komentar isi dengan script PHP <?php phpinfo(); ?> dan letakan pada direktori nginx server root (jika dalam artikel kali ini /var/www/nginx/apaaja.gif).

Nginx 0day

Secara normal, jika kita akses dari browser http://localhost/apaaja.gif akan nampak sebagai gambar .gif biasa. Tapi coba akses url dengan tersebut dari http://localhost/apaaja.gif/terserah.php maka hasilnya luar biasa :

Nginx 0day Exploit

File .gif tersebut dieksekusi sebagai file PHP (ingat comment pada file .gif <?php phpinfo(); ?>).

Tentu saja http://localhost/apaaja.gif/terserah.php sebenarnya tidak ada. Tapi tiap request yang diakhiri dengan .php akan DIEKSEKUSI sebagai script PHP oleh Nginx melalui fitur cgi.fix_pathinfo sehingga Nginx mengeksekusi file .gif tersebut sebagai script PHP!

Cara mengatasi :

  1. Ubah cgi.fix_pathinfo=1 menjadi cgi.fix_pathinfo=0 pada php.ini

  2. Edit /usr/local/nginx/conf/nginx.conf dan tambahkan sctipt berikut di antara block server { }

1error_page   400 402 403 404  /40x.html;
2   location = /40x.html {
3       root   html;
4}

LIBRARY

Nginx Configure Module options

Saat proses konfigurasi, beberapa module akan aktif secara default, dan beberapa module perlu diaktifkan secara manual.

Otomatis aktif

Berikut ini module-module yang otomatis aktif saat command ./configure dijalankan, tambahkan perintah-perintah di bawah untuk me-disable module tersebut:

--without-http_charset_module: Menonaktifkan module Charset untuk re-encoding halaman web.

--without-http_gzip_module: Menonaktifkan module kompresi Gzip.

--without-http_ssi_module: Menonaktifkan Server Side Include module.

--without-http_userid_module: Menonaktifkan User ID module yang menyediakan identifikasi pengguna menggunakan cookies.

--without-http_access_module: Menonaktifkan module pembatasan akses yang memungkinkan kita untuk konfigurasi akses untuk IP range tertentu. misal : deny 192.168.1.1/24.

--without-http_auth_basic_module: Menonaktifkan Basic Authentication module. (seperti Auth Basic Apache)

--without-http_autoindex_module: Menonaktifkan Automatic Index module.

--without-http_geo_module: Menonaktifkan module yang memungkinkan kita untuk mendefinisikan variabel menurut IP range tertentu.

--without-http_map_module: Module ini memungkinkan kita untuk mengklasifikasikan suatu nilai menjadi nilai yang berbeda, menyimpan hasilnya dalam bentuk variabel.

--without-http_referer_module: Module ini memungkinkan untuk memblokir akses berdasarkan header http referer.

--without-http_rewrite_module: Menonaktifkan module Rewrite.

--without-http_proxy_module: Menonaktifkan module HTTP proxy untuk request transfer ke server lain (reverse proxy).

--without-http_fastcgi_module: Menonaktifkan module untuk interaksi dengan proses FastCGI.

--without-http_memcached_module: Menonaktifkan module untuk interaksi dengan daemon memcache.

--without-http_limit_zone_module: Module ini memungkinkan untuk membatasi jumlah koneksi untuk alamat / direktori tertentu.

--without-http_limit_req_module: Menonaktifkan module limit request yang memungkinkan kita untuk membatasi jumlah request per user.

--without-http_empty_gif_module: Menampilkan gambar .gif transparan berukuran 1px x 1px. (sangat berguna untuk web designer)

--without-http_browser_module: Menonaktifkan module yang menungkinkan kita untuk membaca string User Agent.

--without-http_upstream_ip_hash_module: Menonaktifkan module IP-hash untuk load-balancing ke upstream server.

Tidak otomatis aktif

Berikut ini module-module yang tidak aktif saat command ./configure dijalankan, tambahkan perintah-perintah di bawah untuk me-enable module tersebut:

--with-http_ssl_module: Mengaktifkan module SSL untuk website menggunakan protokol https://.

--with-http_realip_module: Mengaktifkan module untuk membaca alamat IP yang sebenarnya dari sebuah request (biasanya didapat dari HTTP header trusted proxy).

--with-http_addition_module: Mengaktifkan module yang memungkinkan kita menambahkan data ke halaman website.

--with-http_xslt_module: Mengaktifkan module untuk transformasi XSL ke XML. Catatan: Perlu menginstal libxml2 dan libxslt library.

--with-http_image_filter_module: Mengaktifkan module yang memungkinkan kita untuk modifikasi gambar. Catatan: Perlu menginstal libgd library untuk module ini.

--with-http_sub_module: Mengaktifkan module untuk melakukan replace teks dalam halaman web.

--with-http_dav_module: Mengaktifkan fitur WebDAV

--with-http_flv_module: Mengaktifkan module khusus untuk meng-handle flash video file (.flv).

--with-http_gzip_static_module: Mengaktifkan module GZIP static compression.

--with-http_random_index_module: Mengaktifkan module untuk memilih file secara acak sebagai index file pada suatu direktori.

--with-http_secure_link_module: Mengaktifkan module untuk memeriksa request URL dengan security token yang dibutuhkan. (Mantap juga buat antisipasi CSRF)

--with-http_stub_status_module: Mengaktifkan module yang menggenerate server statistik dan informasi proses web server.

Miscellaneous options

--with-ipv6: Mengaktifkan IPv6

Menambahkan third-party module yang bisa di download dari internet. Misal dari http://wiki.nginx.org/3rdPartyModules (asli keren2).

1--add-module=/folder/ke/module/tambahan

Seperti yang kita lihat, perintah yang cukup mudah untuk konfigurasi sebuah web server. Pada umunya kita hanya perlu untuk menambahkan module SSL untuk konten HTTPS, dan “Real IP” untuk mengambil alamat IP pengunjung jika menggunakan proxy atau kita menjalankan Nginx sebagai backend server dengan web server lain.

Contoh untuk konfigurasi dengan semua module :

1./configure --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module

Untuk referensi bahan bacaan :