# Apache, NGINX, Kafka, Redis, MySQL, MariaDB, and RabbitMQ Hardening

> **Intro:** These systems often end up in the same production path: web entry, API proxy, queue, cache, stream, database. In practice, compromise happens less often because "the product code was weak" and more often because a supporting service was left with default users, weak network exposure, poor auditability, or overpowered admins.
>
> **What this page includes**
>
> * must-have hardening controls for Apache HTTP Server, NGINX, Kafka, Redis, MySQL, MariaDB, and RabbitMQ
> * typical config files and common edit paths
> * example commands and starter config snippets
> * native controls versus open-source / commercial add-ons
> * patterns for controlling privileged users, preventing silent log deletion, and protecting security settings

## First principles

1. **Do not expose admin surfaces to the internet.**
2. **Turn on authentication before you rely on network rules.**
3. **Encrypt in transit, and encrypt backups with separated key ownership.**
4. **Ship audit-relevant logs off-host.** If local root can delete a log and no remote copy exists, that log is not strong evidence.
5. **Separate duties.** The same human should not be able to change config, disable logging, approve the change, and erase the evidence.
6. **Prefer native hardening first**, then add external control planes where native features are weak.

## High-level architecture

```mermaid
flowchart LR
  A[Client / upstream service] --> B[Apache or NGINX]
  B --> C[App / API]
  C --> D[Kafka / RabbitMQ]
  C --> E[Redis]
  C --> F[MySQL / MariaDB]

  G[Secrets / KMS / Vault] --> B
  G --> C
  G --> D
  G --> E
  G --> F

  H[Central logs / SIEM / object lock] --> B
  H --> D
  H --> E
  H --> F
  H --> C

  I[PAM / JIT / bastion] --> B
  I --> D
  I --> E
  I --> F
```

## Quick matrix

| System             | Must-have controls                                                                  | Typical primary config path(s)                                                                |
| ------------------ | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Apache HTTP Server | TLS, auth where needed, request limits, strong logging, minimal modules             | `/etc/httpd/conf/httpd.conf`, `/etc/apache2/apache2.conf`, `conf.d/*.conf`, `sites-enabled/*` |
| NGINX              | TLS, request limits, auth, strict proxy config, structured logs                     | `/etc/nginx/nginx.conf`, `conf.d/*.conf`, `sites-enabled/*`                                   |
| Kafka              | TLS, broker/client auth, ACL or RBAC, listener separation, log and JMX protection   | `config/server.properties`, external JAAS files, systemd env/JVM opts                         |
| Redis              | bind/protected-mode, ACLs, TLS, command restrictions, persistence protection        | `/etc/redis/redis.conf`, `/etc/redis/redis-stack.conf`                                        |
| MySQL              | network restriction, strong auth, least privilege, audit logging, backup encryption | `/etc/my.cnf`, `/etc/mysql/my.cnf`, `/etc/mysql/mysql.conf.d/*.cnf`                           |
| MariaDB            | network restriction, least privilege, audit plugin, TLS, backup protection          | `/etc/my.cnf`, `/etc/mysql/mariadb.conf.d/*.cnf`, `/etc/my.cnf.d/*.cnf`                       |
| RabbitMQ           | non-default users, TLS, vhost scoping, permissions, operator policies, central logs | `/etc/rabbitmq/rabbitmq.conf`, `/etc/rabbitmq/advanced.config`, definitions JSON              |

> **Path note:** exact locations vary by distro, package source, container image, and Helm chart. Treat the paths above as **common defaults**, not universal truth.

## Apache HTTP Server hardening

## What to enable

* keep Apache current and remove unused modules;
* run as a dedicated non-root service account after startup;
* force HTTPS and modern TLS only;
* disable risky legacy behavior and weak methods where not needed;
* set request limits to reduce abuse and resource exhaustion;
* protect admin / status locations;
* log both access and errors centrally.

## Common files and commands

```bash
# RHEL-like
sudo vi /etc/httpd/conf/httpd.conf
sudo ls /etc/httpd/conf.d/
sudo apachectl -t
sudo systemctl reload httpd

# Debian-like
sudo vi /etc/apache2/apache2.conf
sudo ls /etc/apache2/sites-enabled/
sudo apache2ctl -t
sudo systemctl reload apache2
```

## Starter controls

```apache
# Example only - adapt to your distro and modules
ServerTokens Prod
ServerSignature Off
TraceEnable Off

# Request limits
LimitRequestBody 10485760
LimitRequestFields 50
LimitRequestFieldSize 8190
LimitRequestLine 4094

# TLS in vhost
<VirtualHost *:443>
    SSLEngine on
    SSLProtocol             -all +TLSv1.2 +TLSv1.3
    SSLCompression          off
    SSLUseStapling          on
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    ErrorLog  /var/log/httpd/example-error.log
    CustomLog /var/log/httpd/example-access.log combined
</VirtualHost>
```

