Tutorial Memasang Moodle di VPS

Wabah Covid-19 memaksa sekolah-sekolah di Indonesia mengadakan pembelajaran daring. Ada yang memilih memakai Google Classroom, namun banyak juga yang mencoba memakai rajanya e-learning yaitu Moodle. Sebagian sekolah yang mempunyai tim IT memakai server sendiri, dan sebagian sekolah lainnya ada yang nekat memakai jasa shared/cloud web hosting dengan alasan mudah. Umumnya shared/web hosting sudah dilengkapi cPanel. Tinggal beberapa kali klik di Softaculous, maka Moodle pun siap dipakai. Sebenarnya, web hosting dirancang untuk tugas-tugas ringan misalkan WordPress, sedangkan di sisi lain Moodle sangat haus CPU dan RAM. Maka ketika Moodle diakses serentak oleh siswa, baru 30-an saja sudah down.

Terpaksa upgrade paket. Tapi ini pun sama saja. Baru 50 siswa sudah down. Kalau pun akhirnya kuat bisa melayani 200-an siswa secara serempak, baru berjalan 2 bulan tiba-tiba Moodledata membengkak. Harus tambah disk. Celakanya, paket yang aktif saat ini adalah paket paling tinggi sehingga tidak mungkin lagi diupgrade. Padahal tarifnya lumayan mahal. Ada yang sampai Rp 1,5 jutaan perbulan.

Moodle membutuhkan CPU dan RAM yang tidak sedikit. Sangat menguras sumber daya server, sampai-sampai penyedia shared/cloud web hosting menulis peringatan: “Dilarang menggunakan hosting ini untuk kegiatan e-larning, CBT, atau yang sejenisnya.”

Begini bapak/ibu guru sekalian.
Moodle harus dipasang minimal di VPS (Virtual Private Server). Syukur-syukur bisa dedicated server. Untuk jumlah siswa antara 500-1000 orang, minimal harus ada RAM 8 GB dan CPU minimal 8 core. Disk pun sebaiknya SSD/NVMe. Bila di sekolah ada server (misalkan bekas UNBK), bisa saja server itu difungsikan menjadi server Moodle. Tapi berhubung di masa pandemi ini, siswa ada di rumah, maka harus dipastikan internet di sekolah cukup ngacir bandwidthnya. Akses Internet rumahan/kantoran (bukan khusus untuk server) biasanya dirancang untuk upload sedikit dan download banyak, padahal untuk server justru kebalikannya. Juga pastikan menggunakan router yang bagus, yang kuat melayani ratusan siswa secara serempak.
Bila tidak mau pusing dengan kerumitan penyediaan hardware dan internet, maka gunakan saja VPS. Ini cara paling murah meriah.

Tidak perlu VPS mahal. Saya pernah memakai VPS dengan tarif Rp 400 ribuan/bulan. Bisa melayani sampai 500-an siswa. Itu pun CPU dan RAM terlihat santai. Saya duga, dipakai 1000-an siswa pun seharusnya kuat. Sebenarnya kehandalan server Moodle bukan hanya ditentukan dari jumlah CPU dan RAM, tapi juga dari keahlian kita men-“tune up” Nginx, PHP, MySQL. Ibaratnya seperti sepeda motor bebek yang biasa dipakai ibu-ibu ke pasar. Bila di-tune up dengan sempurna, maka bisa dipakai untuk balapan motor.

Kali ini saya akan memberikan tutorial memasang Moodle pada VPS dengan rincian:

  • Linux Ubuntu 20.04 atau Debian 10.
  • Nginx 1.18.0.
  • MariaDB 10.3.25.
  • PHP 7.4.3.

Tanpa bantuan web host control panel (WHCP) seperti cPanel, Plesk, dll. Keuntungaannya: Server hanya diisi yang benar-benar dibutuhkan. Bila memakai WHCP, maka server diisi oleh layanan-layanan yang hanya semakin membebani server. Untuk Moodle, kita tidak perlu DNS server, anti spam, dan POP email (menerima email masuk).

Login ke VPS menggunakan PuTTY (SSH), akun root. Bila login bukan menggunakan akun root, maka tambahkan “sudo” di awal setiap perintah. Contoh: “apt -y update” menjadi “sudo apt -y update”.

Sebagai jurus pembuka, jangan lupa update dulu Sistem Operasinya. Ketik:

apt -y update && apt -y upgrade && apt -y full-upgrade && apt -y autoremove

Lalu set waktu ke timezone bapak/ibu. Untuk saya, perintahnya adalah:

timedatectl set-timezone Asia/Jakarta

Pasang editor Nano, Unzip, dan Wget.

apt -y install nano unzip wget

MEMASANG NGINX

apt -y install nginx

Setelah selesai, dilanjut dengan perintah di bawah ini:

systemctl stop nginx.service
systemctl start nginx.service
systemctl enable nginx.service

Cobalah dari peramban ketik http://xxx.xxx.xxx.xxx (xxx = IP address). Seharusnya muncul pesan “Welcome to nginx!”.

MEMASANG PHP

