Shell Scripting : Mariadb dan PhpMyAdmin

Buat file baru dengan nama database.sh
nano database.sh
isikan script berikut ini :
#!/bin/bash
# Script untuk instalasi MariaDB dan phpMyAdmin di Debian 12
# Dengan pendekatan config yang benar - hanya modifikasi blowfish_secret
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Logging function
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}
warn() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
}
# Password validation
validate_mysql_password() {
local password="$1"
if [[ ${#password} -lt 8 ]]; then
error "Password harus minimal 8 karakter"
return 1
fi
if ! [[ "$password" =~ [A-Z] ]] || ! [[ "$password" =~ [a-z] ]] || ! [[ "$password" =~ [0-9] ]]; then
error "Password harus mengandung huruf besar, huruf kecil, dan angka"
return 1
fi
return 0
}
# Get MySQL root password from user
get_mysql_password() {
local password
local password_confirm
while true; do
echo
echo "=== KONFIGURASI PASSWORD MYSQL ROOT ==="
echo "Password harus:"
echo "- Minimal 8 karakter"
echo "- Mengandung huruf besar dan kecil"
echo "- Mengandung angka"
echo
read -s -p "Masukkan password untuk MySQL root user: " password
echo
if ! validate_mysql_password "$password"; then
continue
fi
read -s -p "Konfirmasi password: " password_confirm
echo
if [[ "$password" != "$password_confirm" ]]; then
error "Password tidak cocok!"
continue
fi
MYSQL_ROOT_PASSWORD="$password"
log "Password MySQL root diterima"
break
done
}
# Secure MariaDB installation with user-provided password
install_mariadb_secure() {
log "Menginstall MariaDB server..."
export DEBIAN_FRONTEND=noninteractive
apt update
apt install -y mariadb-server unzip curl wget
log "Mengamankan instalasi MariaDB..."
systemctl start mariadb
systemctl enable mariadb
# Gunakan expect atau metode non-interactive untuk mysql_secure_installation
mysql -u root << SQL_EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;
SQL_EOF
if mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SELECT 1;" &>/dev/null; then
log "Password MySQL root berhasil dikonfigurasi"
else
error "Gagal mengkonfigurasi password MySQL root!"
exit 1
fi
}
# Download phpMyAdmin dengan fallback
download_phpmyadmin() {
log "Mendownload phpMyAdmin..."
LATEST_VERSION=$(curl -s --connect-timeout 10 https://www.phpmyadmin.net/home_page/version.txt | head -1)
if [[ -z "$LATEST_VERSION" ]] || ! [[ "$LATEST_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
warn "Gagal mendapatkan versi terbaru, menggunakan fallback: 5.2.1"
LATEST_VERSION="5.2.1"
fi
log "Menggunakan phpMyAdmin version: $LATEST_VERSION"
DOWNLOAD_URL="https://files.phpmyadmin.net/phpMyAdmin/${LATEST_VERSION}/phpMyAdmin-${LATEST_VERSION}-all-languages.zip"
if ! wget --timeout=30 -O /tmp/phpmyadmin.zip "$DOWNLOAD_URL"; then
error "Download phpMyAdmin gagal!"
exit 1
fi
}
# Setup phpMyAdmin directory and config
setup_phpmyadmin() {
log "Menyiapkan phpMyAdmin..."
rm -rf /var/www/phpmyadmin
unzip -q /tmp/phpmyadmin.zip -d /tmp/
mv /tmp/phpMyAdmin-*-all-languages /var/www/phpmyadmin
# Selalu gunakan config.sample.inc.php sebagai base
if [ -f "/var/www/phpmyadmin/config.sample.inc.php" ]; then
cp /var/www/phpmyadmin/config.sample.inc.php /var/www/phpmyadmin/config.inc.php
log "File config.inc.php dibuat dari config.sample.inc.php"
else
error "File config.sample.inc.php tidak ditemukan!"
exit 1
fi
# Konfigurasi blowfish_secret yang proper
configure_blowfish_secret
}
# Konfigurasi blowfish_secret YANG BENAR - hanya modifikasi baris yang diperlukan
configure_blowfish_secret() {
local config_file="/var/www/phpmyadmin/config.inc.php"
log "Mengkonfigurasi blowfish_secret di config.inc.php..."
# Backup file config
cp "$config_file" "${config_file}.backup"
# Cari dan replace baris blowfish_secret yang ada
if grep -q "blowfish_secret" "$config_file"; then
# Hapus baris blowfish_secret yang lama
sed -i '/blowfish_secret/d' "$config_file"
# Tambahkan blowfish_secret yang baru di bagian yang tepat
# Cari baris setelah declaration strict types
if grep -q "declare(.*strict_types" "$config_file"; then
# Tambahkan setelah strict_types declaration
sed -i '/declare(.*strict_types/a \$cfg['"'"'blowfish_secret'"'"'] = sodium_hex2bin('"'"'f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'"'"');' "$config_file"
else
# Jika tidak ada strict_types, tambahkan di area config umum
# Cari area common configuration
if grep -q "Configuration storage settings" "$config_file"; then
# Tambahkan sebelum Configuration storage settings
sed -i '/Configuration storage settings/i \$cfg['"'"'blowfish_secret'"'"'] = sodium_hex2bin('"'"'f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'"'"');' "$config_file"
else
# Tambahkan di bagian atas file setelah PHP opening tag
sed -i '1 a \$cfg['"'"'blowfish_secret'"'"'] = sodium_hex2bin('"'"'f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'"'"');' "$config_file"
fi
fi
else
# Jika tidak ada blowfish_secret, tambahkan di tempat yang tepat
if grep -q "declare(.*strict_types" "$config_file"; then
# Tambahkan setelah strict_types declaration
sed -i '/declare(.*strict_types/a \$cfg['"'"'blowfish_secret'"'"'] = sodium_hex2bin('"'"'f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'"'"');' "$config_file"
else
# Tambahkan di bagian atas file
sed -i '1 a \$cfg['"'"'blowfish_secret'"'"'] = sodium_hex2bin('"'"'f16ce59f45714194371b48fe362072dc3b019da7861558cd4ad29e4d6fb13851'"'"');' "$config_file"
fi
fi
# Verifikasi blowfish_secret berhasil ditambahkan
if grep -q "blowfish_secret" "$config_file"; then
log "blowfish_secret berhasil dikonfigurasi"
# Tampilkan baris yang berhasil dimodifikasi untuk verifikasi
log "Baris blowfish_secret yang ditambahkan:"
grep "blowfish_secret" "$config_file"
else
error "Gagal mengkonfigurasi blowfish_secret!"
exit 1
fi
}
# Set secure permissions YANG BENAR untuk phpMyAdmin
set_permissions() {
local pmadir="/var/www/phpmyadmin"
log "Mengatur permissions yang benar untuk phpMyAdmin..."
# Set ownership ke www-data agar Apache bisa baca/tulis
chown -R www-data:www-data "$pmadir"
# Set permissions yang aman tapi bisa diakses Apache
find "$pmadir" -type d -exec chmod 755 {} \;
find "$pmadir" -type f -exec chmod 644 {} \;
# Khusus config file, beri permission yang bisa dibaca Apache
chmod 644 "$pmadir/config.inc.php"
# Buat dan set permission untuk tmp directory
mkdir -p "$pmadir/tmp"
chown www-data:www-data "$pmadir/tmp"
chmod 755 "$pmadir/tmp"
log "Permissions berhasil diatur"
}
# Install PHP dependencies
install_php_deps() {
log "Menginstall PHP dan dependencies..."
# Install PHP dan ekstensi yang diperlukan untuk phpMyAdmin
local php_packages=(
php
php-fpm
php-mysql
php-mbstring
php-zip
php-gd
php-curl
php-xml
php-bz2
php-json
php-intl
)
for pkg in "${php_packages[@]}"; do
if ! dpkg -l | grep -q "^ii $pkg "; then
apt install -y "$pkg"
fi
done
# Enable PHP module di Apache
a2enmod rewrite
a2enmod headers
log "PHP dan dependencies berhasil diinstall"
}
# Create virtual host
create_virtualhost() {
log "Membuat virtualhost Apache..."
echo
echo "=== KONFIGURASI VIRTUALHOST ==="
echo -n "Masukkan ServerName untuk phpMyAdmin (contoh: pma.domain.com atau localhost): "
read SERVER_NAME
if [[ -z "$SERVER_NAME" ]]; then
SERVER_NAME="localhost"
warn "Menggunakan ServerName default: $SERVER_NAME"
fi
local vhost_file="/etc/apache2/sites-available/phpmyadmin.conf"
# Create virtualhost file
cat > "$vhost_file" << VHOST_EOF
<VirtualHost *:80>
ServerName $SERVER_NAME
DocumentRoot /var/www/phpmyadmin
<Directory /var/www/phpmyadmin>
Options FollowSymLinks
DirectoryIndex index.php
AllowOverride All
Require all granted
# Security headers
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options SAMEORIGIN
Header always set X-XSS-Protection "1; mode=block"
# PHP settings
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
</Directory>
# Logging
ErrorLog \${APACHE_LOG_DIR}/phpmyadmin_error.log
CustomLog \${APACHE_LOG_DIR}/phpmyadmin_access.log combined
# Additional security
<Directory "/var/www/phpmyadmin/setup">
Require all denied
</Directory>
</VirtualHost>
VHOST_EOF
echo "$SERVER_NAME" > /tmp/phpmyadmin_servername.txt
log "Virtualhost berhasil dibuat: $vhost_file"
}
# Enable site and services
enable_site() {
log "Mengaktifkan site dan services..."
a2ensite phpmyadmin.conf
# Disable default site jika ada
if [ -f "/etc/apache2/sites-enabled/000-default.conf" ]; then
a2dissite 000-default.conf
fi
# Restart Apache
systemctl restart apache2
# Restart MariaDB jika belum running
if ! systemctl is-active --quiet mariadb; then
systemctl start mariadb
fi
log "Services berhasil di-restart"
}
# Create phpMyAdmin database user (optional)
create_pma_user() {
log "Membuat user database khusus untuk phpMyAdmin..."
local pma_password=$(openssl rand -base64 16)
# Try to create pma user
if mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SELECT 1;" &>/dev/null; then
mysql -u root -p"${MYSQL_ROOT_PASSWORD}" << MYSQL_EOF
CREATE USER IF NOT EXISTS 'pma_user'@'localhost' IDENTIFIED BY '${pma_password}';
GRANT ALL PRIVILEGES ON *.* TO 'pma_user'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
MYSQL_EOF
if [[ $? -eq 0 ]]; then
log "User pma_user berhasil dibuat"
echo "Password pma_user: $pma_password" > /root/pma_password.txt
chmod 600 /root/pma_password.txt
else
warn "Tidak dapat membuat user pma"
fi
else
warn "Tidak dapat terhubung ke MySQL untuk membuat user pma"
fi
}
# Save credentials securely
save_credentials() {
local cred_file="/root/phpmyadmin_credentials.txt"
local server_name
if [[ -f "/tmp/phpmyadmin_servername.txt" ]]; then
server_name=$(cat /tmp/phpmyadmin_servername.txt)
else
server_name="$SERVER_NAME"
fi
# Create credentials file
cat > "$cred_file" << CRED_EOF
=== KREDENSIAL PHPYMYADMIN ===
Dibuat: $(date)
ServerName: $server_name
=== MYSQL CREDENTIALS ===
MySQL Root User: root
MySQL Root Password: ${MYSQL_ROOT_PASSWORD}
=== AKSES ===
URL: http://$server_name
Direktori: /var/www/phpmyadmin
File Konfigurasi: /var/www/phpmyadmin/config.inc.php
=== KEAMANAN ===
- Simpan file ini di tempat yang aman
- Hapus file ini setelah mencatat kredensial
- Ubah password secara berkala
CRED_EOF
chmod 600 "$cred_file"
log "Kredensial disimpan di: $cred_file"
}
# Verify installation
verify_installation() {
log "Memverifikasi instalasi..."
# Verifikasi MariaDB
if systemctl is-active --quiet mariadb; then
log "✓ MariaDB service berjalan"
else
error "✗ MariaDB service tidak berjalan"
fi
# Verifikasi Apache
if systemctl is-active --quiet apache2; then
log "✓ Apache service berjalan"
else
error "✗ Apache service tidak berjalan"
fi
# Verifikasi file config.inc.php
if [[ -f "/var/www/phpmyadmin/config.inc.php" ]]; then
log "✓ File config.inc.php ada"
# Verifikasi blowfish_secret
if grep -q "blowfish_secret" "/var/www/phpmyadmin/config.inc.php"; then
log "✓ blowfish_secret terkoneksi"
# Tampilkan baris blowfish_secret untuk verifikasi
log "Konfigurasi blowfish_secret:"
grep "blowfish_secret" "/var/www/phpmyadmin/config.inc.php"
else
error "✗ blowfish_secret tidak ditemukan"
fi
# Verifikasi strict_types declaration ada
if head -n 5 "/var/www/phpmyadmin/config.inc.php" | grep -q "strict_types"; then
log "✓ strict_types declaration ada"
else
warn "⚠ strict_types declaration tidak ditemukan"
fi
else
error "✗ File config.inc.php tidak ditemukan"
fi
# Verifikasi direktori phpMyAdmin
if [[ -d "/var/www/phpmyadmin" ]]; then
log "✓ Direktori phpMyAdmin ada"
else
error "✗ Direktori phpMyAdmin tidak ditemukan"
fi
# Verifikasi PHP sodium extension
if php -m | grep -q sodium; then
log "✓ PHP sodium extension terinstall"
else
error "✗ PHP sodium extension tidak terinstall"
fi
}
# Cleanup function
cleanup() {
log "Membersihkan file temporary..."
rm -f /tmp/phpmyadmin.zip
rm -f /tmp/phpmyadmin_servername.txt
}
# Main installation function
main() {
if [[ $EUID -ne 0 ]]; then
error "Script ini harus dijalankan sebagai root!"
exit 1
fi
clear
log "Memulai instalasi MariaDB dan phpMyAdmin di Debian 12"
echo
# Get MySQL password from user
get_mysql_password
# Installation steps
install_mariadb_secure
download_phpmyadmin
setup_phpmyadmin
install_php_deps
set_permissions
create_virtualhost
enable_site
create_pma_user
save_credentials
# Verifikasi
verify_installation
# Cleanup
cleanup
# Final output
log "=================================================="
log "INSTALASI BERHASIL!"
log "=================================================="
log "Akses phpMyAdmin: http://$SERVER_NAME"
log "MySQL Root Password: [tersimpan di /root/phpmyadmin_credentials.txt]"
log ""
log "LANGKAH SELANJUTNYA:"
log "1. Catat kredensial di /root/phpmyadmin_credentials.txt"
log "2. Setup DNS/hosts file jika menggunakan domain"
log "3. Consider setup SSL certificate"
log "4. Restrict access by IP jika needed"
log "=================================================="
}
# Run main function
main "$@"
Simpan script tersebut. beri hak akses eksekusi
chmod +x database.sh
Jika script tidak jalan, jalankan perintah berikut
sed -i 's/\r$//' database.sh
jalankan script
./database.sh