## What to protect especially

* `server-status` and `server-info` endpoints;
* any admin vhost or maintenance location;
* file permissions on config, certs, keys, and logs;
* modules that execute dynamic content under the web-server identity.

## NGINX hardening

## What to enable

* TLS 1.2/1.3 only unless strict compatibility needs say otherwise;
* security headers where NGINX is the browser-facing edge;
* request/body/rate limits;
* explicit upstream allow-lists and sane proxy timeouts;
* basic auth or external auth on operational surfaces;
* access and error logging in a central pipeline.

## Common files and commands

```bash
sudo vi /etc/nginx/nginx.conf
sudo ls /etc/nginx/conf.d/
sudo nginx -t
sudo systemctl reload nginx
```

## Starter controls

```nginx
http {
    server_tokens off;

    log_format main_json escape=json
      '{"time":"$time_iso8601","remote_addr":"$remote_addr","request":"$request","status":$status,"body_bytes_sent":$body_bytes_sent,"request_time":$request_time}';

    access_log /var/log/nginx/access.log main_json;
    error_log  /var/log/nginx/error.log warn;

    limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

    server {
        listen 443 ssl http2;
        ssl_protocols TLSv1.2 TLSv1.3;
        add_header X-Content-Type-Options nosniff always;
        add_header X-Frame-Options DENY always;

        location / {
            limit_req zone=perip burst=20 nodelay;
            proxy_pass http://app_backend;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /admin/ {
            auth_basic "restricted";
            auth_basic_user_file /etc/nginx/htpasswd.admin;
        }
    }
}
```

## Kafka hardening

## What to enable

* TLS for broker-to-client and broker-to-broker traffic;
* SASL or mTLS for authentication;
* ACLs or platform RBAC for authorization;
* separate listeners for internal / external use cases;
* protect JMX and metrics endpoints;
* centralize broker logs and controller logs;
* avoid plaintext and insecure demo auth in production.

## Common files and commands

```bash
sudo vi /opt/kafka/config/server.properties
sudo vi /etc/kafka/server.properties
sudo systemctl restart kafka
```

## Starter controls

```properties
listeners=INTERNAL://0.0.0.0:9093,EXTERNAL://0.0.0.0:9094
listener.security.protocol.map=INTERNAL:SASL_SSL,EXTERNAL:SASL_SSL
inter.broker.listener.name=INTERNAL
sasl.enabled.mechanisms=SCRAM-SHA-512
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512
ssl.keystore.location=/etc/kafka/secrets/broker.keystore.jks
ssl.keystore.password=${FILE:/etc/kafka/secrets/keystore.pass}
ssl.truststore.location=/etc/kafka/secrets/broker.truststore.jks
ssl.truststore.password=${FILE:/etc/kafka/secrets/truststore.pass}
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
super.users=User:broker-admin
allow.everyone.if.no.acl.found=false
```

## Operational notes

* prefer `SCRAM-SHA-512` or mTLS over weaker patterns;
* use TLS with SASL/PLAIN if PLAIN must exist at all;
* do **not** use unsecured default OAUTHBEARER examples in production;
* protect controller nodes / KRaft quorum because credential stores and metadata integrity matter.

## Redis hardening

## What to enable

* bind only to intended interfaces;
* keep `protected-mode yes` unless a strong alternative design exists;
* use ACLs instead of one shared super-password;
* require TLS where feasible;
* deny dangerous administrative commands to app identities;
* protect persistence files and backups;
* monitor ACL failures and auth failures.

## Common files and commands

```bash
sudo vi /etc/redis/redis.conf
sudo systemctl restart redis
redis-cli ACL LIST
redis-cli ACL LOG
```

## Starter controls

```conf
bind 127.0.0.1 10.0.10.15
protected-mode yes
port 0
# use TLS port in production if enabled by build/package
# tls-port 6379
# tls-cert-file /etc/redis/tls/redis.crt
# tls-key-file /etc/redis/tls/redis.key
# tls-ca-cert-file /etc/redis/tls/ca.crt

user default off
user app-user on >REDACTED ~app:* -@all +@read +@write -FLUSHALL -CONFIG -MODULE -ACL
aclfile /etc/redis/users.acl
```

## Operational notes

* use separate ACL users for apps, operators, and automation;
* monitor `ACL LOG` for failed auth and disallowed commands;
* do not expose Redis directly to the internet;
* protect RDB/AOF files and backup targets with OS permissions plus storage encryption.

## MySQL hardening

## What to enable

