MySQL: "Access denied for user 'debian-sys-maint'@'localhost'"

Pengguna Ubuntu mungkin pernah sering ketemu error kayak gini:

[email protected]:~$ sudo /etc/init.d/mysql restart
* Stopping MySQL database server mysqld [fail]
* Starting MySQL database server mysqld [ OK ]
/usr/bin/mysqladmin: connect to server at 'localhost' failed error: 'Access denied for user 'debian-sys-maint'@'localhost' (using password: YES)'

“debian-sys-maint” adalah MySQL user yang dibuat supaya Ubuntu bisa start / stop database dan melakukan operasi2 maintenance lain. Terus knapa ada error “access denied”?

Masalah ini terjadi biasanya karena ketika update MySQL, password user debian-sys-maint ngga ikut terupdate bersamaan dengan file konfigurasi yang baru. Tapi ternyata solusinya cukup simple:

Pertama, liat isi file /etc/mysql/debian.cnf

[email protected]:~$ sudo cat /etc/mysql/debian.cnf

Isinya kurang lebih akan seperti ini:

# Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host = localhost
user = debian-sys-maint
password = n4aSHUP04s1J32X5
socket = /var/run/mysqld/mysqld.sock
 
[mysql_upgrade]
user = debian-sys-maint
password = n4aSHUP04s1J32X5
socket = /var/run/mysqld/mysqld.sock basedir = /usr

Perhatikan pada direktif password, itu adalah password user debian-sys-main yang kita cari. Selanjutnya, execute perintah MySQL untuk update password user debian-sys-maint sekaligus memberikan privilege yang diperlukan. Login kedalam MySQL server menggunakan root:

[email protected]:~$ mysql -uroot -p

Issue perintah GRANT untuk memberikan privilege:

mysql> GRANT ALL PRIVILEGES ON . TO 'debian-sys-maint'@'localhost' IDENTIFIED BY 'n4aSHUP04s1J32X5';

Selesai! Dan sekarang kalau kita restart MySQL, seharusnya ngga bakalan ada lagi error “access denied”.

[email protected]:~$ sudo /etc/init.d/mysql restart
* Stopping MySQL database server mysqld [ OK ]
* Starting MySQL database server mysqld [ OK ]
* Checking for corrupt, not cleanly closed and upgrade needing tables.

Cara Backup & Restore Database MySQL

Berikut ini adalah cara melakukan backup dan restore database MySQL melalui command line pada komputer Linux atau Windows yang udah terinstall MySQL Client. Daripada menggunakan tool seperti PhpMyAdmin saya lebih suka menggunakan cara seperti ini karena lebih cepat, praktis, dan ngga terbatasi dengan ukuran file backup oleh PHP jika menggunakan PhpMyAdmin. PHP biasanya membatasi ukuran file backup sebesar 2-5 megabytes. Untuk melakukan backup;

mysqldump -uscylla -pscylla123 -h serverlama.com scylladb > scylladb.sql

sedangkan untuk melakukan restore;

mysql -uscylla -pscylla123 -h serverbaru.net scylladb < scylladb.sql
  • scylla = username
  • scylla123 = password
  • serverlama.com & serverbaru.net = host / server tempat database berada
  • scylladb = nama database
  • scylladb.sql = file hasil backup

Perhatikan bahwa setelah opsi -u dan -p memang ngga ada spasi atau jarak.

Replikasi Database MySQL Dengan SSL Pada Debian Squeeze

Kali ini saya akan menjelaskan bagaimana melakukan replikasi database MySQL dari satu server (master) ke server lainnya (slave) dan menggunakan enkripsi SSL, sehingga sulit bagi hacker untuk sniff data ketika proses replikasi berlangsung.

