Reverse Proxy from HTTP to HTTPS with Apache

The other day, I had problem accessing an HTTPS site from a Python script. Since I had no time to spend figuring out why (it was for a personal project anyway), I decided to make a reverse proxy using Apache. However, unlike the commonly setup reverse proxy, this one is to make an HTTPS site available as HTTP site.

This is what I needed to put in my Apache config.

<VirtualHost 127.0.0.1:12345>
    ...
    SSLProxyEngine On
    ProxyPass / https://that.secure.site/
    ProxyPassReverse / https://that.secure.site/
    ....
</VirtualHost>

I also had to enable mod_proxy and mod_ssl which can be done easily (on Debian based system) by running the following command

# a2enmod proxy ssl

Then reload or restart Apache

# service apache2 reload

The most important bit in the config above is SSLProxyEngine On. Without this the proxy would not work!

Reverse Proxy dari HTTP ke HTTPS

Masalah lain yang saya temui setelah nyadar kalo tempat saya naro file RSS blog gak bisa diakses adalah ternyata si jadul PlanetPlanet kombinasi dg Python 2.7 punya masalah saat nyedot data dari situs https ini. Entah apakah ini kasus spesifik atau ngga, saya kurang tau 😛

Saat saya menjalankan si PlanetPlanet, tiba2 dia ngeluarin exception di bawah ini.

Traceback (most recent call last):
  File "/anu/itu/planet/feedparser.py", line 1893, in _open_resource
    return opener.open(request)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1215, in https_open
    return self.do_open(httplib.HTTPSConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1174, in do_open
    h.request(req.get_method(), req.get_selector(), req.data, headers)
  File "/usr/lib/python2.7/httplib.py", line 958, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 992, in _send_request
    self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 954, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 814, in _send_output
    self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 776, in send
    self.connect()
  File "/usr/lib/python2.7/httplib.py", line 1161, in connect
    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
  File "/usr/lib/python2.7/ssl.py", line 381, in wrap_socket
    ciphers=ciphers)
  File "/usr/lib/python2.7/ssl.py", line 141, in __init__
    ciphers)
TypeError: must be _socket.socket, not _socketobject

Nanya2 oom google ngga membawa hasil yang menggembirakan. Berhubung saya lagi males ngecek2 lebih jauh, jadi saya putuskan tuk bikin situs blog ini tersedia dalam modus http juga walau cuma bisa diakses dari localhost 😛 ehh ternyata sepertinya si wordpress kekeuh sekali https, tetap https (duh). Berhubung yg ini gagal, saya coba cara lain dg bikin reverse proxy aja 😀 proxy yang membungkus situs https tuk disediakan dalam http.

Kira2 begini konfigurasinya

<VirtualHost 127.0.0.1:12345>
    ...

    SSLProxyEngine On
    ProxyPass / https://fajran.web.id/
    ProxyPassReverse / https://fajran.web.id/

    ...
</VirtualHost>

Nyalakan modul mod_proxy dan mod_ssl dan restart/reload si apache.

Konfigurasi di atas mirip dg cara membuat reverse proxy biasa, namun ada bagian penting yang ngga boleh kelupaan ditulis: SSLProxyEngine On. Tanpa ini, proxy dari http ke https ngga bisa jalan.

Membuat sendiri sumber data untuk MRTG

Biasanya data yang digunakan oleh MRTG berasal dari SNMP server. Namun ternyata kita juga bisa menyiapkan sendiri data yang kemudian akan digunakan oleh MRTG.

Grafik MRTG di atas adalah jumlah rata-rata koneksi HTTP yang terbangun ke Kambing. MRTG mengambil data ini setiap lima menit dari skrip yang saya siapkan sendiri. Bagaimana cara menghubungkannya?

Pertama2, siapkan skrip yang akan menghasilkan dua buah data. Dua data ini akan menjadi data input dan output bagi MRTG. Keluaran harus ditulis dalam format berikut.

input
output

komentar

Baris pertama dan kedua masing-masing berisi sebuah angka yang menggambarkan besar masukan dan keluaran data yang ingin dipantau. Baris ketiga adalah sebuah baris kosong dan baris terakhir berisi komentar.

Tuk mendapatkan jumlah koneksi HTTP dimana Kambing menggunakan nginx sebagai HTTP servernya, saya hanya menggunakan informasi yang diberikan oleh aplikasi netstat. Saya ambil seluruh baris yang menyatakan koneksi terhubung ke port 80 dan hitung jumlah baris tersebut. Kira2 skripnya adalah sebagai berikut.

#!/bin/sh

NUM=`netstat -ant | grep :80 | grep ESTABLISHED | wc -l`

echo $NUM
echo $NUM
echo
echo Established HTTP Connections

Sebenarnya saya hanya butuh sebuah angka yang menggambarkan jumlah koneksi. Berhubung MRTG meminta dua angka, ya sudah saya tuliskan angka yang sama saja.

Lalu untuk konfigurasi MRTGnya sendiri, tuliskan path skrip tadi dalam isian Target. Path ditulis di dalam sepasang backtick. Contoh:

Target[kambing.http]: `/path/ke/mrtg-num-http.sh`

Simpan konfigurasi MRTG dan tunggu beberapa waktu sampai MRTG mendapatkan data yang cukup untuk mulai membuat grafik. Oh iya, jangan lupa mengatur agar skrip tadi bisa dieksekusi.

Catatan tambahan: Saya tidak membedakan jumlah koneksi masuk dan keluar dalam skrip di atas. Agar data yang ditampilkan lebih menggambarkan kondisi asli, tentu saja perlu dibuat skrip yang lebih canggih, yang bisa mengeluarkan dua angka berbeda, yaitu jumlah koneksi masuk dan keluar. Ada yang mau membuat? =D

Referensi: http://lena.franken.de/mrtg/

Log nginx: “-” 400 0 “-” “-“

Di kambing ada sejumlah (err.. sekitar 1.8% di log minggu kemarin) entry seperti berikut di log nginx-nya.

a.b.c.d - - [04/Mar/2009:00:14:01 +0700] "-" 400 0 "-" "-"

Kira2 entry tsb bisa dibaca sebagai request tidak benar (400) dan si server tidak mengirim respon apa2 (0 byte). Tidak ada informasi lain tertulis di sana.

Setelah diselidiki, salah satu penyebabnya adalah adanya koneksi HTTP yang masuk yang langsung diputuskan sehingga si server tidak dapat memberikan respon apa2.

Salah satu “pelakunya” adalah (sepertinya) sebuah bot search engine. Kira2 mengapa ya si bot2 itu berperilaku seperti itu? atau ada masalah dg nginx? humm..