
Why Database Security Matters on Your VPS
Database breaches cost businesses $4.88 million per incident on average. Your VPS database holds customer records, financial data, and application secrets that attackers actively hunt.
Most hosting providers secure the server perimeter but leave database hardening to you. Default MySQL, PostgreSQL, and MariaDB installations ship with convenience settings that favor ease of use over protection.
This creates immediate vulnerabilities. This guide covers practical VPS database security measures you can implement today.
We'll focus on authentication hardening, network isolation, encryption, and monitoring techniques that work across different database engines.
User Management and Authentication Hardening
Start with user accounts. Remove anonymous users and test databases immediately after installation.
These exist for development convenience but create obvious attack vectors in production.
For MySQL and MariaDB, run the secure installation script:
sudo mysql_secure_installation
This removes anonymous users, disables remote root login, and deletes the test database. Answer "yes" to all prompts unless you have specific requirements otherwise.
PostgreSQL requires manual cleanup. Connect as the postgres superuser and remove the public schema privileges:
REVOKE CREATE ON SCHEMA public FROM PUBLIC; REVOKE ALL ON DATABASE postgres FROM PUBLIC;
Create dedicated database users for each application. Never use root or postgres accounts for application connections.
Grant only the minimum privileges needed for functionality. For a typical web application, this means SELECT, INSERT, UPDATE, and DELETE on specific tables.
Avoid GRANT ALL or database-wide permissions unless absolutely necessary.
Network Security and Access Control
Bind your database to localhost only unless you need remote connections. Edit the MySQL configuration file at /etc/mysql/mysql.conf.d/mysqld.cnf:
bind-address = 127.0.0.1
For PostgreSQL, modify postgresql.conf:
listen_addresses = 'localhost'
If you need remote database access, use specific IP addresses instead of wildcards. Update pg_hba.conf for PostgreSQL or create MySQL users with host restrictions:
CREATE USER 'appuser'@'192.168.1.100' IDENTIFIED BY 'strong_password';
Configure firewall rules to block database ports from external access. Use UFW or iptables to restrict port 3306 (MySQL/MariaDB) and 5432 (PostgreSQL) to authorized sources only.
Consider SSH tunneling for administrative access. This adds an extra authentication layer and encrypts all database traffic through the SSH connection.
HostMyCode Managed VPS servers include pre-configured firewall rules and database hardening as part of our security baseline.
Encryption Configuration for Data Protection
Enable SSL/TLS encryption for all database connections. Modern versions support this by default but require explicit configuration to enforce encrypted connections.
For MySQL 8.0 and newer, generate SSL certificates if they don't exist:
sudo mysql_ssl_rsa_setup --uid=mysql
Then require SSL connections in the configuration:
[mysqld] require_secure_transport=ON
PostgreSQL users should enable SSL in postgresql.conf:
ssl = on ssl_cert_file = 'server.crt' ssl_key_file = 'server.key'
Configure client applications to verify SSL certificates. This prevents man-in-the-middle attacks even if someone intercepts the connection.
For sensitive data, consider transparent data encryption at rest. MySQL Enterprise and PostgreSQL with extensions like pg_tde provide column-level encryption for compliance requirements.
Audit Logging and Monitoring Setup
Enable comprehensive audit logging to track database access and changes. This helps with forensics and compliance reporting.
MySQL Enterprise includes audit logging by default. For community versions, install the audit plugin:
INSTALL PLUGIN audit_log SONAME 'audit_log.so';
Configure which events to log in my.cnf:
[mysqld] audit_log_file=/var/log/mysql/audit.log audit_log_format=JSON audit_log_connection_policy=ALL audit_log_statement_policy=ALL
PostgreSQL provides built-in logging through log_statement and log_connections parameters:
log_statement = 'all' log_connections = on log_disconnections = on log_duration = on
Be careful with full statement logging in production. It captures everything including passwords in plain text.
Consider log_statement = 'ddl' for data definition changes only.
Set up log rotation to prevent disk space issues. Database logs grow quickly with detailed auditing enabled.
Backup Security and Recovery Planning
Secure your backup files as carefully as production databases. Backups often sit on shared storage with weaker access controls than live systems.
Encrypt backup files at creation time. Use mysqldump with compression and encryption:
mysqldump --single-transaction --routines --triggers database_name | gzip | gpg --cipher-algo AES256 --compress-algo 1 --symmetric > backup.sql.gz.gpg
For PostgreSQL, pg_dump supports compression but requires separate encryption:
pg_dump -Fc database_name | gpg --cipher-algo AES256 --symmetric > backup.custom.gpg
Store backup decryption keys separately from backup files. A common mistake is keeping the encryption password in the same script directory as encrypted backups.
Test restore procedures regularly. Schedule monthly restore tests to verify backup integrity and measure recovery time objectives.
For critical applications, consider point-in-time recovery capabilities. MySQL binary logs and PostgreSQL WAL archives let you recover to any specific moment before corruption or data loss.
You can also read our MySQL backup and recovery tutorial for detailed automation steps.
Database Configuration Security Settings
Review default configuration files for security-relevant parameters. Database engines ship with settings optimized for functionality rather than security.
Disable unnecessary features and functions. MySQL's LOAD_FILE() and INTO OUTFILE capabilities can read and write arbitrary files with database privileges.
Set secure defaults in my.cnf:
[mysqld] local-infile=0 secure-file-priv="" skip-show-database
PostgreSQL administrators should review shared_preload_libraries and remove unused extensions. Each loaded module expands the attack surface.
Configure connection limits to prevent resource exhaustion attacks. Set max_connections appropriately for your server resources and application requirements.
Enable query logging for suspicious patterns but balance security monitoring with performance impact. Full query logs on high-traffic databases can overwhelm storage and processing capacity.
Regular Security Maintenance Tasks
Create a monthly security checklist for database maintenance. Regular tasks prevent configuration drift and catch emerging vulnerabilities early.
Review user accounts and privileges quarterly. Remove unused accounts and audit permission grants.
Applications often accumulate excess privileges during development that remain in production.
Monitor security advisories for your database versions. Subscribe to vendor security mailing lists and apply critical patches promptly.
Check our cPanel security updates guide for control panel-specific database vulnerabilities.
Run security scanners against your database configurations. Tools like MySQL's mysql_config_editor and PostgreSQL's pg_checksums help identify common misconfigurations.
Document your security baseline and change procedures. This ensures consistent hardening across multiple servers and helps onboard new team members.
Ready to secure your database infrastructure? HostMyCode VPS hosting includes security-hardened database configurations and automated backup encryption. Our managed hosting team handles security updates and monitoring so you can focus on application development.
Frequently Asked Questions
Should I use database connection pooling for security?
Connection pooling reduces database load but creates security considerations. Pool connections use shared credentials, so compromised applications can access other application data. Use separate pools per application and configure connection limits carefully.
How often should I rotate database passwords?
Rotate database passwords quarterly or after any security incident. Use strong, unique passwords for each database user. Consider certificate-based authentication for automated systems to eliminate password rotation complexity.
What network ports do I need to secure for databases?
Secure port 3306 for MySQL/MariaDB and port 5432 for PostgreSQL. Also check for non-standard ports if you've changed defaults. Block these ports at the firewall level and restrict source IP addresses for remote access.
Do I need separate servers for different database engines?
Running multiple database engines on one server increases complexity and potential attack vectors. Separate servers provide better isolation but require more resources. Consider containerization or VPS scaling based on your security and performance requirements.
How do I secure database backups stored off-site?
Encrypt backups before uploading to cloud storage or remote servers. Use strong encryption algorithms like AES-256 and store decryption keys separately from backup files. Verify backup integrity regularly and test restore procedures from encrypted archives.