Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > redis使用requirepass不生效

redis.conf中使用requirepass不生效的原因及解决方法

作者:小平杂记

本文主要介绍了如何启用requirepass,以及启用requirepass为什么不会生效,从代码层面分析了不生效的原因,以及解决方法,需要的朋友可以参考下

requirepass字段介绍

requirepass字段是redis.conf中的一个字段,可以看下redis.conf中的注释

# IMPORTANT NOTE: starting with Redis 6 "requirepass" is just a compatibility
# layer on top of the new ACL system. The option effect will be just setting
# the password for the default user. Clients will still authenticate using
# AUTH <password> as usually, or more explicitly with AUTH default <password>
# if they follow the new protocol: both will work.
#
# The requirepass is not compatable with aclfile option and the ACL LOAD
# command, these will cause requirepass to be ignored.
#
# requirepass foobared

即这个字段是用来设置默认用户default的密码的,用户可以通过auth 或者auth default 来认证,同时说明了不能跟aclfile兼容,如果启动acl,则该字段会被忽略,会使用acl文件中的default用户,如果没有配置default用户,则会新建一个nopass的default用户并使用,哈哈,这就是为什么redis.conf配置了requirepass而不生效的原因,提前说了。

如何启用requirepass

至于为什么启用aclfile时会不生效,请继续看

启用requirepass时requirepass不生效?

现象

requirepass是default用户的密码,配置密码后,aclfile也启用时,修改redis.conf配置后重启redis后,redis-cli -h localhost -p port 无需认证仍然可以访问,即没有生效

看下redis.conf中注释可以知道跟aclfile是不兼容的,启用aclfile时,会忽略requirepass

原因

redis.conf中同时启用requirepass和aclfile,redis在加载配置时,会读取aclfile,重新新建全局Users对象,调用ACLInitDefaultUser函数重新新建nopass的default用户,先前已加载的defaultUser对象(密码从requirepass来)不会被用到,即default用户是nopass的,但是如果acl文件中配置了default用户以及配置了密码,则还是需要认证的

sds ACLLoadFromFile(const char *filename) {
      ...
    /* The default user pointer is referenced in different places: instead
         * of replacing such occurrences it is much simpler to copy the new
         * default user configuration in the old one. */
        user *new_default = ACLGetUserByName("default",7);
        if (!new_default) {
            new_default = ACLCreateDefaultUser();  // nopass的default用户
        }
        ACLCopyUser(DefaultUser,new_default);
        ACLFreeUser(new_default);
        raxInsert(Users,(unsigned char*)"default",7,DefaultUser,NULL);
        raxRemove(old_users,(unsigned char*)"default",7,NULL);
        ACLFreeUsersSet(old_users);
        sdsfree(errors);
        return NULL;
       ...
}

解决方法

注意点:config set requirepass xxx会调用updateRequirePass函数,该函数会继续调用ACLUpdateDefaultUserPassword更新default用户的密码(nopass变为有密码状态),注意redis最新版本(7.0以上)只会在更新的内容发生变化时才会调用到updateRequirePass函数,如下面的sdsConfigSet函数,在内容有变化时才返回1

configSetCommand -> performInterfaceSet -> sdsConfigSet函数

performInterfaceSet会将sdsConfigSet函数返回值作为自己的返回值,

configSetCommand函数判断performInterfaceSet返回值,如果为1,则

会调用到updateRequirePass函数

总结

本文主要介绍了如何启用requirepass,以及启用requirepass为什么不会生效,从代码层面分析了不生效的原因,是因为同时启用了aclfile导致requirepass中的密码不会被用到,最后介绍了解决方法,建议使用上直接使用aclfile即可。

到此这篇关于redis.conf中使用requirepass不生效的原因及解决方法的文章就介绍到这了,更多相关redis.conf中使用requirepass不生效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文