Why this matters for PCI DSS
PCI DSS 4.0 Requirement 1.4.1: "NSCs are implemented between trusted and untrusted networks." That means your perimeter must block inbound traffic to every port that doesn't have a documented business need. Requirement 2.2.4 requires that only necessary services, protocols, and daemons are enabled.
Practically: a publicly reachable database is a one-step away from a full breach if any credential leaks, any default password exists, or any unpatched CVE applies. The PCI assessor will fail you on the open port alone — they don't need to prove exploitation.
How to fix it
Cloud (AWS/Azure/GCP) — fix at the security group / NSG level, which is the cheapest place to block. AWS example:
aws ec2 revoke-security-group-ingress \
--group-id sg-0123456789abcdef \
--protocol tcp --port 3306 --cidr 0.0.0.0/0
Replace with a rule allowing only your application servers' security group, or a VPN CIDR.
Linux server — bind the service to localhost so it can't accept external connections. For MySQL, edit /etc/mysql/my.cnf:
[mysqld]
bind-address = 127.0.0.1
For PostgreSQL, edit postgresql.conf: listen_addresses = 'localhost'.
Then add a host firewall belt to the suspenders:
sudo ufw default deny incoming
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Windows — use Windows Firewall. The principle is the same: default-deny inbound, allow only the specific ports your application requires.
Verify externally with Shodan (search your IP) or run nmap -Pn -p- example.com from outside your network.