Kita gunakan PHP bawaan dari sistem operasi. Pada Ubuntu 20.04 adalah PHP 7.4.

apt -y install php-fpm php-common php-mbstring php-xmlrpc php-soap php-gd php-xml php-intl php-mysql php-cli php-ldap php-zip php-curl php-xsl php-memcached php-redis

Prosesnya agak lebih lama dari pada memasang Nginx.
Setelah selesai, boleh dicoba reload.

systemctl reload php7.4-fpm

MEMASANG MARIADB

MySQL 8.0 memang bagus. Tapi bila RAM di bawah 8 GB, sebaiknya gunakan MariaDB.

apt -y install mariadb-server mariadb-client

Restart untuk memastikan semuanya berjalan dengan baik.

systemctl stop mariadb.service
systemctl start mariadb.service
systemctl enable mariadb.service

Lanjutkan dengan memperkuat pertahanan MySQL dari serangan peretas.

mysql_secure_installation

Akan muncul beberapa pertanyaan. Jawablah seperti ini:

Enter current password for root (enter for none): (enter)
Set root password? [Y/n] n
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

Sekali lagi, untuk memastikan semuanya berjalan dengan baik, restart MySQL.

systemctl restart mariadb.service

Lalu kita membuat database. Misalkan kita akan membuat seperti ini:

Username: moodle@localhost
Password: Abcd1234
Database: moodle

mysql
CREATE DATABASE moodle;
CREATE USER 'moodle'@'localhost' IDENTIFIED BY 'Abcd1234';
GRANT ALL ON moodle.* TO 'moodle'@'localhost' IDENTIFIED BY 'Abcd1234' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;

MEMBUAT VHOST

Misalkan alamat Moodle adalah belajar.sekolah.sch.id

nano /etc/nginx/sites-available/belajar.sekolah.sch.id

Kemudian masukkan ini ke dalamnya.

server {
  listen 80;
  listen [::]:80;
  root /var/www/belajar.sekolah.sch.id/html;
  index index.php index.html index.htm;
  server_name belajar.sekolah.sch.id www.belajar.sekolah.sch.id;

  location / {
    try_files $uri $uri/ =404; 
  }

  location /dataroot/ {
    internal;
    alias /var/www/belajar.sekolah.sch.id/moodledata/;
  }

  location ~ [^/]\.php(/|$) {
    include snippets/fastcgi-php.conf;

    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
  }

  location ~* .(js,css,jpg,jpeg,gif,png,ico)$ {
    expires max;
    log_not_found off;
    access_log off;
  }
}

Simpan dengan menekan tombol: Ctrl+O, enter, Ctrl+X.

Agar VHOST di atas aktif, buatkan symbolic link-nya dan reload nginx.

ln -s /etc/nginx/sites-available/belajar.sekolah.sch.id /etc/nginx/sites-enabled/
systemctl restart nginx.service

MENGUNDUH MOODLE

Untuk pemakaian jangka panjang, memang lebih baik memakai git karena lebih mudah bila Moodle-nya akan diupgrade. Tapi pada tutorial ini, saya akan memakai cara klasik yaitu mengunduh file.
Pertama kali, kita siapkan folder.

mkdir /var/www/belajar.sekolah.sch.id
mkdir /var/www/belajar.sekolah.sch.id/moodledata

Mengunduh dan meng-extract Moodle.

cd /var/www/belajar.sekolah.sch.id
wget https://download.moodle.org/download.php/direct/stable310/moodle-latest-310.zip
unzip moodle-latest-310.zip
mv moodle html
chown -R www-data:www-data /var/www/belajar.sekolah.sch.id

MEMASANG SSL

Kita akan memasang LetsEncrypt tanpa bantuan Snapd. Sebenarnya lebih disarankan memakai Snapd, tapi pada beberapa VPS, Snapd tidak bisa dipakai. Langkah-langkah memasang LetsEncrypt adalah:

apt -y install software-properties-common
apt -y install python3-certbot-nginx
certbot --nginx -d belajar.sekolah.sch.id -d www.belajar.sekolah.sch.id

Ada beberapa pertanyaan yang harus dijawab. Setelah selesai, reload Nginx agar perubahan VHOST terbaca.

systemctl reload nginx

Coba buka https://www.belajar.sekolah.sch.id
Akan muncul menu instalasi. Silakan isi sesuai konfigurasi database yang dibuat di atas. Port boleh dikosongkan.

Sampai di sini, seharusnya Moodle telah siap digunakan.

MEMPERKUAT PERTAHANAN

Jangan biarkan orang asing mengobok-obok server kita. Harus dibatasi, paket apa yang boleh keluar masuk. Istilahnya adalah memasang Firewall. Netfilter adalah modul pada Linux untuk melakukan tugas ini, dan iptables adalah penghubung (interface) untuk memudahkan kita dalam mengatur netfilter. Sayangnya, tata penulisan perintah pada iptables sangat rumit. Untungnya, ada ufw yang bisa menyederhanakan kode-kode panjang iptables menjadi beberapa kata berbahasa Inggris yang lebih mudah dipahami. Cara menginstall ufw:

apt -y install ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 'nginx full'
ufw allow ssh