* restrict listening scope and require TLS where possible;
* remove unused accounts and never rely on shared admin credentials;
* create role-based least-privilege accounts;
* enable audit logging if edition/licensing supports it;
* protect and encrypt backups;
* centralize logs and use separation for DB admin versus audit-log access.

## Common files and commands

```bash
sudo vi /etc/my.cnf
sudo vi /etc/mysql/my.cnf
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
mysql -e "SHOW VARIABLES LIKE 'have_ssl';"
mysql -e "SHOW GRANTS FOR 'app'@'%';"
```

## Starter controls

```ini
[mysqld]
bind-address = 10.0.20.10
local_infile = OFF
require_secure_transport = ON
skip_name_resolve = ON
log_error = /var/log/mysql/error.log
slow_query_log = ON
slow_query_log_file = /var/log/mysql/mysql-slow.log
```

### Audit example (commercial feature)

```ini
[mysqld]
plugin-load-add = audit_log.so
audit_log_format = JSON
audit_log_file = /var/lib/mysql/audit.log
```

## MariaDB hardening

## What to enable

* same basic DB hygiene as MySQL: least privilege, network reduction, TLS, protected backups;
* enable `server_audit` or enterprise audit where required;
* log connection, query, and table events selectively to avoid unusable noise;
* send logs to file or syslog with restricted access and remote forwarding.

## Common files and commands

```bash
sudo vi /etc/my.cnf.d/server.cnf
sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf
mariadb -e "SHOW GLOBAL VARIABLES LIKE 'server_audit%';"
```

## Starter community audit controls

```ini
[mariadb]
plugin_load_add = server_audit
server_audit_logging = ON
server_audit_events = CONNECT,QUERY,TABLE
server_audit_output_type = file
server_audit_file_path = /var/log/mysql/mariadb-audit.log
server_audit_file_rotate_now = ON
server_audit_file_rotations = 10
```

## RabbitMQ hardening

## What to enable

* replace the default `guest`/default user model before first production boot;
* use TLS for client and inter-node traffic where required;
* use vhosts and granular permissions;
* use LDAP / OAuth / x509 only when operated correctly;
* protect management UI and CLI access;
* centralize logs and definitions exports;
* use operator policies as guardrails for queue resource behavior.

## Common files and commands

```bash
sudo vi /etc/rabbitmq/rabbitmq.conf
sudo vi /etc/rabbitmq/advanced.config
rabbitmqctl list_users
rabbitmqctl list_permissions -p /
rabbitmq-diagnostics listeners
```

## Starter controls

```conf
listeners.tcp = none
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/tls/ca.pem
ssl_options.certfile   = /etc/rabbitmq/tls/server.pem
ssl_options.keyfile    = /etc/rabbitmq/tls/server.key
ssl_options.verify     = verify_peer
ssl_options.fail_if_no_peer_cert = true
management.tcp.port = 15672
management.tcp.ip   = 127.0.0.1
log.file.level = info
default_user = admin-bootstrap
default_pass = REPLACE_ME_BEFORE_FIRST_BOOT
```

## Operator policy example

```bash
rabbitmqctl set_operator_policy transient-queue-ttl '^amq\.' '{"expires":1800000}' --priority 1 --apply-to queues
```

## Privileged-user and admin oversight

## The uncomfortable truth

If a person has unrestricted host root on the box and all logs remain local, you usually **cannot** stop them reliably from deleting logs, modifying configs, or tampering with data. You need **control layering**:

1. **reduce standing privilege**;
2. **centralize and protect evidence off-host**;
3. **separate administration duties**;
4. **review privileged actions independently**.

## Control patterns that actually help

### 1) Separate roles

Separate at least:

* platform / OS admin;
* service admin;
* security / audit reviewer;
* backup operator;
* KMS / HSM admin.

### 2) Use PAM / JIT / bastion access

Examples:

* SSH only through bastion or access proxy;
* temporary elevation with ticket linkage;
* MFA and session recording for privileged sessions.

### 3) Ship logs remotely and immutably enough

* forward service logs, audit logs, auth logs, and shell-session metadata to a central platform;
* restrict who can delete or alter central logs;
* for high-value environments, use object lock / WORM or storage-layer immutability.

### 4) Protect configs and backup material separately

* config repos with review requirements;
* encrypted backups;
* backup keys managed separately from primary service admins;
* restore testing with logging and approval evidence.

### 5) Review privileged actions

Examples of reviewable events:

* `ALTER USER`, `GRANT`, `REVOKE`, disabling audit plugins;
* queue policy changes, listener changes, auth backend changes;
* Redis ACL changes, dangerous command use, persistence changes;
* Kafka listener / JAAS / authorizer changes;
* Apache / NGINX admin-vhost or TLS-key changes.

## Native versus external controls

