1. MySQL 数据库授权表
MySQL 数据库管理软件将权限信息都存放于 mysql 库下,该库下有一系列授权 表,权限信息都存放于这一系列表中,下面介绍几个常用的授权表:
- mysal.user
- 存储内容:用户账户和全局权限
- 权限范围:
- 服务器级别的全局权限
- 影响所有数据库的权限
- msyql.db
- 存储内容:数据库级别的权限
- 权限范围:特定数据库的操作权限
- tables_priv
- 存储内容:表级别的权限
- 权限范围:特定表的操作权限
- columns_priv
- 存储内容:列级别的权限
- 权限范围:表中特定列的操作权限
- procs_priv
- 存储内容:存储过程和函数的权限
- 权限范围:存储过程和函数的执行、修改权限
注意:在 MySQL 中,一个用户是通过 User
+ Host
的组合唯一标识的。相同的用户名允许登录的来源不同的时,可以看做是不同的用户,可以分别授予不同的权限。例如:
SELECT User, Host FROM mysql.user;
+------------------+-----------+
| User | Host |
+------------------+-----------+
| root | localhost |
| alice | 192.168.% |
| alice | % |
+------------------+-----------+
# 这里 alice@192.168.% 和 alice@% 是两个不同的用户账户(即使用户名相同,但允许的登录来源不同)。
Bash2. 权限相关操作
2.1. 创建用户
create user '用户名'@'主机' identified by '密码';
# 示例:
create user 'alice'@'1.1.1.1' identified by '123';
create user 'alice'@'192.168.1.%' identified by '123';
create user 'alice'@'%' identified by '123';
Bash2.2. 删除用户
mysql> drop user 'alice'@'1.1.1.1';
Bash2.3. 授权
GRANT 命令基本语法:
GRANT 权限类型
ON 数据库对象
TO 用户
# 查看 GRANT 命令详细用法
mysql> help GRANT
Bash常用权限类型:
- 数据库操作权限
ALL PRIVILEGES
: 所有权限CREATE
: 创建数据库/表ALTER
: 修改表结构DROP
: 删除数据库/表SHOW VIEW
: 查看视图定义
- 数据操作权限
SELECT
: 查询数据INSERT
: 插入数据UPDATE
: 更新数据DELETE
: 删除数据EXECUTE
: 执行存储过程
- 管理权限
GRANT OPTION
: 允许用户授权他人PROXY
: 允许代理用户
示例:
全局权限:
# 授予用户 'admin'@'localhost' 对所有数据库和所有表的完全权限,并允许该用户将这些权限授予其他用户。
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost'
WITH GRANT OPTION;
# 授予用户 'alice'@'localhost' 对所有数据库和所有表的只读查询权限。
GRANT SELECT ON *.* TO 'alice'@'localhost';
Bash数据库级别权限:
# 授予用户 'user'@'%' 对数据库 mydb 中所有表的查询(SELECT)、插入(INSERT)和更新(UPDATE)权限
GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'user'@'%';
Bash表级别权限:
# 授予用户 'user'@'192.168.1.%' 对数据库 mydb 中表 mytable 的查询(SELECT)和插入(INSERT)权限
GRANT SELECT, INSERT ON mydb.mytable TO 'user'@'192.168.1.%';
Bash列级别权限:
# 授予用户 'user'@'localhost' 对 mydb.mytable 表的列级精细权限,col1 和 col2 两列有查询(SELECT)权限,col1 列有更新(UPDATE)权限。
GRANT SELECT (col1, col2), UPDATE (col1) ON mydb.mytable TO 'user'@'localhost';
Bash存储过程和函数权限:
# 授予用户 'user'@'localhost' 执行存储过程 mydb.myprocedure 的权限
GRANT EXECUTE ON PROCEDURE mydb.myprocedure TO 'user'@'localhost';
Bash2.4. 查看权限
# 查看当前用户(自己)权限:
mysql> show grants;
# 查看其他 MySQL 用户权限:
mysql> show grants for root@'%';
Bash2.5. 撤销权限
撤销权限命令 REVOKE 语法与 GRANT 相似,只需将关键字 TO 更换为 FROM。
grant all on *.* to dba@localhost;
revoke all on *.* from dba@localhost;
Bash2.6. 用户资源限制
max_queries_per_hour # 一个用户每小时可发出的查询数量
max_updates_per_hour # 一个用户每小时可发出的更新数量
max_connections_per_hour # 一个用户每小时可连接到服务器的次数
max_user_connections # 允许同时连接数量
# 示例:
# 创建用户时直接设置
CREATE USER 'user1'@'localhost'
IDENTIFIED BY 'password'
WITH
MAX_QUERIES_PER_HOUR 1000
MAX_UPDATES_PER_HOUR 200
MAX_CONNECTIONS_PER_HOUR 50
MAX_USER_CONNECTIONS 10;
# 修改已有用户的限制
ALTER USER 'user1'@'localhost'
WITH
MAX_QUERIES_PER_HOUR 500
MAX_USER_CONNECTIONS 5;
# 需结合 GRANT 语句精细权限控制
GRANT SELECT ON db1.* TO 'report_user'@'%'
WITH MAX_QUERIES_PER_HOUR 1000;
Bash2.7. 针对不同角色的权限分配
MySQL 的角色权限系统(MySQL 8.0+)提供了一种高效的方式来管理用户权限。
角色权限分配:
- 创建角色
CREATE ROLE 'role_name';
Bash- 授予角色权限
GRANT privilege_type ON database.object TO 'role_name';
Bash- 将角色分配给用户
GRANT 'role_name' TO 'user'@'host';
Bash- 激活角色
-- 激活并设置默认角色
SET DEFAULT ROLE 'role_name' TO 'user'@'host';
-- 或当前会话激活,每个新会话开始时需要重新激活(除非设置了默认角色)
SET ROLE 'role_name';
Bash常见角色权限方案:
- 数据库管理员 (DBA)
CREATE ROLE 'db_admin';
GRANT ALL PRIVILEGES ON *.* TO 'db_admin' WITH GRANT OPTION;
Bash- 应用开发者
CREATE ROLE 'app_developer';
GRANT CREATE, ALTER, DROP, INDEX, SELECT, INSERT, UPDATE, DELETE
ON app_db.* TO 'app_developer';
GRANT EXECUTE ON PROCEDURE app_db.* TO 'app_developer';
Bash- 数据分析师
CREATE ROLE 'data_analyst';
GRANT SELECT ON analytics.* TO 'data_analyst';
GRANT SHOW VIEW ON analytics.* TO 'data_analyst';
Bash- 只读用户
CREATE ROLE 'read_only';
GRANT SELECT ON *.* TO 'read_only';
REVOKE SELECT ON mysql.* FROM 'read_only'; -- 排除系统库
Bash- 备份管理员
CREATE ROLE 'backup_admin';
GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION CLIENT, PROCESS
ON *.* TO 'backup_admin';
Bash完整示例工作流示例:
-- 1. 创建角色
CREATE ROLE 'finance_ro', 'finance_rw', 'finance_admin';
-- 2. 分配权限
GRANT SELECT ON finance.* TO 'finance_ro';
GRANT SELECT, INSERT, UPDATE ON finance.* TO 'finance_rw';
GRANT ALL ON finance.* TO 'finance_admin' WITH GRANT OPTION;
-- 3. 创建用户并分配角色
CREATE USER 'john'@'%' IDENTIFIED BY 'secure_pass';
GRANT 'finance_ro' TO 'john'@'%';
CREATE USER 'jane'@'10.0.%' IDENTIFIED BY 'strong_pass';
GRANT 'finance_rw', 'finance_ro' TO 'jane'@'10.0.%';
-- 4. 设置默认角色
SET DEFAULT ROLE 'finance_rw' TO 'jane'@'10.0.%';
SET DEFAULT ROLE 'finance_ro' TO 'john'@'%';
-- 5. 验证权限
SHOW GRANTS FOR 'john'@'%' USING 'finance_ro';
Bash3. 破解密码
3.1. Linux 平台
方法一:启动时跳过授权表
# 修改配置文件
vim /etc/my.cnf
[mysqld]
skip-grant-table # 以跳过权限表方式启动
# 重启数据库
systemctl restart mysqld
# 连接到MySQL(无需密码)
mysql -u root
# 在MySQL中执行(5.7.6+版本)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
FLUSH PRIVILEGES;
# 或旧版本
UPDATE mysql.user SET authentication_string=PASSWORD('new_password') WHERE User='root';
FLUSH PRIVILEGES;
# 打开 /etc/my.cnf 去掉 skip-grant-table,然后重启
systemctl restart mysql
Bash方法二:使用 init 文件重置
# 停止MySQL服务
sudo systemctl stop mysqld
# 创建包含密码修改命令的文件
echo "ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';" > /root/reset.sql
# 配置MySQL在启动时执行脚本
sudo sed -i '/\[mysqld\]/a init-file=/root/reset.sql' /etc/my.cnf
# 启动MySQL服务
sudo systemctl start mysqld
# 确认服务运行后,立即清理
sudo rm -f /root/reset.sql
sudo sed -i '/init-file=\/root\/reset.sql/d' /etc/my.cnf
Bash3.2. Windows 平台
# 停止 MySQL 服务
# 创建包含密码重置命令的文本文件
# 使用 --init-file 参数启动 mysqld
Bash