ShellScripting

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