在 Ubuntu 上部署 MySQL,很多新手容易犯两个极端错误:要么直接用 apt install mysql-server 装完就跑,完全忽略安全配置;要么被网上各种“硬核”教程搞晕,改了一堆配置文件导致服务起不来。
作为在云环境摸爬滚打多年的运维/开发,我推荐一种平衡了安全性、可维护性和标准化的安装初始化流程。这里以目前主流的云厂商(如阿里云 ECS、腾讯云 CVM)推荐的 Ubuntu 20.04/22.04 LTS 为例。
核心原则
- 最小权限原则:不要给 root 密码远程登录,不要用 root 连接业务数据库。
- 网络隔离:生产环境严禁绑定
0.0.0.0,必须通过内网 IP 或特定公网 IP 访问。 - 自动更新与补丁:利用系统自带的包管理器管理版本,避免手动编译带来的依赖地狱。
第一步:系统准备与源清理
不要急着装 MySQL,先确保系统是干净的。
# 1. 更新系统基础包
sudo apt update && sudo apt upgrade -y
# 2. 安装必要的依赖(部分镜像可能预装,但显式安装更稳妥)
sudo apt install -y curl gnupg lsb-release
# 3. 检查是否残留旧版 MySQL/MariaDB(重要!防止冲突)
dpkg -l | grep mysql
dpkg -l | grep mariadb
# 如果有残留,建议彻底清除
# sudo apt purge mysql* mariadb*
# sudo apt autoremove
注意:Ubuntu 默认源里现在通常提供的是 MySQL 8.0。如果你需要特定版本(如 5.7),需要添加官方 APT 仓库。但对于大多数新项目,直接拥抱 MySQL 8.0 是更好的选择,因为它对 JSON 支持更好,安全性更强(默认密码插件 caching_sha2_password)。
第二步:安装 MySQL Server
使用官方源安装是最省心的方式。
# 1. 下载并导入 MySQL 官方的 GPG 密钥和仓库配置
wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.29-1_all.deb
# 在执行过程中,屏幕会弹出一个菜单:
# - Select "MySQL Server & Cluster" -> Choose "mysql-8.0" (默认通常是这个)
# - Select "Tools & Utils" -> 保持默认
# - 确定后,它会更新 apt 源。
# 如果不想交互,也可以直接添加源(针对 Ubuntu 20.04/22.04):
# wget https://repo.mysql.com/apt/ubuntu/pool/main/m/mysql-community/mysql-apt-config_0.8.29-1_all.deb
# sudo dpkg -i mysql-apt-config_0.8.29-1_all.deb
# sudo apt update
# 2. 正式安装
sudo apt install mysql-server -y
安装完成后,MySQL 服务通常会自动启动。你可以检查状态:
sudo systemctl status mysql
如果没启动,执行 sudo systemctl start mysql 并设置开机自启 sudo systemctl enable mysql。
第三步:安全初始化(关键步骤)
这是大多数人忽略但决定服务器生死的一步。绝对不要跳过!
运行安全脚本:
sudo mysql_secure_installation
脚本会引导你完成以下操作,请仔细回答:
-
Validate Password Component(密码验证组件):
- 提示:
Press y|Y for Yes, any other key for No: - 建议选 Y。这会强制要求密码复杂度(长度、大小写、特殊字符、数字)。虽然有点烦,但在云上这是底线。
- 级别选择:通常选
2 (STRONG)。
- 提示:
-
Change the root password?
- 建议选 N。因为 MySQL 8.0 默认使用
auth_socket插件进行本地 root 认证,不需要密码也能通过 sudo 登录。如果你非要设密码,选 Y 并设置一个强密码。 - 专家建议:保留默认的 socket 认证更安全,因为这意味着只有拥有服务器 sudo 权限的人才能以 root 身份进入数据库,防止了远程暴力破解 root 密码的风险。
- 建议选 N。因为 MySQL 8.0 默认使用
-
Remove anonymous users?
- 必须选 Y。删除匿名账户,防止未授权访问。
-
Disallow root login remotely?
- 必须选 Y。禁止 root 用户从远程(非 localhost)登录。这是防止黑客撞库的第一道防线。
-
Remove test database and access to it?
- 必须选 Y。删除测试库,防止信息泄露。
-
Reload privilege tables now?
- 必须选 Y。立即重新加载权限表,使更改生效。
第四步:创建专用数据库用户(最佳实践)
永远不要用 root 账号连接你的应用程序。创建一个具有最小权限的业务用户。
-
进入 MySQL 命令行:
sudo mysql -
创建数据库和用户(示例):
-- 创建数据库,指定 utf8mb4 编码(支持 emoji 和多语言) CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建用户,仅限特定 IP 访问(假设应用服务器 IP 为 192.168.1.100) -- 如果应用和数据库在同一台机器,可以用 'localhost' 或 '127.0.0.1' CREATE USER 'myapp_user'@'192.168.1.100' IDENTIFIED BY 'Your_Strong_Passw0rd!'; -- 授予权限(只给该数据库的 CRUD 权限,不给 FILE, SUPER, GRANT 等高危权限) GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON myapp_db.* TO 'myapp_user'@'192.168.1.100'; -- 刷新权限 FLUSH PRIVILEGES; -- 退出 EXIT;
为什么不用
ALL PRIVILEGES? 万一应用代码有 SQL 注入漏洞,攻击者只能操作myapp_db,无法删除其他库或读取系统文件。
第五步:网络与安全组配置(云服务器特有)
这一步决定了你的数据库是否会被扫到。
-
修改 MySQL 监听地址(可选但推荐):
编辑/etc/mysql/mysql.conf.d/mysqld.cnf:[mysqld] # 将 bind-address 改为你的内网 IP,或者注释掉这行(默认是 127.0.0.1) # 如果是单机部署,保持 127.0.0.1 即可,外部通过 SSH 隧道或内网访问 bind-address = 127.0.0.1注意:如果你希望从其他服务器通过内网连接,这里要改成服务器的内网 IP,而不是
0.0.0.0。 -
重启 MySQL:
sudo systemctl restart mysql -
防火墙与安全组:
- UFW(Ubuntu 自带防火墙):如果开启了 UFW,确保 3306 端口只对可信 IP 开放。
sudo ufw allow from 192.168.1.100 to any port 3306 - 云厂商安全组(重中之重):
- 在阿里云/腾讯云的 ECS/CVM 控制台,找到“安全组”。
- 入方向规则:添加一条规则,协议 TCP,端口 3306,来源 IP 填应用服务器的内网 IP(如果是同一可用区)或应用服务器的公网 IP(如果跨地域且无专线)。
- 绝对不要将来源设为
0.0.0.0/0,除非你在做开发调试且知道风险。
- UFW(Ubuntu 自带防火墙):如果开启了 UFW,确保 3306 端口只对可信 IP 开放。
第六步:验证与监控
-
验证连接:
从应用服务器尝试连接:mysql -h <数据库服务器内网IP> -u myapp_user -p输入密码,如果能进入命令行,说明网络、权限、用户都配置正确。
-
查看日志:
如果出现奇怪的问题,第一时间看日志:sudo tail -f /var/log/mysql/error.log
常见坑点总结
- 时区问题:MySQL 8.0 默认不加载系统时区,可能导致时间查询偏差。可以在
mysqld.cnf中加上default-time-zone = '+08:00'(中国标准时间)。 - 客户端兼容性问题:如果你的应用程序非常老(如某些 PHP 5.x + PDO 的老项目),可能不支持 MySQL 8.0 默认的
caching_sha2_password认证插件。这种情况下,需要将用户认证方式改回mysql_native_password:ALTER USER 'myapp_user'@'%' IDENTIFIED WITH mysql_native_password BY 'Your_Password'; - 内存溢出:MySQL 默认配置可能占用过多内存。对于小内存云服务器(如 2G/4G),建议安装后调整
/etc/mysql/my.cnf中的innodb_buffer_pool_size,一般设置为物理内存的 50%-70%。
按照这套流程走下来,你的 MySQL 实例不仅安装成功,而且在安全基线上达到了生产环境的基本要求。
云技术博客