Django通过Unix域套接字连接Redis时权限拒绝问题求助
看起来你遇到的是Unix域套接字的权限配置问题,别着急,咱们一步步排查解决:
1. 先确认Redis套接字的权限与所属组
首先运行这条命令查看套接字的权限详情:
ls -l /var/run/redis/redis-server.sock
正常情况下,这个套接字应该归redis用户和redis组所有,且组权限得包含读写权限(比如权限显示为srw-rw----)。如果组权限没有rw,哪怕你把myuser加到redis组里也没用。
如果权限不对,修改Redis配置文件(通常是/etc/redis/redis.conf),找到unixsocketperm配置项,把它改成770(保证组有读写权限),然后重启Redis服务:
sudo systemctl restart redis-server
2. 确认myuser的组权限已生效
运行这条命令检查myuser是否真的在redis组里:
groups myuser
如果输出里有redis,那接下来要注意:你添加用户到组后,当前运行的gunicorn进程并没有继承新的组权限(因为它是在你改组之前启动的)。所以必须重启gunicorn服务,让它以更新后的权限运行:
sudo systemctl restart gunicorn
(如果你的gunicorn不是用systemd管理的,就用对应的重启方式,比如重启supervisor进程之类的)
3. 检查Redis套接字所在目录的权限
有时候目录权限不够,哪怕套接字本身权限对,用户也访问不到。运行这条命令查看目录权限:
ls -ld /var/run/redis
这个目录需要给redis组至少读和执行权限(即权限里有g+rx)。如果权限不足,用这条命令修正:
sudo chmod g+rx /var/run/redis
4. 测试直接连接,快速定位问题
如果上面的步骤都试过还是不行,你可以直接用myuser身份测试Redis连接,排除Django代码的问题:
sudo -u myuser redis-cli -s /var/run/redis/redis-server.sock ping
如果返回PONG,那说明系统权限没问题,你得检查Django的CACHES配置里的套接字路径是不是写错了;如果还是提示权限拒绝,那就是系统权限还没配置到位,回头再检查前面的步骤。
备注:内容来源于stack exchange,提问作者Bobort