Arti dari perintah-perintah di atas kurang lebih berarti: Izinkan semua komunikasi ke luar, dan larang semua komunikasi ke dalam kecuali pada port-port 22 (SSH), 80 (http), dan 443 (https).

Setelah itu, aktifkan ufw dengan perintah:

ufw enable

Untuk mengetahui ip address apa saja yang berusaha masuk melalui port 22 tapi diblok oleh UFW, perintahnya adalah:

grep 'DPT=22' /var/log/ufw.log |\
egrep -o 'SRC=([0-9]{1,3}[\.]){3}[0-9]{1,3}' |\
awk -F'=' '{ print $2 }' | sort -u

Selain ufw, sebaiknya juga dipasang Fail2ban yang berguna melindungi server dari usaha penerobosan peretas melalui lapisan 7 model OSI (application layer). Cara memasangnya:

apt -y install fail2ban
chown -R www-data:www-data /var/run/fail2ban
systemctl start fail2ban
systemctl enable fail2ban

Misalkan kita ingin membatasi agar peretas tidak bisa mencoba-coba mencari kelemahan pada server kita. Caranya:

cd /etc/fail2ban
cp jail.conf jail.local
nano jail.local

Lalu sesuaikan isi file jail.local agar menjadi seperti di bawah ini:

[default]
ignoreip = 127.0.0.1 ::1

[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 2

[nginx-http-auth]
enabled  = true
filter   = nginx-http-auth
port     = http,https
logpath  = /var/log/nginx/error.log

[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 2

[nginx-unknown]
enabled  = true
port     = http,https
filter   = nginx-unknown
logpath  = /var/log/nginx/error.log
maxretry = 2

Simpan dengan menekan tombol Ctrl + O, enter, Ctrl + X.

Dilanjut dengan membuat file nginx-unknown.conf

nano filter.d/nginx-unknown.conf

Ketik kode di bawah ini:

[Definition]
failregex = \(No such file or directory\)” while reading response header from upstream, client: <ADDR>
ignoreregex = (/html/local/mobile/check.php|/html/my/login/token.php) \(No such file or directory\)” while reading response header from upstream, client: <ADDR>

Simpan dengan menekan tombol Ctrl + O, enter, Ctrl + X.
Maksud dari filter nginx-unknown adalah memblok IP address yang mencoba menerka-nerka keberadaan suatu script php. Ini ide saya sih, didasari pada pemikiran bahwa manusia biasanya berpindah-pindah antar halaman web melalui tautan (link), sedangkan bot akan langsung membuka halaman web yang dianggap berisi script php yang ada celah keamanannya.
Lalu restart Fail2ban agar konfigurasi di atas bisa diterapkan.

fail2ban-client restart

Selesai. Agar server bisa melayani lebih banyak siswa yang serentak mengakses Moodle, harus dilakukan tuning up konfigurasi pada Nginx, PHP, dan MariaDB. Tapi ini terlalu panjang bahasannya, jadi saya akhiri dulu artikel ini. Semoga bermanfaat.

Catatan penting:
Lokasi Moodle: /var/www/sekolah.sch.id/html
Lokasi Data: /var/www/sekolah.sch.id/moodledata
Lokasi Log: /var/log
Me-restart Nginx: systemctl restart nginx.service
Me-restart MariaDB: systemctl restart mariadb.service
Me-restart PHP: systemctl restart php7.4-fpm

Bila bapak/ibu ada waktu senggang, bisa membaca situs web CVE yang menjabarkan lubang-lubang security pada Moodle. Lumayan menyeramkan. Untuk mempersulit Moodle diretas (dihack), saran saya adalah: Selalu update Moodle ke versi terbaru, dan jangan memasang plugin tambahan kecuali sangat terpaksa. Bila ingin lebih aman, gunakan Theme standar, misalkan Boost atau Classic. File-file backup (zip, tar.gz, tar.bz2) jangan pernah disimpan di public_html. Simpan lah di tempat yang tidak terjangkau web browser. Sering kali, peretas hanya mencoba-coba menebak keberadaan suatu file. Itu sebabnya, kita wajib memasang Fail2ban.

MENGHAPUS VHOST DAN SERTIFIKAT LE

Suatu saat, mungkin bapak/ibu ingin menghapus instalasi Moodle dari server. Mungkin saja karena Moodle-nya akan dipindah ke server lain. Bila tidak dihapus, maka LetsEncrypt akan terus diperbarui sertifikatnya. Ini tentu menambah beban server dan membuat server menjadi tidak rapi (berantakan). Tidak fatal sih, tapi tidak nyaman saja dilihatnya.

Langkah-langkah menghapus Vhost dan Sertifikat LetsEncrypt adalah seperti di bawah ini. Jangan lupa ganti belajar.domain.sch.id.

mydomain=belajar.domain.sch.id
cd /etc/nginx
sudo rm sites-available/$mydomain
sudo rm sites-enabled/$mydomain
sudo nginx -t
sudo service nginx restart
sudo certbot delete –cert-name $mydomain
certbot certificates

Semoga bermanfaat.

Web Hosting