Web安全
基础漏洞
01前端基础【HTML】
02前端基础【CSS】
03后端基础【PHP速通】
04后端基础【PHP面向对象】
05MySQL基础操作
06前后端联动【代码练习】
07SQL注入【1】
07SQL 注入【2】
08SQL注入 Labs
08SQL注入速查表
09XSS
09跨站脚本攻击【XSS】
09XSS Labs
10跨站请求伪造【CSRF】
11服务器端请求伪造【SSRF】
12XML 外部实体注入【XXE】
13代码执行漏洞
14命令执行漏洞
15文件包含漏洞
16文件上传漏洞
17反序列化漏洞
18业务逻辑漏洞
19未授权访问漏洞集合
20跨源资源共享【CORS】
21SSTI模板注入
22并发漏洞
23点击劫持【Clickjacking 】
24请求走私
25路径遍历
26访问控制
27身份验证漏洞
28WebSocket
29Web缓存中毒
30HTTP 主机头攻击
31信息泄露漏洞
32原型污染
33NoSQL注入
API 安全
01web应用程序
02HTTP协议
03API概述
04分类类型
05交换格式
06身份验证
07常见API漏洞
08crAPI靶场
09JWT
10OAuth 2.0身份验证
11GraphQL【1】
11GraphQL【2】
12DVGA靶场
13服务器端参数污染
14API文档
15API Labs
16OAuth Labs
17GraphQL API Labs
18JWT Labs
小程序
小程序抓包
数据库
MySQL
Oracle
MongoDB
Redis
PostgreSQL
SQL server
中间件
Nginx
Apache HTTP Server
IIS
Tomcat
框架
ThinkPHP
Spring
Spring Boot
Django
访问控制
-
+
首页
Redis
 ## 概述 Redis(Remote Dictionary Server,远程字典服务)是一款**基于内存的开源键值对(Key-Value)数据库**,由意大利开发者 Salvatore Sanfilippo 于 2009 年发布。它不仅支持简单的键值存储,还提供了丰富的数据结构(如字符串、哈希、列表、集合等),兼具高性能、持久化、高可用等特性,广泛用于缓存、会话存储、消息队列、实时排行榜等场景。 官网地址:https://redis.io/ 默认端口为6379。 备用端口(集群 / 哨兵): - 哨兵默认端口:26379 - 集群节点间通信端口:16379(主端口 + 10000) 默认用户名与密码: - Redis 6.0 及以上版本默认有一个**空用户名**("")和**空密码**(无密码),生产环境需立即设置密码(通过 CONFIG SET requirepass "your_password" 临时设置,或修改配置文件永久生效)。 - Redis 5.x 及以下版本默认无用户名,仅空密码 ## 特性 Redis 的优势源于其独特的设计,核心特性如下: | 特性 | 说明 | | ------------------ | ------------------------------------------------------------ | | **基于内存存储** | 数据优先存于内存,读写速度极快(单机 QPS 可达 10 万 +),远超磁盘数据库。 | | **多数据结构支持** | 不仅支持 String(字符串),还支持 Hash(哈希)、List(列表)、Set(集合)、Sorted Set(有序集合)等,满足复杂业务场景。 | | **持久化机制** | 支持 RDB(快照)和 AOF(日志)两种持久化方式,避免内存数据丢失。 | | **高可用架构** | 提供主从复制、哨兵(Sentinel)、Redis Cluster(集群),保障服务稳定性和扩展性。 | | **原子操作** | 所有命令均为原子操作,支持批量命令(如 MSET)和事务(MULTI/EXEC),避免并发问题。 | | **过期策略** | 支持为键设置过期时间(如 EXPIRE),过期后自动删除,适合缓存场景。 | | **发布 / 订阅** | 支持消息队列模式(PUBLISH/SUBSCRIBE),实现跨客户端通信。 | | **分布式锁** | 基于 SET key value NX EX 命令可实现分布式锁,解决分布式系统并发问题。 | ## 默认数据库 Redis 的 “数据库” 并非关系型数据库的 “库”,而是**内存中的命名空间**(隔离不同键集合),无独立存储文件。 默认配置: - Redis 默认创建 **16 个数据库**,编号为 0~15(由配置文件 redis.conf 中的 databases 16 控制,可修改数量)。 - 启动后默认使用 **0 号数据库**,无需显式 “创建” 数据库,切换到未使用的编号即可直接使用。 核心命令: | 命令 | 语法格式 | 功能说明 | 示例 | | -------------- | ------------------- | ------------------------------------------------------------ | -------------------------------- | | 切换数据库 | SELECT [数据库编号] | 切换到指定编号的数据库(编号需 ≤ databases-1) | SELECT 1 → 切换到 1 号数据库 | | 查看当前库键数 | DBSIZE | 返回当前数据库中键的总数 | DBSIZE → 输出 5(表示有 5 个键) | | 清空当前库 | FLUSHDB | 删除当前数据库中所有键(谨慎使用!) | FLUSHDB → 成功返回 OK | | 清空所有库 | FLUSHALL | 删除所有 16 个数据库的所有键(高危!) | FLUSHALL → 成功返回 OK | | 查看数据库信息 | INFO [section] | 查看 Redis 状态(如内存、键数量),section 可选(如 INFO keyspace 查看所有库键数) | INFO keyspace → 输出各库键数信息 | ## 核心操作 Redis 的操作围绕 “键(Key)” 展开,不同数据结构的 “增删改查” 语法不同。以下分**通用键操作**和**主流数据结构**: **1. 通用键操作(适用于所有数据结构)** 无论值的类型是 String 还是 Hash,键的基础操作语法一致。 | 操作类型 | 命令 | 语法格式 | 功能说明 | 示例 | | ------------ | ------ | -------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | 新增 / 修改 | SET | SET key value [EX seconds] [PX ms] [NX / XX] | 设置键值(覆盖已有键),可选过期时间(EX = 秒,PX = 毫秒)、条件(NX = 键不存在才设,XX = 键存在才设) | SET username alice EX 3600 → 设 username=alice,1 小时后过期; SET lock 1 NX EX 10 → 分布式锁(不存在才设,10 秒过期) | | 批量新增 | MSET | MSET key1 value1 key2 value2 ... | 批量设置多个键值 | MSET age 25 email alice@xxx.com | | 查询值 | GET | GET key | 获取指定键的值(仅适用于 String 类型,其他类型需用对应命令) | GET username → 输出 "alice" | | 批量查询 | MGET | MGET key1 key2 ... | 批量获取多个键的值 | MGET username age → 输出 ["alice", "25"] | | 判断键存在 | EXISTS | EXISTS key1 [key2 ...] | 判断键是否存在,返回存在的键数量 | EXISTS username age → 输出 2(两个键都存在) | | 设置过期时间 | EXPIRE | EXPIRE key seconds | 为键设置过期时间(秒),过期后自动删除 | EXPIRE username 1800 → 设 username 30 分钟后过期 | | 查看剩余时间 | TTL | TTL key | 查看键的剩余过期时间(-1 = 永久,-2 = 已过期) | TTL username → 输出 1780(剩余 1780 秒) | | 删除键 | DEL | DEL key1 [key2 ...] | 永久删除一个或多个键,返回删除的键数量 | DEL username age → 输出 2(删除 2 个键) | | 异步删除大键 | UNLINK | UNLINK key1 [key2 ...] | 异步删除键(避免大键删除阻塞主线程) | UNLINK big_hash → 适合删除百万级字段的 Hash | | 查看键类型 | TYPE | TYPE key | 返回键值的数据结构类型(string/hash/list 等) | TYPE user:1 → 输出 hash | | 模糊查询键 | KEYS | KEYS pattern | 模糊匹配键(*= 任意字符,?= 单个字符),**大数据量慎用(阻塞线程)** | KEYS user:* → 匹配所有以 user: 开头的键 | | 迭代查询键 | SCAN | SCAN cursor [MATCH pattern] [COUNT count] | 迭代查询键(非阻塞),cursor 初始为 0,返回下一轮游标 | SCAN 0 MATCH user:* COUNT 10 → 迭代匹配 10 个 user:* 键 | **2. 主流数据结构操作** Redis 支持 8 种数据结构,以下讲解最常用的 5 种核心操作。 **String(字符串)**:String 是 Redis 最基础的类型,值可以是文本(如 alice)、数字(如 25)或二进制数据(如图片),最大容量 512MB。 **场景**:存储用户昵称、计数器、验证码等。 | 操作类型 | 命令 | 语法格式 | 示例 | | ------------ | ------ | ---------------- | ------------------------------------------------------ | | 新增 / 修改 | SET | 同通用键操作 | SET user:1:name "Alice" | | 查询 | GET | 同通用键操作 | GET user:1:name → "Alice" | | 自增(数字) | INCR | INCR key | SET view_count 100 → INCR view_count → 输出 101 | | 自减(数字) | DECR | DECR key | DECR view_count → 输出 100 | | 追加内容 | APPEND | APPEND key value | APPEND user:1:name " Smith" → GET 结果为 "Alice Smith" | **Hash(哈希)**:Hash 是 “键值对的集合”(类似 JSON 对象),适合存储结构化数据(如用户信息),可单独操作某个字段,无需修改整个值。 **场景**:存储用户详情(姓名、年龄、邮箱)、商品信息等。 | 操作类型 | 命令 | 语法格式 | 示例 | | ------------ | ------- | --------------------------------------------- | ----------------------------------------------------- | | 新增字段 | HSET | HSET hash_key field value [field2 value2 ...] | HSET user:1 name "Alice" age 25 email "alice@xxx.com" | | 查询单个字段 | HGET | HGET hash_key field | HGET user:1 age → "25" | | 查询所有字段 | HGETALL | HGETALL hash_key | HGETALL user:1 → 输出所有字段和值 | | 批量查询字段 | HMGET | HMGET hash_key field1 field2 | HMGET user:1 name email → 输出指定字段 | | 删除字段 | HDEL | HDEL hash_key field1 [field2] | HDEL user:1 email → 删除 email 字段 | | 查看字段数 | HLEN | HLEN hash_key | HLEN user:1 → 输出 2(剩余 name/age) | **List(列表):**List 是有序的字符串列表(基于双向链表实现),支持从两端插入 / 删除元素,可模拟 “栈”“队列” 或 “消息队列”。 **场景**:消息队列、最新评论列表、排行榜(按时间排序)。 | 操作类型 | 命令 | 语法格式 | 示例 | | -------------- | ------ | ------------------------------ | ------------------------------------------------------------ | | 左插入(头部) | LPUSH | LPUSH list_key value1 [value2] | LPUSH msg_queue "msg1" "msg2" → 列表为 ["msg2", "msg1"] | | 右插入(尾部) | RPUSH | RPUSH list_key value1 [value2] | RPUSH msg_queue "msg3" → 列表为 ["msg2", "msg1", "msg3"] | | 查看列表 | LRANGE | LRANGE list_key start end | LRANGE msg_queue 0 -1 → 查看所有元素(0= 第一个,-1= 最后一个) | | 左删除(头部) | LPOP | LPOP list_key | LPOP msg_queue → 删除并返回 "msg2" | | 右删除(尾部) | RPOP | RPOP list_key | RPOP msg_queue → 删除并返回 "msg3" | | 查看长度 | LLEN | LLEN list_key | LLEN msg_queue → 输出 1(剩余 "msg1") | Set(集合):Set 是无序的字符串集合,元素唯一(自动去重),支持交集、并集、差集等数学操作。 **场景**:用户标签(去重)、共同关注、好友推荐。 | 操作类型 | 命令 | 语法格式 | 示例 | | ------------ | --------- | ---------------------------- | ------------------------------------------------------------ | | 新增元素 | SADD | SADD set_key value1 [value2] | SADD user:1:tags "redis" "database" "cache" | | 查看所有元素 | SMEMBERS | SMEMBERS set_key | SMEMBERS user:1:tags → 输出所有标签(无序) | | 判断元素存在 | SISMEMBER | SISMEMBER set_key value | SISMEMBER user:1:tags "redis" → 输出 1(存在) | | 删除元素 | SREM | SREM set_key value1 [value2] | SREM user:1:tags "cache" → 删除标签 | | 求交集 | SINTER | SINTER set1 set2 | SADD user:2:tags "redis" "java" → SINTER user:1:tags user:2:tags → 输出 ["redis"] | | 查看元素数 | SCARD | SCARD set_key | SCARD user:1:tags → 输出 2(剩余 redis/database) | **Sorted Set(有序集合)**:Sorted Set(ZSet)是**有序的集合**,每个元素关联一个 “分数(score)”,按分数从小到大排序,元素唯一(分数可重复)。 **场景**:实时排行榜(如游戏积分、销量排名)、带权重的消息队列。 | 操作类型 | 命令 | 语法格式 | 示例 | | -------------------- | --------- | ------------------------------------------- | ------------------------------------------------------------ | | 新增元素 | ZADD | ZADD zset_key score1 value1 [score2 value2] | ZADD rank 100 "Alice" 90 "Bob" 95 "Charlie" | | 查看排序(升序) | ZRANGE | ZRANGE zset_key start end [WITHSCORES] | ZRANGE rank 0 -1 WITHSCORES → 按分数升序输出(带分数) | | 查看排序(降序) | ZREVRANGE | ZREVRANGE zset_key start end [WITHSCORES] | ZREVRANGE rank 0 -1 WITHSCORES → 按分数降序输出(Alice 第一) | | 增加分数 | ZINCRBY | ZINCRBY zset_key increment value | ZINCRBY rank 5 "Bob" → Bob 分数变为 95 | | 删除元素 | ZREM | ZREM zset_key value1 [value2] | ZREM rank "Charlie" → 删除 Charlie | | 查看元素排名(升序) | ZRANK | ZRANK zset_key value | ZRANK rank "Bob" → 输出 1(Bob 排第 2,从 0 开始) | ## 安装并启动Redis 使用docker拉去最新的redis镜像: ```bash docker pull redis:latest ``` ```bash C:\Users\root>docker pull redis:latest latest: Pulling from library/redis d107e437f729: Pull complete a3f725691cac: Pull complete bd022da7d981: Pull complete 349073970fc7: Pull complete cf596724f63e: Pull complete 4f4fb700ef54: Pull complete d7e6e9e45ecf: Pull complete Digest: sha256:acb90ced0bd769b7c04cb4c32c4494ba7b3e0ee068bdbfff0eeb0d31c2a21078 Status: Downloaded newer image for redis:latest docker.io/library/redis:latest C:\Users\root>docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis latest f1285ef3611d 3 weeks ago 137MB C:\Users\root> ``` 启动容器: ```bash docker run -d # -d:后台运行容器 --name redis-container # --name:指定容器名称 -p 16379:6379 #- p 16379:6379:将宿主机 16379 端口映射到容器内 6379 端口(Redis 默认端口) redis:latest #本地的容器名称 ``` ```bash C:\Users\root>docker run -d --name redis-container -p 16379:6379 redis:latest 8427829b6c6d1463a7dd64a620fdc5ac20936d65ccac059b0fe210f41d6594ae C:\Users\root>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8427829b6c6d redis:latest "docker-entrypoint.s…" 3 seconds ago Up 3 seconds 0.0.0.0:16379->6379/tcp, [::]:16379->6379/tcp redis-container ``` **方式一**:使用【Navicat】外部数据库连接工具进行连接(官网免费版下载地址:https://www.navicat.com.cn/download/navicat-premium-lite)。  **方式二**:容器内使用redis-cli。 ```bash # 进入容器并启动 redis-cli,同时输入密码 docker exec -it redis-container redis-cli -a 123456 ``` ```bash C:\Users\root>docker exec -it 8427829b6c6d redis-cli 127.0.0.1:6379> ``` ## 核心操作示例 **通用键操作** ```sql # 1. 设置键值(String 类型) 127.0.0.1:6379> SET username "alice" OK # 2. 获取键值 127.0.0.1:6379> GET username "alice" # 3. 判断键是否存在,1 表示存在,0 表示不存在 127.0.0.1:6379> EXISTS username (integer) 1 # 4. 设置键过期时间(30 秒后自动删除) 127.0.0.1:6379> EXPIRE username 30 (integer) 1 # 5. 查看剩余过期时间(-1=永久,-2=已过期) 127.0.0.1:6379> TTL username (integer) 26 127.0.0.1:6379> TTL username (integer) 18 # 6. 批量设置键值 127.0.0.1:6379> MSET age 25 email "alice@example.com" OK # 7. 批量获取键值 127.0.0.1:6379> MGET username age email 1) (nil) 2) "25" 3) "alice@example.com" # 8. 删除键(支持批量删除) 127.0.0.1:6379> DEL email (integer) 1 127.0.0.1:6379> TTL username (integer) -2 127.0.0.1:6379> ``` **Hash操作** ```sql # 1. 设置哈希字段(用户 ID 为 1 的信息) 127.0.0.1:6379> HSET user:1 name "bob" age 30 city "beijing" (integer) 3 # 成功设置 3 个字段 # 2. 获取单个字段值 127.0.0.1:6379> HGET user:1 age "30" # 3. 获取所有字段和值 127.0.0.1:6379> HGETALL user:1 1) "name" 2) "bob" 3) "age" 4) "30" 5) "city" 6) "beijing" # 4. 删除哈希中的字段 127.0.0.1:6379> HDEL user:1 city (integer) 1 # 删除 1 个字段 # 5. 查看哈希字段数量 127.0.0.1:6379> HLEN user:1 (integer) 2 # 剩余 2 个字段(name、age) 127.0.0.1:6379> ``` **List(列表)操作** ```sql # 1. 从左侧插入元素(头部) 127.0.0.1:6379> LPUSH msg_queue "msg1" "msg2" (integer) 2 # 2. 从右侧插入元素(尾部) 127.0.0.1:6379> RPUSH msg_queue "msg3" (integer) 3 # 列表长度为 3 # 3. 查看列表所有元素(0 表示第一个,-1 表示最后一个) 127.0.0.1:6379> LRANGE msg_queue 0 -1 1) "msg2" 2) "msg1" 3) "msg3" # 4. 从左侧删除并返回元素(头部) 127.0.0.1:6379> LPOP msg_queue "msg2" # 5. 从右侧删除并返回元素(尾部) 127.0.0.1:6379> RPOP msg_queue "msg3" # 6. 查看列表长度 127.0.0.1:6379> LLEN msg_queue (integer) 1 127.0.0.1:6379> ``` **Set(集合)操作** ```sql # 1. 向集合添加元素(自动去重) 127.0.0.1:6379> SADD tags "redis" "database" "cache" "redis" (integer) 3 # 2. 查看集合所有元素(无序) 127.0.0.1:6379> SMEMBERS tags 1) "redis" 2) "database" 3) "cache" # 3. 判断元素是否在集合中 127.0.0.1:6379> SISMEMBER tags "redis" (integer) 1 # 4. 删除集合中的元素 127.0.0.1:6379> SREM tags "cache" (integer) 1 # 5. 计算两个集合的交集(示例:用户 1 和用户 2 的共同标签) 127.0.0.1:6379> SADD user:1:tags "redis" "java" (integer) 2 127.0.0.1:6379> SADD user:2:tags "redis" "python" (integer) 2 # 交集结果 127.0.0.1:6379> SINTER user:1:tags user:2:tags 1) "redis" 127.0.0.1:6379> ``` **Sorted Set(有序集合)操作** ```sql # 1. 向有序集合添加元素(元素 + 分数,按分数排序) 127.0.0.1:6379> ZADD rank 100 "alice" 90 "bob" 95 "charlie" (integer) 3 # 2. 按分数升序查看元素(带分数) 127.0.0.1:6379> ZRANGE rank 0 -1 WITHSCORES 1) "bob" 2) "90" 3) "charlie" 4) "95" 5) "alice" 6) "100" # 3. 按分数降序查看元素(带分数,适合排行榜) 127.0.0.1:6379> ZREVRANGE rank 0 -1 WITHSCORES 1) "alice" 2) "100" 3) "charlie" 4) "95" 5) "bob" 6) "90" # 4. 增加元素的分数(如游戏加分) 127.0.0.1:6379> ZINCRBY rank 5 "bob" # 给 bob 加 5 分 "95" # 5. 查看元素的排名(降序,第 1 名为 0) 127.0.0.1:6379> ZREVRANK rank "alice" (integer) 0 127.0.0.1:6379> ``` ## 用户与权限的核心概念 Redis 作为高性能的键值对数据库,其权限管理机制随着版本演进不断完善。 早期版本(≤5.x)仅支持简单的密码认证,而 **Redis 6.0 及以上版本引入了 ACL(Access Control List,访问控制列表)**,实现了多用户、细粒度权限控制(如命令级、键空间级权限),满足企业级安全需求。 版本差异: - **Redis 5.x 及以下**:无 “用户” 概念,仅支持全局密码认证(通过 requirepass 配置),所有客户端共享同一密码和全部权限,安全性较低。 - **Redis 6.0 及以上**:引入 ACL,支持多用户管理,可针对不同用户配置独立密码、命令权限、键空间权限,实现精细化控制。 **用户(User)**:Redis 中的身份标识,包含用户名、密码、权限规则、启用状态等属性(如 admin、app_read)。 **默认用户(default)**:Redis 启动时自动创建的用户,默认无密码、拥有全部权限(allkeys +@all),需手动修改以保障安全。 **ACL 规则**:定义用户可执行的命令、可操作的键空间,格式包括: - **命令权限**:+command(允许)、-command(禁止)、+@category(允许某类命令,如 +@string 允许所有字符串命令)。 - **键空间权限**:~pattern(允许操作匹配 pattern 的键,如 ~user:* 允许操作 user:1、user:2 等键)。 - **特殊权限**:on/off(启用 / 禁用用户)、nopass(无需密码登录)、reset(重置用户权限)等。 ## 启用ACL Redis 6.0+ 默认启用 ACL,无需额外配置,但需通过配置文件或命令管理用户。 配置文件(redis.conf): ```bash # 启用 ACL(6.0+ 默认启用,无需修改) aclfile /etc/redis/acl.conf # ACL 规则持久化文件(默认自动生成) # 旧版本密码认证(与 ACL 兼容,建议仅用于过渡) # requirepass old_password ``` 修改配置后重启 Redis 服务: ```bash # Linux 重启 sudo systemctl restart redis-server # 验证版本(确认 6.0+) redis-server --version # 输出 Redis server v=6.2.6 ... ``` ## 用户管理 Redis 通过 ACL SETUSER 命令创建 / 修改用户,ACL DELUSER 删除用户,所有操作需在客户端(如 redis-cli)执行。 **创建/修改用户** ```bash ACL SETUSER 用户名 [属性1] [属性2] ... ``` 常用属性: | 属性格式 | 作用说明 | | ---------- | ------------------------------------------------------------ | | on/off | 启用 / 禁用用户(默认 on) | | >password | 设置密码(> 表示明文密码,Redis 会自动哈希存储;# 可直接指定哈希值) | | nopass | 无需密码即可登录(谨慎使用) | | +command | 允许执行指定命令(如 +get 允许 GET 命令) | | -command | 禁止执行指定命令(如 -del 禁止 DEL 命令) | | +@category | 允许执行某类命令(如 +@string 允许所有字符串命令,+@all 允许所有命令) | | -@category | 禁止执行某类命令(如 -@keyspace 禁止键空间管理命令) | | ~pattern | 允许操作匹配 pattern 的键(如 ~user:* 允许操作 user:1、user:2) | | reset | 重置用户权限(清除所有已配置的规则) | ```bash # 示例1:创建管理员用户(允许所有命令和键,需密码) ACL SETUSER admin on >Admin@123456 +@all ~* # 说明: # on:启用用户 # >Admin@123456:密码为 Admin@123456 # +@all:允许所有命令 # ~*:允许操作所有键 # 示例2:创建只读用户(仅允许查询命令,操作 user:* 键) ACL SETUSER app_read on >Read@123 +@read ~user:* # 说明: # +@read:允许所有只读命令(如 GET、MGET、EXISTS 等) # ~user:*:仅允许操作以 user: 为前缀的键 # 示例3:创建字符串操作用户(仅允许字符串命令,禁止删除) ACL SETUSER string_user on >String@123 +@string -del ~* # 说明: # +@string:允许所有字符串命令(如 SET、GET、INCR 等) # -del:禁止 DEL 命令(即使属于 @string 类别也会被禁止) # 示例4:修改默认用户(default)- 关键! # 默认用户默认无密码且有全部权限,必须修改 ACL SETUSER default on >Default@67890 -@all +ping # 仅允许 PING 命令 ``` **删除用户** ```bash # 语法:ACL DELUSER 用户名 ACL DELUSER app_read # 删除 app_read 用户 ``` **查看用户信息** ```bash # 1. 查看所有用户(简略信息) ACL LIST # 2. 查看指定用户的详细权限(如 admin) ACL GETUSER admin # 3. 查看默认用户 ACL GETUSER default ``` ```bash ACL GETUSER admin 1) "flags" 2) 1) "on" 3) "passwords" 4) 1) "sha256$..." # 密码哈希值 5) "commands" 6) "+@all" # 允许所有命令 7) "keys" 8) 1) "*" # 允许所有键 ``` ## 权限 Redis 权限通过 “命令权限” 和 “键空间权限” 组合实现细粒度控制,需理解规则的优先级和组合方式。 **命令权限** 命令按功能分为多个类别(可通过 ACL CAT 查看所有类别): ```bash ACL CAT # 列出所有命令类别:string, list, set, hash, admin, read, write... ACL CAT string # 查看 string 类别包含的命令:set, get, incr, decr... ``` 权限优先级 - 具体命令规则(+command/-command)优先于类别规则(+@category/-@category)。 例如:+@string -set 表示允许所有字符串命令,但禁止 SET 命令。 - 禁止规则(-)优先于允许规则(+)。 例如:+@all -del 表示允许所有命令,但禁止 DEL 命令。 **键空间权限** 通过 ~pattern 限制用户可操作的键,支持通配符: - ~*:允许所有键(默认)。 - ~user:*:允许 user:1、user:2 等键。 - ~order:* ~cart:*:允许 order:xxx 和 cart:xxx 两类键。 注意:键空间权限仅限制 “显式指定键” 的命令(如 GET key),对不指定键的命令(如 KEYS *、FLUSHDB)无效,需通过命令权限控制。 **特殊权限** admin:允许执行 ACL 管理命令(如 ACL SETUSER、ACL DELUSER)。 noscript:禁止执行 Lua 脚本(EVAL、EVALSHA),防止脚本绕过权限。 pubsub:允许发布 / 订阅命令(PUBLISH、SUBSCRIBE) ## 客户端登录 客户端需通过 AUTH 命令认证,Redis 6.0+ 支持指定用户名 **基本认证** ```bash # 语法:AUTH 用户名 密码 redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379> AUTH admin Admin@123456 # 认证 admin 用户 OK # 认证成功 127.0.0.1:6379> GET user:1 # 执行允许的命令 "Alice" ``` **连接时认证** ```bash redis-cli -h 127.0.0.1 -p 6379 -u redis://admin:Admin@123456@127.0.0.1:6379 ``` **旧版本兼容(仅密码认证)** 若用户设置了密码且兼容旧版本,可省略用户名(默认使用 default 用户): ```bash redis-cli 127.0.0.1:6379> AUTH Default@67890 # 等价于 AUTH default Default@67890 OK ``` ## 权限查询与审计 Redis 提供了一系列 ACL 命令用于查询用户、权限规则、命令类别等信息,帮助管理员掌握当前权限配置状态。 **查询所有用户权限** ACL LIST 命令以紧凑格式展示所有用户的权限规则,适合快速概览系统中所有用户的配置。 ```bash # 查看所有用户权限 127.0.0.1:6379> ACL LIST 1) "user default on #8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 >Default@67890 ~* +ping" 2) "user admin on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 -flushdb -flushall -shutdown +@all ~*" 3) "user app_read on #5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 ~user:* +@read" ``` 输出格式为: ```txt user 用户名 [状态] [密码哈希] [权限规则] ``` - on/off:用户是否启用; - #哈希值:密码的 SHA-256 哈希(> 开头表示明文设置,存储时自动转为哈希); - ~pattern:键空间权限; - +/-命令 或 +/-@类别:命令权限。 **查看指定用户的详细权限** ACL GETUSER 用户名 该命令返回指定用户的详细权限配置,包括状态、密码、命令权限、键空间权限等,适合深入分析单个用户的权限。 ```bash # 查看 app_read 用户的详细权限 127.0.0.1:6379> ACL GETUSER app_read 1) "flags" 2) 1) "on" # 用户启用 3) "passwords" 4) 1) "sha256$5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8" # 密码哈希 5) "commands" 6) "+@read" # 允许所有只读命令 7) "keys" 8) 1) "user:*" # 仅允许操作 user:* 键 9) "channels" 10) 1) "*" # 发布订阅通道权限(默认允许所有) ``` 关键字段说明: - flags:用户状态(on/off、nopass 等); - passwords:密码哈希列表(支持多密码,Redis 6.2+ 新增); - commands:命令权限规则(+@read 表示允许只读命令类别); - keys:键空间权限规则(user:* 表示允许操作匹配的键)。 **查看命令类别与包含的命令** Redis 将命令按功能分为多个类别(如 string、list、read、admin 等),ACL CAT 命令可查询类别列表及类别包含的命令,帮助理解权限规则中的 +@category 含义。 ```bash # 1. 查看所有命令类别 127.0.0.1:6379> ACL CAT 1) "keyspace" 2) "read" 3) "write" 4) "set" 5) "sortedset" ...(省略其他类别) # 2. 查看 "read" 类别包含的命令(只读命令) 127.0.0.1:6379> ACL CAT read 1) "get" 2) "mget" 3) "exists" 4) "keys" 5) "type" ...(包含所有查询类命令) # 3. 查看 "admin" 类别包含的命令(管理员命令) 127.0.0.1:6379> ACL CAT admin 1) "acl" 2) "bgrewriteaof" 3) "bgsave" 4) "config" ...(包含所有系统管理命令) ``` **检查用户是否有权执行指定命令** - ACL WHOAMI:查看当前登录用户的用户名,确认当前会话的身份; - 直接执行命令:通过执行目标命令,观察是否返回 NOPERM(无权限)判断权限是否生效。 ```bash # 1. 查看当前用户 127.0.0.1:6379> ACL WHOAMI "app_read" # 当前登录用户为 app_read # 2. 测试允许的命令(GET user:1) 127.0.0.1:6379> GET user:1 "Alice" # 有权限,执行成功 # 3. 测试禁止的命令(SET user:1 "Bob") 127.0.0.1:6379> SET user:1 "Bob" (error) NOPERM this user has no permissions to run the 'set' command or its subcommand # 无权限,执行失败 ``` **启动日志** Redis 日志可记录连接、认证、权限相关事件,需在配置文件(redis.conf)中开启并指定日志路径。 ```bash # 修改 redis.conf logfile "/var/log/redis/redis-server.log" # 日志文件路径 loglevel notice # 日志级别(notice 或 warning,记录关键事件) sudo systemctl restart redis-server #重启生效 ``` **统计信息查询** INFO 命令提供 Redis 运行的统计信息,其中与权限和连接相关的指标可用于审计: ```bash 127.0.0.1:6379> INFO stats # Stats total_connections_received:120 # 总连接数 rejected_connections:5 # 被拒绝的连接数(如认证失败、最大连接数限制) total_commands_processed:500 # 总命令执行数 total_denied_commands:10 # 被拒绝的命令数(权限不足) ``` - rejected_connections:若数值突增,可能存在暴力破解或异常访问; - total_denied_commands:若数值非零,说明存在用户尝试执行无权限的命令,需检查权限配置或是否有恶意操作
毛林
2025年9月12日 20:58
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码