在管理基于CentOS的服务器时,安全性始终是运维工作的重中之重,3306端口是MySQL和MariaDB数据库系统的默认监听端口,一旦将此端口暴露在公共网络中,服务器就如同敞开大门,极易成为暴力破解、漏洞利用和恶意攻击的目标,除非有特定的远程访问需求并通过VPN等安全方式实现,否则关闭或限制对3306端口的访问是保障数据库安全的一项基本且必要的操作,本文将详细介绍在CentOS系统上关闭3306端口的几种主流方法,并提供验证步骤和最佳实践建议。

为什么需要关闭3306端口?
数据库服务器承载着网站、应用的核心数据,其价值不言而喻,默认情况下,MySQL/MariaDB会监听在所有网络接口(0.0.0:3306)上,这意味着任何知道服务器IP地址的人都可以尝试连接到数据库,攻击者可以利用自动化工具对3306端口进行扫描,并尝试使用弱口令或已知的漏洞进行入侵,成功入侵后,可能导致数据泄露、数据被篡改、勒索软件植入甚至整个服务器被控制,造成不可估量的损失,遵循“最小权限原则”,仅开放必要的端口,是构建安全服务器的基石。
关闭3306端口的方法
关闭3306端口并不意味着必须停止数据库服务,因为本地应用(如部署在同一服务器上的Web应用)仍然需要连接数据库,我们的目标是禁止外部网络访问,同时保留内部访问权限,主要有以下三种实现方法。
使用 firewalld 防火墙规则(推荐)
firewalld 是CentOS 7及以上版本默认的动态防火墙管理工具,通过配置防火墙规则,可以在网络层面阻止任何发往3306端口的请求,这是最常用且灵活的方法,因为它不影响数据库服务本身的配置。
操作步骤:
- 
检查当前端口状态 确认3306端口在防火墙中是否已开放。
firewall-cmd --zone=public --query-port=3306/tcp
如果返回
yes,表示端口已开放;返回no,则表示已关闭。 - 
永久移除端口规则 使用
--permanent参数确保规则在重启后依然生效。firewall-cmd --zone=public --remove-port=3306/tcp --permanent
执行后,系统会提示
success。 - 
重载防火墙配置 使刚才的永久更改立即生效。

firewall-cmd --reload
 - 
再次验证 确认规则已成功移除。
firewall-cmd --zone=public --query-port=3306/tcp
此时应返回
no。 
为了方便查阅,以下为关键命令的小编总结表格:
| 目的 | 命令 | 
|---|---|
| 检查端口是否开放 | firewall-cmd --zone=public --query-port=3306/tcp | 
| 关闭(移除)端口 | firewall-cmd --zone=public --remove-port=3306/tcp --permanent | 
| 使配置生效 | firewall-cmd --reload | 
| 查看所有已开放的端口 | firewall-cmd --zone=public --list-ports | 
修改数据库配置文件 bind-address
这是一种从应用层面进行控制的方法,通过修改MySQL或MariaDB的配置文件,可以指定数据库服务仅监听本地的回环地址(0.0.1),这样一来,数据库服务就只接受来自服务器自身的连接请求,从根源上杜绝了外部访问的可能。
操作步骤:
- 
找到配置文件 MySQL或MariaDB的配置文件通常位于
/etc/my.cnf或/etc/my.cnf.d/目录下的某个文件(如server.cnf)。 - 
编辑配置文件 使用
vi或nano等编辑器打开配置文件。sudo vi /etc/my.cnf
 - 
修改
bind-address在[mysqld]配置段中,找到bind-address这一行,如果不存在,则手动添加,将其值修改为0.0.1。[mysqld] # ... 其他配置 ... bind-address = 127.0.0.1
如果该行被注释掉(以 开头),或者值为
0.0.0,则表示监听所有地址,务必修改或取消注释并设置为0.0.1。
 - 
重启数据库服务 保存并退出文件后,重启数据库服务以使配置生效。
# 对于 MySQL sudo systemctl restart mysqld # 或者对于 MariaDB sudo systemctl restart mariadb
 
直接停止数据库服务
这是最极端的方法,直接关闭整个数据库服务,这种方法适用于服务器上的任何应用都不再需要数据库的临时维护场景,如果本地应用仍然需要数据库,则不能使用此方法。
sudo systemctl stop mysqld # 或 sudo systemctl stop mariadb
如何验证端口状态?
在执行完关闭操作后,验证是否成功至关重要,可以使用 ss 或 netstat 命令来查看端口监听状态。ss 是 netstat 的现代替代品,速度更快,信息更详细。
# 使用 ss 命令查看 sudo ss -tulnp | grep 3306
输出解读:
- 如果显示 
LISTEN 0 80 127.0.0.1:3306,表示3306端口仅在本机(0.0.1)上监听,这是bind-address方法生效后的结果,外部无法访问。 - 如果使用 
firewalld方法关闭,ss的输出可能仍然是*:3306或0.0.0:3306,但这不代表不安全,因为防火墙已经在外部拦截了所有请求。 - 如果没有任何输出,则表示数据库服务已停止,或者监听在其他端口上。
 
最佳实践建议
为了实现最高级别的安全,建议组合使用方法一和方法二。
- 修改 
bind-address为0.0.1:作为第一道防线,确保数据库进程本身不响应外部请求。 - 配置 
firewalld阻止3306端口:作为第二道防线,即使未来因误操作修改了bind-address,防火墙依然能提供保护。 
这种深度防御的策略可以最大限度地降低数据库的风险,还应定期更新数据库软件版本,为数据库用户设置强密码,并遵循最小权限原则为不同应用分配独立的数据库用户。
相关问答 (FAQs)
我按照方法二修改了 bind-address = 127.0.0.1,为什么服务器上的网站连接数据库失败了?
答: 这是一个常见的配置问题,当您将 bind-address 设置为 0.0.1 后,数据库只接受通过TCP/IP协议发往localhost地址的连接,确保您的网站应用程序配置文件中数据库主机(Host或DB_HOST)参数设置为 localhost 或 0.0.1,在某些PHP应用中,如果设置为 localhost,PHP会尝试使用Unix套接字文件(/var/lib/mysql/mysql.sock)连接,这通常比TCP/IP更快,请检查MySQL的套接字文件路径配置并在应用中正确设置,或者直接使用 0.0.1 强制TCP连接,请确保Web服务器进程有权限访问该套接字文件。
firewalld 关闭端口和修改 bind-address 有什么本质区别?我应该优先选择哪个?
答: 两者的工作层面不同:firewalld 是网络层/传输层的解决方案,它像一个位于服务器外部的保安,检查所有进入的网络数据包,并丢弃目标为3306端口的数据包,而数据包能否到达数据库服务程序,而修改 bind-address 是应用层的解决方案,它像是数据库程序内部的门禁规则,数据库服务启动时只绑定(监听)在本地回环接口上,从根本上就不接受来自其他网络接口的连接请求。从安全角度讲,修改 bind-address 更为彻底,因为它减少了服务的攻击面。 优先推荐使用 bind-address 方法,因为它在服务启动时就决定了监听范围,再辅以 firewalld 作为补充防御,形成一个纵深防御体系。