| System         | Strong native controls                                   | Native gaps                                                                | Helpful external controls                             |
| -------------- | -------------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------- |
| Apache / NGINX | TLS, auth, logs, request limits                          | no strong privileged-user governance by themselves                         | PAM/JIT, WAF, central logs, file-integrity monitoring |
| Kafka          | TLS, SASL, ACLs                                          | admin accountability often needs external workflow and platform guardrails | RBAC platforms, PAM, SIEM, secrets manager            |
| Redis          | ACLs, ACL LOG, protected mode, TLS                       | weak native separation if one superuser remains                            | bastion/JIT, SIEM, backup immutability                |
| MySQL          | roles, grants, TLS, enterprise audit                     | stronger audit often commercial                                            | DAM, SIEM, PAM, object lock                           |
| MariaDB        | community/enterprise audit, grants, TLS                  | community features may need more ops work                                  | SIEM, PAM, DAM                                        |
| RabbitMQ       | users, permissions, vhosts, TLS, operator policies, logs | no full privileged-session governance                                      | PAM/JIT, SIEM, config-governance pipeline             |

## Open-source and commercial solutions worth knowing

### Open-source / community-oriented

* **Wazuh / OSSEC / auditd** for host-level auditing and file-change visibility;
* **osquery** for config/state collection and change review;
* **Falco / Tetragon** for runtime activity monitoring on containerized deployments;
* **MariaDB Community Audit Plugin**;
* **Percona audit capabilities** where MySQL-compatible estates use Percona distributions;
* **rsyslog / syslog-ng / Fluent Bit / Vector / OpenSearch** for centralized logs.

### Commercial / enterprise-oriented

* **CyberArk / Delinea / BeyondTrust / StrongDM / Teleport Enterprise** for privileged access workflows;
* **MySQL Enterprise Audit** and **MariaDB Enterprise Audit** for richer native DB audit features;
* **IBM Guardium** / **Imperva Data Security Fabric** / similar DAM platforms for privileged DB activity monitoring;
* **Confluent RBAC / enterprise controls** where Kafka estates use the commercial platform;
* **F5 NGINX App Protect** or other WAF / API-protection layers at the ingress tier.

## Top 10 problems when these systems are configured badly

1. default users or shared admin passwords remain active;
2. service listens on all interfaces with no network reduction;
3. plaintext transport remains enabled where credentials or data cross trust boundaries;
4. broad superuser roles are reused by apps and humans;
5. audit logging is disabled, too narrow, or stored only locally;
6. backup files are readable, unencrypted, or key-managed by the same admins they protect against;
7. unsafe admin surfaces are exposed publicly or weakly protected;
8. dangerous commands are available to application identities;
9. runtime config can be changed directly without review or evidence;
10. no central detection exists for failed auth, ACL violations, or privileged changes.

## Suggested review checklist

* [ ] non-default users and credentials only
* [ ] TLS enabled where trust boundaries exist
* [ ] least-privilege service accounts only
* [ ] audit-relevant logs enabled and shipped off-host
* [ ] backups encrypted and restore-tested
* [ ] privileged access time-bounded and reviewable
* [ ] config changes flow through versioned review where possible
* [ ] local root or service admins cannot silently destroy all authoritative evidence

## Related pages

* [Web-Server Security Controls: HTTPS, CORS, CSP, and HSTS for Apache and Nginx](/application-security-and-secure-sdlc/index-2/web-server-security-headers-https-cors-csp-and-hsts-for-apache-and-nginx.md)
* [Container Isolation — seccomp, SELinux, AppArmor, Capabilities, gVisor, and Namespaces](https://github.com/D3One/Product-Security-Gitbook/blob/main/09-container-and-kubernetes-security/container-isolation-seccomp-selinux-apparmor-capabilities-gvisor-and-namespaces.md)
* [Runtime Security / Detection / Incident Response / Resilience](/attack-paths-testing-detection-and-hardening/index/runtime-security-detection-incident-response-resilience-and-platform-map.md)
* [AWS and Azure KMS / HSM Key Management Patterns](/cloud-kubernetes-and-infrastructure-security/index/aws-and-azure-kms-hsm-key-management-patterns.md)

## External references

* Apache HTTP Server Security Tips and mod\_ssl documentation
* NGINX SSL, auth\_basic, and rate-limiting module documentation
* Apache Kafka security overview and SASL / ACL guidance
* Redis security, ACL, and ACL LOG documentation
* MySQL Enterprise Audit documentation
* MariaDB Audit Plugin / Enterprise Audit documentation
* RabbitMQ access control, TLS, logging, and operator policy documentation

***

*Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/cloud-kubernetes-and-infrastructure-security/index/apache-nginx-kafka-redis-mysql-mariadb-rabbitmq-hardening-and-privileged-user-control.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