Dengan melakukan replikasi kita bisa memiliki database slave yang datanya sama persis dengan database master. Semua updates yang dilakukan di sisi master akan “langsung” ter-replikasi ke slave. Perlu diingat bahwa skema seperti ini bukan untuk backup, karena apabila kita melakukan perintah DELETE pada master maka perintah tersebut juga akan tereksekusi di slave. Tapi skema seperti ini dapat berguna apabila misalnya terjadi hardware failure pada salah satu server sehingga bisa langsung switch over. Atau untuk meningkatkan performa aplikasi web, semua proses write / update dilakukan di server master, dan proses read / select dilakukan di server slave.

Tutorial ini akan menunjukkan bagaimana cara mereplikasi database koole dari server server1.ariw.net (master, IP 192.168.1.1) ke server server2.ariw.net (slave, IP 192.168.1.2). Kedua server menggunakan distro Linux Debian Squeeze. Database koole sudah terisi dengan data pada server master, dan pada server slave belum terisi apa-apa.

MySQL Replication
Install MySQL Server pada server1 dan server2 maka install dengan cara berikut;
(server1 & server2)

apt-get install mysql-server mysql-client

kita akan diminta untuk memasukkan password baru root MySQL, bukan password root linux!

New password for the MySQL "root" user:
Repeat password for the MySQL "root" user:

jika sudah terinstall lalu kita login ke MySQL (server1 dan server2) untuk mengecek apakah SSL support sudah diaktifkan atau belum;

mysql -u root -p

lalu execute perintah ini pada prompt SQL;

show variables like '%ssl%';

jika hasilnya seperti di bawah ini;

+---------------+----------+ | Variablename | Value | +---------------+----------+ | haveopenssl | DISABLED | | havessl | DISABLED | | sslca | | | sslcapath | | | sslcert | | | sslcipher | | | sslkey | | +---------------+----------+ 7 rows in set (0.07 sec)

itu berarti MySQL server sudah terinstall dengan dukungan SSL. Selanjutnya kita tinggal mengaktifkannya aja. Keluar dulu dari prompt SQL;

quit;

dan buka file file /etc/mysql/my.cnf;

vi /etc/mysql/my.cnf

pada bagian Security Features uncomment atau tambahkan line baru dengan kata “ssl”

# Security Features
## Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
## For generating SSL certificates I recommend the OpenSSL GUI "tinyca". ssl
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem

lalu restart mysql;

/etc/init.d/mysql restart

cek lagi apakah SSL sudah diaktifkan atau belum;

mysql -u root -p
show variables like '%ssl%';

outputnya harus seperti ini;

+---------------+----------+ | Variablename | Value | +---------------+----------+ | haveopenssl | YES | | havessl | YES | | sslca | | | sslcapath | | | sslcert | | | sslcipher | | | sslkey | | +---------------+----------+ 7 rows in set (0.07 sec)

ketik;

quit;

untuk keluar dari SQL prompt..

Mengkonfigurasi Master
Agar proses replikasi dapat berfungsi, kita harus mengkonfigurasi service MySQL untuk listen pada semua interface (server1). Untuk itu beri tanda # pada baris bind-address = 127.0.0.1 di /etc/mysql/my.cnf: (server1)

vi /etc/mysql/my.cnf
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           = 127.0.0.1

restart MySQL;

/etc/init.d/mysql restart

Sekarang kita akan membuat CA, server, dan client certificates yang akan dibutuhkan untuk proses enkripsi SSL. Sebagai contoh saya akan membuat certificates tersebut di direktori /etc/mysql/newcerts;

mkdir /etc/mysql/newcerts
cd /etc/mysql/newcerts

pastikan openssl sudah terinstall;

apt-get install openssl

buat CA certificate;

openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes 1000 -key ca-key.pem > ca-cert.pem

buat server certificate;

openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem > server-req.pem
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

buat client certificate;

openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem > client-req.pem
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

sehingga isi dari folder /etc/mysql/newcerts terlihat seperti ini;

