Skip to content

Redis 安全

本文介绍如何配置Redis的访问密码,如何禁用危险命令,如何创建用户并配置权限,如何开启数据加密传输。

1. 配置访问密码

redis.conf文件中,可以配置访问Redis实例的密码:

txt
requirepass 123456

当配置了Redis的访问密码后,从节点访问主节点也需要提供密码,此时也可以配置如下:

txt
masterauth 123456

强烈建议将requirepassmasterauth配置成相同值,减少运维问题。

2. 禁用危险命令

redis.conf文件,提供了为命令重命名的功能,可以借此实现禁用危险命令。

什么是危险命令?会影响数据库性能或数据安全的命令,统称为危险命令,例如FLUSHDBFLUSHALLKEYS *

命令重命名语法如下:

txt
rename-command <command> <alias>
  • <command>:需要重命名的命令,例如FLUSHDB
  • <alias>:命令别名;

例如:

txt
rename-command flushdb myflushdb

image-20250613184839892

如果要禁用某个命令,可以将其别名置空,例如:

txt
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""

image-20250613185039477

但是,有时候为了管理需要,可以将某些命令取一个复杂的别名,仅供内部使用:

txt
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

最后,Redis已将命令重命名标记为【废弃】状态,请使用ACL。

3. ACL

ACL,全称Access Control Lists,即访问控制列表,其定义了一系列用户,以及这些用户所具有的操作权限。

即ACL(访问控制列表),可以更细粒度地控制用户对命令和 key 的访问权限。通过 ACL,可以创建不同的用户,并为他们分配特定的命令权限。

3.1 开启ACL

开启ACL有两种方式:

  • redis.conf中引入ACL文件,例如:

    txt
    aclfile /path/to/your/users.acl
  • 直接在redis.conf中定义用户并分配权限,例如:

    txt
    # admin用户,拥有所有权限
    user admin on >password +@all

注意,两种方式不兼容,即只能使用一种方式。推荐使用ACL文件方式,ACL文件中的内容就是定义用户并分配权限。

3.2 ACL规则

ACL语法如下:

txt
user <username> ... <acl rules> ...

即使用关键字user,其后跟一个或多个用户名,然后跟ACL规则。

具体的ACL规则如下:

  • on:启用用户;

  • off:停用用户;

  • +<command>:该用户具有执行命令command的权限,例如+CONFIG;如果该命令还有子命令,可以使用|进一步细分启用,例如+CONFIG|GET

  • -<command>:禁止该用户执行命令command,例如-CONFIG;如果该命令还有子命令,可以使用|进一步细分启用,例如-CONFIG|GET

  • +@<category>:允许该用户执行某组命令,例如+@string,表示允许用户执行有关String的命令,同理,如果要禁止用户执行某组命令,可以使用-@<category>。完整的命令分组参考:https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/#command-categories。

    如果要允许执行所有命令,可以使用+@all

    如果要禁用危险命令,Redis为我们定义了一个危险命令组,直接使用规则-@dangerous即可;

  • ~<pattern>:为用户指定他们可以访问的键 (key) 的模式,即限定了用户在使用任何需要指定键的命令(比如 GET keySET key valueHGETALL hash_key 等)时,能够操作的键的范围。

    例如,现在有一个名为 app_user 的应用用户,希望他:

    1. 能够执行 GETSETHGETALLHSET 命令。
    2. 只能操作以 user: 开头或以 product: 开头的键。

    可以配置如下:

    txt
    user app_user on +GET +SET +HGETALL +HSET ~user:* ~product:*

    有了这个配置:

    • app_user 可以执行 GET user:100
    • app_user 可以执行 SET product:sku:abc "value"
    • app_user 不能 执行 GET order:123,因为 order:123 不符合 ~user:*~product:* 模式;
    • app_user 不能 执行 FLUSHDB (除非用 +@all 且不禁用它),因为 FLUSHDB 命令本身就没有被授权;
  • ><password>:为用户指定密码,例如>123456

以上只是部分ACL规则,完整的ACL规则,请参考官方文档ACL

注意,ACL规则是从左到右应用的,也就是说写在后面的规则会覆盖前面的规则。

默认情况下,Redis提供名称为default的用户:

image-20250613192750287

并且,requirepass定义的就是default用户的密码。

3.3 ACL实践

定义一个app用户,该用户需要密码111111,并且不能执行危险操作,只能操作以user:开头的键:

txt
user app_user on >111111 +@all -@dangerous ~user:*

image-20250613193457657

然后我们使用redis-cli连接Redis服务器:

  • 使用--user <username>提供用户名;
  • 使用--pass <password>提供密码;

然后做些操作,可以发现配置生效:

image-20250613193901961

4. 数据传输加密

Redis默认情况下是明文传输数据,如果对数据安全有要求,Redis 6支持TLS配置。配置步骤如下【自签名证书,适用于测试、开发或内部环境】:

  1. 生成 CA 私钥和 CA 证书

    bash
    # 生成 CA 私钥
    openssl genrsa -out ca.key 2048
    
    # 生成 CA 证书 (作为根证书,用于签署其他证书)
    openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
    # Common Name (CN) 可以是 "My Root CA"
  2. 生成服务器私钥

    bash
    openssl genrsa -out server.key 2048
  3. 生成服务器CSR

    bash
    openssl req -new -key server.key -out server.csr
    # Common Name (CN) 必须是你的 Redis 服务器的域名或 IP 地址,否则客户端验证会失败 -- 好像不用
  4. 使用 CA 证书和私钥签署服务器 CSR,生成服务器证书

    bash
    openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256
  5. 经过上面的步骤后,我们有以下文件:

    image-20250613202809833

    只需要三个文件:server.keyserver.crtca.crt

  6. 将这三个文件放在redis.confdir 配置的路径下;

  7. 修改redis.conf文件:

    txt
    port 0
    tls-port 6379
    
    tls-cert-file server.crt
    tls-key-file server.key
    tls-ca-cert-file ca.crt
    tls-auth-clients no
  8. 重新启动Redis服务器;

  9. 以如下命令启动redis-cli:

    txt
    redis-cli -a 123456 --tls  --cacert /projects/docker/redis6379/data/ca.crt

    注意要加参数--tls

  10. 完成TLS配置,在Navicat中也可以验证:

    image-20250613203139302

参考资料

[1] ACL:https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/

[2] TLS:https://redis.io/docs/latest/operate/oss_and_stack/management/security/encryption/