Table of Contents
Introduction
Database hardening is the process of reducing the attack surface of a database server and limiting the damage if something goes wrong. It builds on general Linux security, but focuses on the specific risks that come with storing valuable data, often accessible over the network. In practice, hardening means making deliberate choices about installation, configuration, authentication, access control, monitoring, and maintenance so that the database is resilient against both external and internal threats.
This chapter focuses on concepts and practices that apply broadly to relational databases like MySQL, MariaDB, and PostgreSQL. The details of configuration files or commands differ between engines, but the principles are consistent.
Database hardening is never a one time setup. It is an ongoing process that must be revisited regularly as software, threats, and usage patterns change.
Threat Model and Principles
Before changing configuration, you need a mental model of what you are defending against. Common threats to databases include:
Unauthorized network access to the database port.
Stolen or guessed credentials.
SQL injection through poorly written applications.
Privilege escalation by a low privileged database user.
Data exfiltration by an insider with legitimate access.
Data corruption or destruction due to compromise or mistakes.
From these risks, several hardening principles follow.
Keep the database accessible only to the systems that really need it.
Minimize the privileges of every account, human and application.
Reduce the information that an attacker can gather.
Separate duties so no single account or system can cause catastrophic damage alone.
Monitor and log so you can detect misuse or investigate incidents.
These principles guide each of the hardening measures described in the rest of this chapter.
Always start with the assumption that application code and outer layers can be bypassed. The database must be secure even if an application connected to it is compromised.
Installation and Surface Reduction
Hardening starts as early as installation. A database server that is casually installed with default options often exposes unnecessary components and weak defaults.
Use the minimal server feature set for your needs. Many database engines support optional components such as test schemas, sample databases, embedded scripting languages, or non essential plugins. If you do not need them, do not install them. Every extra feature can introduce new vulnerabilities.
If your distribution provides separate packages for client tools and server components, install server packages only on the systems that actually host the database. Likewise, do not install compilation or development tools on production database servers unless there is a strict operational need and a process to justify and audit such installations.
Disable or remove default schemas and example data that are intended for testing or tutorials. Publicly documented default objects often become an easy entry point when left in place in production.
Network Exposure and Access Control
Databases are usually accessed over TCP and each product has a default port, such as 3306 for MySQL or 5432 for PostgreSQL. Leaving a database port reachable from the entire network, especially from the public internet, is one of the most serious and common mistakes.
Bind the database service to specific interfaces or addresses. Instead of listening on all interfaces, configure the database to listen only on a private address or local interface used by application servers. If applications run on the same host, consider binding to 127.0.0.1 or a local Unix socket where supported.
Restrict which IP addresses or subnets may connect. Databases usually support host based access rules that specify allowed or denied clients. Use these controls to limit access to known application servers, administrative bastion hosts, or VPN ranges. Do not use wildcard entries that allow any host unless absolutely necessary for a controlled scenario.
Use a firewall on the server to complement database level host controls. Even if the database has its own access control lists, enforce the same restrictions at the network layer using your chosen firewall solution. This provides defense in depth and can block some traffic before it reaches the database process.
Avoid exposing the database port directly to the internet. If remote administrative access is required, use an intermediate system such as a bastion host or VPN. Administrators can connect to the bastion securely and from there access the database over an internal network, rather than opening the database to the world.
If a database port is reachable over the public internet, expect automated scans and brute force attempts against it within minutes. Treat open database ports as critical risks.
Authentication Hardening
Authentication determines who is allowed to connect. If this is weak or poorly managed, other hardening measures are easily bypassed.
Use strong passwords for all database accounts, including those used by applications. Strong means sufficiently long and unpredictable. Prefer passphrases over short complex strings. Enforce minimum length and complexity in the database engine if it supports password policies.
Avoid shared accounts where multiple people log in as the same database user. Instead, provide individual accounts for administrators and developers, and use application specific accounts for services. This makes activity traceable and allows you to revoke access for a single person or component without affecting others.
Integrate with external authentication systems when appropriate. Many database engines support authentication through LDAP, PAM, Kerberos, or other identity providers. Centralized authentication allows organization wide policies, such as account lockout, multi factor authentication at the outer layers, and streamlined offboarding.
Use certificate based or key based authentication where supported. For example, some databases allow clients to authenticate with TLS certificates mapped to database roles. This avoids passwords being transmitted or stored and can fit well into a public key infrastructure.
Disable authentication methods that are known to be insecure, such as old challenge response protocols or plain text authentication over unencrypted channels. Always prefer mechanisms that protect credentials in transit and are not vulnerable to simple replay attacks.
Authorization and Least Privilege
Authentication proves identity. Authorization decides what that identity is allowed to do. In database hardening, careful authorization design is as important as network and authentication controls.
Apply the principle of least privilege strictly for every database user and role. An application that only needs to run read queries should have read only permissions on the relevant tables, not global administrative rights. If it must write to a subset of tables, grant access only to those tables.
Separate roles by function. For example, create roles for schema management, reporting, routine application usage, and backup operations. Individual accounts can be granted membership in appropriate roles rather than receiving ad hoc privileges. This structure simplifies reviews and makes it clear who can perform sensitive actions.
Avoid using the built in superuser or root like database account for regular operations. Reserve it for rare tasks such as initial setup or emergency recovery. Operational scripts and applications should use carefully scoped roles that can be audited and, if compromised, limited in impact.
Revoke unnecessary default privileges. Some systems grant generous rights to public or anonymous roles by default, such as permission to create objects in certain schemas. Review and tighten these defaults in production environments to ensure new accounts do not inherit permissions unintentionally.
Periodically review grants and roles. Over time, permissions tend to accumulate as needs change and urgent fixes are applied. Implement a process to audit database privileges, remove unused accounts, and reduce rights that are no longer required.
Never grant full administrative privileges to an application account that faces the internet. Treat that as equivalent to giving remote attackers root level control over your database.
Secure Configuration and Feature Management
Beyond basic access controls, database engines offer many configuration options that can increase or decrease security. Thoughtful configuration is a central part of hardening.
Disable or restrict features that execute arbitrary code or external commands. Examples include stored procedures that can call shell scripts, user defined functions that load external libraries, or embedded scripting languages. If you must use such features, limit them to trusted schemas and roles, and carefully review the code that uses them.
Limit the use of dynamic SQL that concatenates user provided input into queries. While SQL injection prevention is mainly an application concern, the database side can sometimes enforce policies such as parameterized queries through prepared statement APIs. Use security settings that reduce the ability of injected input to alter control flow where they exist.
Use secure defaults for error reporting. Detailed error messages can leak internal information such as schema names, table structures, or query fragments. Configure the database to send detailed diagnostics to logs for administrators, but present minimal and generic messages to clients, especially in production.
Restrict resource usage per session or user where supported. Limits on the number of connections, query timeout, memory usage, and temporary disk space can reduce the impact of abusive queries or denial of service attempts, whether accidental or malicious.
Configure session and idle timeouts so that abandoned connections do not stay active indefinitely. Combined with proper authentication, this reduces the window in which session hijacking or misuse can occur.
Encryption in Transit and at Rest
Protecting data has two different but related concerns: safeguarding information while it crosses the network and securing stored data against unauthorized access.
Encryption in transit is typically achieved with TLS. Enable TLS support on the database server and configure it to use strong protocols and ciphers. Use certificates from a trusted certificate authority, whether internal or external, and validate them on clients to prevent man in the middle attacks. Ensure that administrator and application connections both use encrypted channels, not only external ones.
Where possible, configure the server to require TLS for all network connections, not just offer it as an option. Optional encryption can be bypassed by misconfigured clients and mixed security levels are difficult to reason about.
Encryption at rest can involve several layers. Common approaches include full disk or volume encryption at the operating system level, file system level encryption, and database native encryption of tablespaces or specific columns. Each has different trade offs between transparency and granularity.
Column level or field level encryption is useful for particularly sensitive data, such as personally identifiable information or secrets, especially when only a subset of users or components should see unencrypted values. In these cases, manage keys outside the database server whenever possible, using dedicated key management or secrets systems.
Key management is at the core of encryption. Protect encryption keys with strict access control, rotate them periodically, and store them separately from the encrypted data. If keys are stored on the same system without care, encryption at rest loses much of its security value.
Encryption is only as strong as your key management. If attackers can read both the encrypted data and the keys that unlock it, encryption does not protect you.
Backup Security and Recovery
Backups are essential for recovery but they also create copies of sensitive data. Hardening must include how backups are created, stored, and restored.
Treat backup files as highly sensitive. Apply the same or stronger access control to backup storage as to the primary database storage. Limit who can read or restore from backups and log access to backup locations.
Encrypt backups both in transit and at rest. When sending backups to remote storage, use secure transfer protocols. Store backups encrypted, preferably with keys managed separately from the storage location. This is especially important for offsite or cloud backups.
Isolate backup infrastructure. If possible, use dedicated backup servers or storage that is not directly reachable from the production network, other than what is necessary for backup traffic. This limits an attacker’s ability to exfiltrate large amounts of data quickly.
Test restores regularly. From a hardening perspective, you must be confident that if you detect a compromise or corruption, you can restore clean data. Regular restore tests also ensure that decryption and key access procedures work as intended.
Consider point in time recovery and write ahead log archiving. These mechanisms allow you to rebuild the database up to just before an incident, which can significantly reduce lost data after a security event.
Auditing, Logging, and Monitoring
Hardening is incomplete without visibility. You need to know who does what, when, and from where, and you must be able to reconstruct events after the fact.
Enable and configure database audit logging. Depending on the engine, you can log connection attempts, authentication failures, DDL changes, privilege changes, and sometimes even specific query patterns. Decide which events are critical to capture and ensure logs are stored in a reliable and tamper resistant manner.
Avoid logging sensitive values unnecessarily. While you want to know that a query was executed, logging complete query parameters that contain secrets or personal data can create new risks. Configure logging to balance forensic usefulness with privacy and data protection.
Centralize logs. Forward database logs to a central logging system so that they are not only stored on the database host. This both simplifies analysis and makes it harder for an attacker who gains access to the database server to erase their tracks completely.
Set up alerts on suspicious patterns. Examples include repeated failed logins, connections from unexpected IP addresses, sudden increases in privilege changes, or unusual spikes in data export activity. Automated alerts allow faster response than manual log review.
Keep time synchronized across systems. Accurate timestamps are essential for correlating events between application servers, database servers, and other infrastructure. Time skew can make incident analysis confusing or misleading.
If an attacker can operate inside your database without triggering logs or alerts, you are effectively blind. Visibility is a core security control, not an optional convenience.
Patching and Lifecycle Management
Database software, like any complex system, contains bugs and vulnerabilities that are discovered over time. Hardening requires a disciplined approach to updates and lifecycle.
Stay informed about security advisories for your database engine and related components, such as connectors or replication tools. Subscribe to vendor or community mailing lists, RSS feeds, or security announcement channels.
Apply security patches in a timely manner, balancing risk against uptime requirements. For production systems, maintain a staging environment where updates can be tested with representative workloads before deployment. Plan maintenance windows and automation around this process to make regular patching routine rather than exceptional.
Avoid running unsupported or end of life database versions in production. When a product leaves support, new vulnerabilities may never receive fixes. Include version upgrades in your long term planning so that they can be done in a controlled way, not as last minute emergency projects.
Document configuration changes. Many security related settings are applied through configuration files or startup parameters. Track these changes in version control or configuration management tools so you can reproduce a hardened setup, audit differences, and roll back if needed.
Segregation of Duties and Environment Isolation
Beyond technical settings, organizational and architectural decisions influence database security.
Separate responsibilities between roles. The person who manages database infrastructure should not also be the only person responsible for application development and deployment. Segregation of duties makes it harder for a single compromise or mistake to affect everything.
Isolate environments. Use separate databases or clusters for development, testing, and production. Do not copy production credentials into non production environments. When production data must be used in lower environments, consider masking or anonymizing it before transfer.
Limit direct access to production databases. Prefer application level access and controlled administrative paths through bastion hosts or specific tooling. For routine reporting or analysis, provide read only replicas or dedicated reporting instances with carefully controlled data exposure.
Hardening in High Availability and Replication
Database servers are often part of larger topologies with replication, clustering, or high availability setups. Hardening must consider these relationships.
Secure replication channels. If your database uses replication between nodes, ensure replication traffic is encrypted and authenticated. Do not rely on open trusted networks. Configure replication users with minimal rights needed for replication.
Apply consistent security policies across all nodes. A hardened primary server is of limited value if a replica is misconfigured and exposed. Review host access, firewall rules, and configurations for every node in the cluster or replication chain.
Protect failover mechanisms from abuse. Automatic failover or promotion tools usually require elevated access to manage roles or modify configuration. Ensure that access to these tools and their configuration is restricted and audited.
Continuous Improvement and Validation
Database hardening is not static. New features, application changes, and evolving threats all create a need for ongoing validation.
Perform regular security assessments focused on the database layer. This can range from internal reviews of configuration and permissions to more formal penetration tests where allowed. Use these assessments to find gaps between intended policy and actual implementation.
Use baseline configurations or templates. Define what a hardened database server should look like in your environment and use configuration management tools to enforce those baselines. Deviations from the baseline can then be detected quickly.
Integrate security checks into deployment processes. When schema changes or new applications are rolled out, include checks that verify roles and permissions remain compliant with least privilege principles, and that no insecure patterns are introduced.
Document policies and procedures. Clear documentation helps ensure that new team members understand how to interact with the database in a secure way, and it reduces the chance that workarounds quietly weaken your hardening efforts over time.
Hardening is a cycle: assess, improve, verify, and repeat. Treat it as a continuous practice rather than a one time project.
Conclusion
Database hardening weaves together multiple layers: restricted network access, strong authentication, careful authorization, secure configuration, encryption, protected backups, thorough logging, timely patching, and disciplined operational practices. Each layer compensates for weaknesses in others, and together they reduce both the chance of compromise and the impact if something does go wrong. By applying these principles consistently and revisiting them regularly, you can keep your database servers significantly more resistant to the many threats they face.