root@server1:/etc/mysql/newcerts# ls -l
total 32 -rw-r--r-- 1 root root 1346 Dec 17 16:17
ca-cert.pem -rw-r--r-- 1 root root 1675 Dec 17 16:17
ca-key.pem -rw-r--r-- 1 root root 1099 Dec 17 16:17
client-cert.pem -rw-r--r-- 1 root root 1679 Dec 17 16:17
client-key.pem -rw-r--r-- 1 root root  956 Dec 17 16:17
client-req.pem -rw-r--r-- 1 root root 1099 Dec 17 16:17
server-cert.pem -rw-r--r-- 1 root root 1675 Dec 17 16:17
server-key.pem -rw-r--r-- 1 root root  956 Dec 17 16:17
server-req.pem root@server1:/etc/mysql/newcerts#

Penting! Pastikan COMMON NAME ketika membuat CA certificate dan Server certificate harus berbeda. Misal common name CA certificate adalah ca.ariw.net dan common name untuk server certificate adalah ariw.net. sekarang kita harus mentransfer ca-cert.pem, client-cert.pem, dan client-key.pem ke slave (server2), tapi sebelumnya kita buat dulu direktori /etc/mysql/newcerts di server2; (server2):

mkdir /etc/mysql/newcerts

kembali ke server1, kita bisa transfer file-file tersebut di atas tadi dengan cara; (server1):

scp /etc/mysql/newcerts/ca-cert.pem root@192.168.1.2:/etc/mysql/newcerts
scp /etc/mysql/newcerts/client-cert.pem root@192.168.1.2:/etc/mysql/newcerts
scp /etc/mysql/newcerts/client-key.pem root@192.168.1.2:/etc/mysql/newcerts

lalu, buka /etc/msql/my.cnf;

vi /etc/mysql/my.cnf

edit pada bagian * Security Features; hilangkan tanda pagar pada ssl-ca, ssl-cert, dan ssl-key dan isi dengan nilai yang sesuai;

# Security Features #
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/ #
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca". ssl
ssl-ca=/etc/mysql/newcerts/ca-cert.pem
ssl-cert=/etc/mysql/newcerts/server-cert.pem
ssl-key=/etc/mysql/newcerts/server-key.pem

restart MySQL;

/etc/init.d/mysql restart

Sekarang kita buat user MySQL yang akan digunakan oleh server2 untuk mengakses database pada server1, misal slave_user;

mysql -u root -p

pada MySQL prompt, execute perintah ini;

GRANT REPLICATION SLAVE ON . TO 'slaveuser'@'%' IDENTIFIED BY 'slavepassword'; FLUSH PRIVILEGES;
quit;

Kita harus memberitau MySQL agar membuat log untuk database koole (yang akan direplikasi). Nantinya log inilah yang akan digunakan oleh slave untuk melihat apa yang sudah berubah dari database master. Edit file /etc/mysql/my.cnf seperti ini;

vi /etc/mysql/my.cnf
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about other settings you may need to change.
server-id             = 1
logbin                = /var/log/mysql/mysql-bin.log
expirelogsdays        = 10
maxbinlogsize         = 100M
binlogdo_db           = koole

restart MySQL;

/etc/init.d/mysql restart

Langkah berikutnya kita akan mengunci (lock) database koole di server1, mengetahui master status server1, dan membuat SQL dump database koole (yang akan kita import ke server2), lalu unlock database koole agar bisa digunakan lagi;

mysql -u root -p

pada prompt MySQL execute command ini;

USE koole;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

perintah terakhir akan menampilkan output seperti ini. Catat hasilnya!

+---------------+----------+--------------+------------------+ | File          | Position | Binlogdodb | Binlogignoredb | +---------------+----------+--------------+------------------+ | mysql-bin.006 | 183      | koole     |                  | +---------------+----------+--------------+------------------+ 1 row in set (0.00 sec)

Sekarang jangan keluar dulu dari prompt MySQL, karena kalau keluar database akan otomatis unlock. Buka satu lagi prompt bash / Linux di server1;

cd /tmp
mysqldump - u root -ppasswordrootmysql --opt koole > snapshot.sql
scp snapshot.sql root@192.168.1.2:/tmp

Kalau proses transfer sudah selesai kita boleh close prompt Linux, kemudian unlock dan keluar dari database koole; (server1):

