Introduction
phpMyAdmin is one of the most attacked pages on any LAMP server. Automated bots scan the entire internet for /phpmyadmin around the clock, hammering it with brute-force login attempts and probing for old, exploitable versions. If you installed phpMyAdmin with the defaults and never hardened it, you have a database administration panel sitting at a predictable URL with no rate limiting. That is a problem worth fixing today.
This guide walks you through 7 essential hardening steps on Ubuntu 24.04 with Apache. Each step takes a few minutes, and together they turn phpMyAdmin from an easy target into a locked-down admin tool. The steps are: update, rename the URL, disable root login, add an Apache password layer, enforce HTTPS, add Fail2ban, and restrict access by IP.
Prerequisites
- An Ubuntu 24.04 (or 22.04) server with sudo access.
- phpMyAdmin installed via apt (the Debian/Ubuntu package) with Apache serving it.
- A domain name pointed at the server if you want HTTPS (Step 5). Steps 1-4 work without one.
Step 1: Update phpMyAdmin to the latest version
Most phpMyAdmin compromises exploit known vulnerabilities in old versions. Before hardening anything else, make sure you are running the latest version your distro ships.
sudo apt update
sudo apt upgrade phpmyadmin
The first command refreshes the package lists; the second upgrades only the phpmyadmin package so you are not accidentally pulling unrelated upgrades mid-session.
Now confirm the installed version:
dpkg -l | grep phpmyadmin
This prints the installed version (on Ubuntu 24.04 you should see 4:5.2.x). Compare it against the latest release on phpmyadmin.net. If the Ubuntu package lags far behind and you need newer fixes, consider installing phpMyAdmin manually from the official release tarball instead of apt.
Step 2: Change the default /phpmyadmin URL alias
Every scanner on the internet probes https://your-server/phpmyadmin. Renaming the alias does not stop a determined attacker, but it instantly eliminates 99% of automated noise.
Open the Apache configuration for phpMyAdmin:
sudo nano /etc/phpmyadmin/apache.conf
Find this line near the top:
Alias /phpmyadmin /usr/share/phpmyadmin
Change the alias to something unguessable, for example:
Alias /db-console-9f2kq7 /usr/share/phpmyadmin
Save, then reload Apache so the new alias takes effect:
sudo systemctl reload apache2
From now on you reach phpMyAdmin at https://your-server/db-console-9f2kq7. The old /phpmyadmin URL returns a 404. Pick a random string, not something like /admin or /pma, which scanners also try.
Step 3: Disable root login and use a limited-privilege user
phpMyAdmin lets the MySQL root user log in by default. If an attacker ever guesses or steals a phpMyAdmin password, you do not want them landing with full server-wide privileges.
First, block root from logging in through phpMyAdmin. Edit the main configuration file:
sudo nano /etc/phpmyadmin/config.inc.php
Add this line anywhere near the other $cfg['Servers'][$i] settings:
$cfg['Servers'][$i]['AllowRoot'] = false;
This setting denies the root account specifically at the phpMyAdmin login screen, while root still works normally over SSH and the MySQL console.
Next, create a dedicated admin user with limited privileges. Log in to MySQL and run:
sudo mysql
CREATE USER 'pma_manager'@'localhost' IDENTIFIED BY 'a-strong-unique-password-here';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, CREATE VIEW, SHOW VIEW ON *.* TO 'pma_manager'@'localhost';
FLUSH PRIVILEGES;
EXIT;
This grants the day-to-day privileges you actually need while withholding dangerous ones like SUPER, SHUTDOWN, and FILE, which an attacker could use to read server files or take the database down. Log in to phpMyAdmin as pma_manager from now on.
Step 4: Add an Apache password layer in front of phpMyAdmin
With HTTP Basic authentication, an attacker must defeat two separate logins: the Apache password and the phpMyAdmin password. This single step kills nearly all brute-force bots, because they cannot even reach the login form.
Create the password file and your first user:
sudo htpasswd -c /etc/phpmyadmin/.htpasswd dbgatekeeper
The -c flag creates the file (use it only the first time; repeat without -c to add more users). You will be prompted to set the password twice.
Now tell Apache to require this login for the phpMyAdmin directory. Open /etc/phpmyadmin/apache.conf again and add inside the existing <Directory /usr/share/phpmyadmin> block:
AuthType Basic
AuthName "Restricted Access"
AuthUserFile /etc/phpmyadmin/.htpasswd
Require valid-user
Reload Apache:
sudo systemctl reload apache2
Visiting your phpMyAdmin URL now shows a browser login prompt before the phpMyAdmin page ever loads. Use a different password here than the MySQL user password from Step 3.
Step 5: Force HTTPS on the phpMyAdmin page
Without HTTPS, your phpMyAdmin username, password, and every database query travel the network in plain text. If you manage the database from anywhere but the server itself, HTTPS is non-negotiable.
If you do not have a certificate yet, install one free with Certbot (replace the domain with yours):
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d db.example.com
Certbot fetches a Let's Encrypt certificate, configures Apache's SSL virtual host, and offers to redirect all HTTP traffic to HTTPS. Choose the redirect option.
Then enforce SSL inside phpMyAdmin itself. Edit /etc/phpmyadmin/config.inc.php and add:
$cfg['ForceSSL'] = true;
This makes phpMyAdmin refuse to serve over plain HTTP even if someone bypasses the Apache redirect. Verify by visiting http:// (not https) your phpMyAdmin URL: you should land on HTTPS automatically.
Step 6: Block brute-force attacks with Fail2ban
Fail2ban watches your logs and bans IP addresses that fail authentication too many times. Since Step 4 put Basic authentication in front of phpMyAdmin, failed attempts now land in Apache's error log, which Fail2ban's built-in apache-auth jail already knows how to read.
Install Fail2ban and enable the jail:
sudo apt install fail2ban -y
sudo nano /etc/fail2ban/jail.d/phpmyadmin.local
Add:
[apache-auth]
enabled = true
port = http,https
logpath = /var/log/apache2/*error.log
maxretry = 5
bantime = 3600
This bans an IP for one hour (bantime = 3600) after 5 failed logins. Start and enable Fail2ban:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status apache-auth
The status command should show the jail as active. Five wrong passwords from one IP now earns it a one-hour ban, which makes brute-forcing effectively impossible.
Step 7: Restrict access to your IP addresses
The strongest lock is a door most people cannot even see. If you always manage the database from a fixed office IP or home IP, restrict phpMyAdmin to those addresses and the page simply does not exist for everyone else.
In /etc/phpmyadmin/apache.conf, inside the same <Directory /usr/share/phpmyadmin> block from Step 4, add a Require line:
Require ip 203.0.113.45
Require ip 198.51.100.0/24
Replace these with your real public IP (find it with curl -4 ifconfig.me) and, optionally, your office subnet. Reload Apache once more:
sudo systemctl reload apache2
Anyone outside those IPs now gets a 403 Forbidden. If your IP changes often (mobile data, dynamic home broadband), skip this step rather than locking yourself out: Steps 2-6 already provide strong protection.
Verify it worked
- Visit the OLD
/phpmyadminURL: you should get a 404. - Visit your new secret alias: the browser should prompt for the Apache password (Step 4) before showing anything.
- Try logging in to phpMyAdmin as
root: it must be rejected (Step 3). Log in as your limited user instead. - Visit the page over plain
http://: it must redirect to HTTPS (Step 5). - Check Fail2ban is watching:
sudo fail2ban-client status apache-authshould list the jail with a file list. - From a different IP (phone on mobile data), confirm you get 403 if you enabled Step 7.
Common issues and fixes
404 on the new alias after Step 2. You edited the file but did not reload Apache. Run sudo systemctl reload apache2 and double-check the Alias line has no typos.
500 Internal Server Error after editing config.inc.php. A PHP syntax error, usually a missing semicolon. Check it with php -l /etc/phpmyadmin/config.inc.php and fix the reported line.
Locked out by the Apache password prompt. Reset the htpasswd user with sudo htpasswd /etc/phpmyadmin/.htpasswd dbgatekeeper (no -c) and set a new password.
Fail2ban banned your own IP. Unban it with sudo fail2ban-client set apache-auth unbanip YOUR_IP, then add your IP to ignoreip in /etc/fail2ban/jail.local.
phpMyAdmin CSS looks broken over HTTPS. Mixed-content blocking from an incomplete redirect. Re-run sudo certbot --apache and choose the redirect option, and confirm $cfg['ForceSSL'] = true; is set.
Conclusion
Those 7 steps, updates, a secret URL, no root login, a second password layer, HTTPS, Fail2ban, and IP restriction, take phpMyAdmin from "publicly probed thousands of times a day" to "effectively invisible". Security is a habit, not a one-time task: re-run updates monthly and review your Fail2ban bans occasionally to see who is knocking.
If you would rather have a professional handle server hardening, XpertBees sets up and secures LAMP/LEMP stacks, databases, and admin panels for businesses every day. Get in touch and we will lock your servers down properly.



