在 Ubuntu 服务器上安装 MySQL 并配置远程访问,是许多开发者从本地开发转向云端部署时的常见需求。作为长期在云计算领域摸爬滚打的技术人员,我见过太多因为权限设置不当导致的安全隐患,或者因为配置文件理解偏差导致的连接失败。
下面我将以 Ubuntu 20.04/22.04 LTS 和 MySQL 8.0+ 为例,提供一套生产环境可用的标准操作流程。整个过程分为:安装、基础安全加固、远程访问配置、以及防火墙放行。
第一步:安装 MySQL Server
Ubuntu 的官方软件源中通常包含最新稳定版的 MySQL。打开终端,执行以下命令:
# 更新包索引
sudo apt update
# 安装 MySQL Server
sudo apt install mysql-server -y
安装完成后,MySQL 服务通常会自启动。你可以检查状态:
sudo systemctl status mysql
注意:Ubuntu 18.04 及更高版本默认使用
auth_socket插件进行 root 用户认证。这意味着通过命令行(socket)登录时不需要密码,但通过网络远程登录时,root 用户默认是被禁止或受限的。这是出于安全考虑的设计,我们后续需要调整。
第二步:运行安全脚本(强烈建议)
MySQL 提供了一个安全配置脚本,用于设置 root 密码、移除匿名用户、禁用远程 root 登录等初始安全措施。
sudo mysql_secure_installation
执行过程中你会遇到几个选项:
- VALIDATE PASSWORD COMPONENT:是否启用密码强度验证插件。生产环境建议开启,避免弱口令。
- Change the root password?:如果你之前没设过密码,这里选 Y 并设置一个强密码。如果已经设过,可以选 N。
- Remove anonymous users?:选 Y。
- Disallow root login remotely?:先选 Y。为什么?因为我们要手动创建专门的远程用户,而不是直接开放 root 远程登录。这是最佳实践。
- Remove test database and access to it?:选 Y。
- Reload privilege tables now?:选 Y。
第三步:创建专用远程用户并授权
出于最小权限原则,不要直接使用 root 账号进行远程连接。我们应该创建一个专门用于应用连接的数据库用户。
- 进入 MySQL 命令行:
sudo mysql
- 执行 SQL 语句创建用户并授权。假设我们要创建一个名为
myapp_user,密码为StrongPassword123!的用户,允许从任何 IP(%)连接,并对所有数据库拥有权限(你可以根据实际需求限制特定数据库):
-- 创建用户 (适用于 MySQL 8.0+)
CREATE USER 'myapp_user'@'%' IDENTIFIED BY 'StrongPassword123!';
-- 授予权限 (根据业务需求调整)
GRANT ALL PRIVILEGES ON *.* TO 'myapp_user'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
-- 退出 MySQL
EXIT;
技术细节提示:在 MySQL 8.0 中,默认认证插件是
caching_sha2_password。大多数现代客户端库都支持它。如果你的旧版应用报错,可能需要将认证方式改为mysql_native_password,但这会降低安全性,仅建议在兼容性问题无法解决时临时使用。
第四步:修改 MySQL 监听地址
默认情况下,MySQL 只监听本地回环地址 127.0.0.1,这意味着即使防火墙开了,外部也无法连接。我们需要修改配置文件让它监听所有接口。
- 编辑 MySQL 配置文件。主配置文件通常在
/etc/mysql/mysql.conf.d/mysqld.cnf:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
- 找到
bind-address这一行。默认通常是:
bind-address = 127.0.0.1
将其修改为:
bind-address = 0.0.0.0
注:0.0.0.0 表示监听所有网络接口。如果你知道服务器的公网 IP,也可以写成具体的 IP 地址,这样更安全。
-
保存并退出(在 nano 中按
Ctrl+O,Enter,Ctrl+X)。 -
重启 MySQL 服务使配置生效:
sudo systemctl restart mysql
第五步:配置防火墙(UFW)
Ubuntu 默认使用 UFW(Uncomplicated Firewall)。你需要开放 MySQL 的默认端口 3306。
重要安全警告:在生产环境中,绝对不要对全网段(0.0.0.0/0)开放 3306 端口。你应该只允许特定的应用服务器 IP 或 CIDR 网段访问。
假设你的应用服务器 IP 是 203.0.113.5:
# 允许特定 IP 访问 3306 端口
sudo ufw allow from 203.0.113.5 to any port 3306
# 如果你使用的是阿里云/腾讯云等云厂商,还需要去控制台的安全组中添加规则
# 这里仅展示操作系统层面的 UFW 配置
sudo ufw reload
如果你确实需要从任意 IP 测试(仅限开发环境),可以使用:
sudo ufw allow 3306/tcp
第六步:验证远程连接
从另一台机器(或者同一台机器的另一个终端,如果安装了 MySQL Client)尝试连接:
mysql -h <你的服务器公网IP> -P 3306 -u myapp_user -p
输入你设置的密码。如果成功进入 MySQL 命令行,说明配置成功。
常见问题排查(Troubleshooting)
-
连接超时(Timeout):
- 检查云服务商控制台(如阿里云 ECS、腾讯云 CVM)的安全组规则。很多新手只在系统内配了防火墙,忘了在云平台层面放行端口。
- 确认
bind-address已修改且服务已重启。
-
Access denied for user:
- 检查用户名和密码是否正确。
- 检查用户的主机部分是否为
%或对应的具体 IP。如果创建用户时用了'user'@'localhost',则无法远程连接。 - 检查是否使用了正确的认证插件。
-
Can’t connect to MySQL server on ‘xxx’ (111):
- 通常是防火墙拦截或服务未监听。使用
netstat -tlnp | grep 3306查看端口是否在监听0.0.0.0:3306。
- 通常是防火墙拦截或服务未监听。使用
总结与最佳实践
- 永远不要暴露 root 账户到互联网。
- 优先使用云厂商的安全组来控制入站流量,比系统防火墙更可靠且易于管理。
- 定期备份数据库。
- 如果使用 Docker 部署,上述逻辑同样适用,只需确保容器映射端口
-p 3306:3306并挂载配置文件即可。
这套流程兼顾了功能性与安全性,适合绝大多数 Linux 服务器场景。如有特定架构需求(如主从复制、集群),还需额外配置,但基础远程访问的核心步骤是一致的。
云技术博客