UNLOCK TABLES;
quit;

Konfigurasi Slave
Di server slave kita buat database koole;

mysql -u root -p Enter password:
CREATE DATABASE koole;
quit;

lalu import mysql dump dari server master yang tadi sudah dibuat (snapshot.sql)

mysql -u root -p koole < /tmp/snapshot.sql

Penting: ngga ada spasi antara -p dan koole

Sekarang kita kasitau server slave bahwa dia adalah slave, masternya adalah 192.168.1.1, dan database yang harus dimonitor di master adalah koole. Untuk itu tambahkan / edit baris berikut di /etc/mysql/my.cnf;

server-id=2
master-host=192.168.1.1
master-user=slaveuser
master-password=slavepassword
master-connect-retry=60
replicate-do-db=koole

restart MySQL;

/etc/init.d/mysql restart

Langkah berikutnya;

mysql -u root -p Enter password:
SLAVE STOP;

masih di sql prompt yang sama;

CHANGE MASTER TO MASTERHOST='192.168.1.100', MASTERUSER='slaveuser', MASTERPASSWORD='slavepassword', MASTERLOGFILE='mysql-bin.006', MASTERLOG_POS=183;

MASTERHOST adalah ip address atau hostname server master (dalam contoh ini 192.168.1.1). MASTERUSER adalah user yang diberikan akses untuk melakukan replikasi di database master. MASTERPASSWORD adalah password user replikasi di server master. MASTERLOGFILE adalah file log yang terlihat ketika kita mengetikkan perintah SHOW MASTER STATUS; di server master tadi. MASTERLOG_POS adalah posisi terakhir MySQL ketika kita mengetikkan perintah SHOW MASTER STATUS; di server master. Langkah terakhir adalah start slave, masih di prompt sql server slave;

START SLAVE;
quit;

Selesai! Sekarang coba tes lakukan update di server master dan lihat apakah ada perubahan di server slave 😉

Uninstall MySQL Server 5 dari Debian

Saya bener2 mengacaukan MySQL server semalam. Niat awalnya mau upgrade MySQL server 5.1 menjadi 5.5, tapi yang terjadi adalah setelah upgrade MySQL 5.5 ngga bisa start. Mungkin ada perbedaan konfigurasi, karena pada versi 5.1 sebelumnya saya menggunakan konfigurasi yang sudah dicustom untuk lowend VPS.

Beruntung ada VPS backup yang sudah terinstall MySQL 5.1, jadi website masih tetap bisa online setelah melakukan backup-restore database.

Balik lagi ke urusan MySQL 5.5 yang ngadat tadi, saya pun akhirnya mencoba untuk meng-uninstall MySQL server 5.5 tersebut, termasuk menghapus data yang terletak di /var/lib/mysql. Dan ketika saya coba execute perintah

apt-get remove --purge mysql-server

perintah tadi cuma menghapus sesuatu yang berukuran ~86 kilobytes. Sepertinya “mysql-server” itu sebuah shortcut. Nama software yang sebenarnya adalah “mysql-server-5.1” atau “mysql-server-5.5”. Disuruh start ngga mau, tapi di-uninstall juga ngga bisa, mengecewakan sigh.

OK lalu saya mencoba perintah berikut untuk menghapus MySQL server:

apt-get remove --purge mysql-server*

yep, dan akhirnya seluruh instalasi MySQL server musnah, bersih!

Install Lighttpd Dengan PHP5 Dan MySQL Pada Debian 6 (Squeeze)

Merasa bosan dengan Apache, akhirnya saya memutuskan untuk menggunakan Lighttpd sebagai web server di blog ini. Yep, sekarang saya udah ngga menggunakan shared hosting lagi, tapi Virtual Private Server (VPS) yang menggunakan Debian sebagai sistem operasinya.

Lighttpd saya rasakan memang lebih ringan, ngga menghabiskan banyak memory seperti Apache. Dan satu fitur yang paling saya sukai adalah mod-simple-vhost yang memudahkan kita untuk menambah virtual host atau domain. Tapi itu nanti aja akan saya bahas di posting berikutnya 😉

Install MySQL 5
Pertama kita menginstall MySQL 5 dengan cara seperti ini;

apt-get install mysql-server

Kita akan diminta memasukkan password root MySQL – password yang digunakan untuk user [email protected]

Install Lighttpd
Karena Lighttpd udah tersedia di repo Debian, jadi kita bisa install dengan apt-get;

apt-get install lighttpd

Sekarang coba gunakan browser untuk mengakses server, misal dengan alamat http://192.168.0.100 dan harusnya akan tampil halaman placeholder.

Default document root Lighttpd untuk Debian adalah /var/www, dan file konfigurasinya ada di /etc/lighttpd/lighttpd.conf. File konfigurasi tambahan ada di direktori /et/lighttpd/conf-available. File konfigurasi tersebut dapat diaktifkan dengan menggunakan perintah lighttpd-enable-mod, yang akan membuat smbolic link dari /etc/lighttpd/conf-available ke /etc/lighttpd/conf-enabled.

Install PHP5 PHP5 di Debian menggunakan FastCGI dan diinstall dengan cara berikut;

apt-get install php5-cgi

Mengkonfigurasi Lighttpd dan PHP5 Untuk mengaktifkan PHP5 pada Lighttpd, kita harus mengedit file /etc/php5/cgi/php5.ini dan uncomment pada baris cgi.fix_pathinfo=1;

vi /etc/php5/cgi/php.ini
; cgi.fixpathinfo provides *real* PATHINFO/PATHTRANSLATED support for CGI. PHP's ; previous behaviour was to set PATHTRANSLATED to SCRIPTFILENAME, and to not grok ; what PATHINFO is. For more information on PATHINFO, see the cgi specs. Setting ; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting ; of zero causes PHP to behave as before. Default is 1. You should fix your scripts ; to use SCRIPTFILENAME rather than PATHTRANSLATED. ; http://php.net/cgi.fix-pathinfo
cgi.fixpathinfo=1

Lalu aktifkan konfigurasi fastcgi dengan menggunakan perintah berikut;

lighttpd-enable-mod fastcgi lighttpd-enable-mod fastcgi-php

Perintah ini membuat symlink /etc/lighttpd/conf-enabled/10-fastcgi.conf yang mengarah ke /etc/lighttpd/conf-available/10-fastcgi.conf

ls -l /etc/lighttpd/conf-enabled
total 0
lrwxrwxrwx 1 root root 33 Feb 17 18:02 10-fastcgi.conf -&gt; ../conf-available/10-fastcgi.conf
lrwxrwxrwx 1 root root 37 Feb 17 18:04 15-fastcgi-php.conf -&gt; ../conf-available/15-fastcgi-php.conf

Test Instalasi PHP5 Sekarang saatnya mengetes instalasi Lighttpd + PHP5. Document root default nya ada di /var/www. Kita akan coba membuat sebuah halaman php (phpinfo.php) yang menampilkan seluruh detail tentang konfigurasi PHP5 di server, misalnya versi PHP5 yang terinstall atau letak direktori document root.

vi /var/www/phpinfo.php

Lalu coba akses menggunakan browser, misal http://192.168.0.100/phpinfo.php

MySQL dan PHP5
Untuk mengaktifkan support MySQL pada PHP kita cukup menginstall paket php5-mysql

apt-get install php5-mysql

Atau bisa juga menginstall beberapa modul PHP lainnya sekaligus untuk dukungan aplikasi web yang lebih lengkap, tapi sebenarnya ngga saya anjurkan karena nantinya Lighttpd akan mengkonsumsi lebih banyak memory

apt-get install php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

Jika udah selesai proses instalasinya, sekarang refresh halaman http://192.168.0.100/phpinfo.php dan arahkan ke bagian modules di bawah. Harusnya akan terlihat detail tentang modul MySQL