Hi Redis gurus,
I'm sorry to be a bother, but the below behaviour has me stumped :/
Describe the bug
My goal; disable/deactivate the default user, in-order to limit users to ACL only.
Unfortunately it seems attempts to secure the default user affects the HELLO behaviour for the other ACL users on Redis.
Symptom discovered in v6.0.5, but also reproducible in v6.0.11 & v6.2.
To reproduce
Start Redis as outlined below; adding a password to the default user + defining a new ACL user:
root@ab948e714298:/data# redis-server --port 1236 "--user default on >somepw" "--user redisun on >redispw +@all" &
[2] 44
root@ab948e714298:/data# 44:C 25 Feb 2021 09:07:01.224 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
44:C 25 Feb 2021 09:07:01.224 # Redis version=6.2.0, bits=64, commit=00000000, modified=0, pid=44, just started
44:C 25 Feb 2021 09:07:01.224 # Configuration loaded
44:M 25 Feb 2021 09:07:01.225 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.2.0 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 1236
| `-._ `._ / _.-' | PID: 44
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
44:M 25 Feb 2021 09:07:01.226 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
44:M 25 Feb 2021 09:07:01.226 # Server initialized
44:M 25 Feb 2021 09:07:01.227 * Ready to accept connections
Connect via redis-cli
root@ab948e714298:/data# redis-cli -p 1236
Attempt to execute HELLO as the new user
127.0.0.1:1236> HELLO 2 AUTH redisun redispw
(error) NOPERM this user has no permissions to run the 'hello' command or its subcommand
Attempt to execute HELLO as the default user (mostly for completeness)
127.0.0.1:1236> HELLO 2 AUTH default somepw
(error) NOPERM this user has no permissions to run the 'hello' command or its subcommand
Attempt to execute HELLO as the default user by authorising explicitly first
127.0.0.1:1236> AUTH default somepw
OK
127.0.0.1:1236> HELLO 2
(error) NOPERM this user has no permissions to run the 'hello' command or its subcommand
Attempt to execute HELLO as the new user by authorising explicitly first
127.0.0.1:1236> AUTH redisun redispw
OK
127.0.0.1:1236> HELLO 2
1) "server"
2) "redis"
3) "version"
4) "6.2.0"
5) "proto"
6) (integer) 2
7) "id"
8) (integer) 3
9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)
In this case, 2 steps are required to get HELLO to work.
Expected behavior
HELLO 2 AUTH redisun redispw
Is expected to work, independently of the default user (or any other user) when redisun is defined in the ACL.
Additional information
Symptom is also present if the the default user is disabled ala --user default off
"Workaround"
When only defining a new ACL user, the HELLO behaviour matches expectations. Expect now anyone can now use the default user :/
Start Redis as outlined below, defining a new ACL user:
root@ab948e714298:/data# redis-server --port 1235 "--user redisun on >redispw +@all" &
Connect via redis-cli
root@ab948e714298:/data# redis-cli -p 1235
Attempt to execute HELLO as the new user
127.0.0.1:1235> HELLO 2 AUTH redisun redispw
1) "server"
2) "redis"
3) "version"
4) "6.2.0"
5) "proto"
6) (integer) 2
7) "id"
8) (integer) 4
9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)
Attempt to execute HELLO as the default user
127.0.0.1:1235> HELLO
1) "server"
2) "redis"
3) "version"
4) "6.2.0"
5) "proto"
6) (integer) 2
7) "id"
8) (integer) 4
9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)
127.0.0.1:1235>
Thanks in advance 🤓
Comment From: hpatro
I also believe this is an issue, HELLO should be treated similar to AUTH and shouldn't get restricted from getting executed.
https://github.com/redis/redis/blob/unstable/src/acl.c#L1185-L1186
As initially the client isn't authenticated in the above scenario, the user is set to default and doesn't have permission to the command it's failing.
@madolson I'm thinking we can handle this in two ways,
- Let the command execution if hello command has auth subcommand in it.
- The second approach which might be a breaking one is to let the
hellocommand irrespective ofauthin it.
Let me know what you think.
Comment From: madolson
Well this is some weird behavior.
@dlehammer Technically you can resolve your issue with:
redis-server --port 1236 "--user default off +@all" "--user redisun on >redispw +@all" &
This will prevent users from logging in as default and securing it, but will still let you use hello for auth.
@hpatro I would do #2. The HelloCommand already does special handling for authentication: https://github.com/redis/redis/blob/d828f90c26bf796cb54d6622389e5c14fcc9cbf0/src/networking.c#L2959. I would also use the "CMD_NO_AUTH" flag check instead of checking for the hello command, to allow module authentication to work.
Comment From: dlehammer
Thanks a bunch @madolson, the user default off +@all workaround is sufficient for now - and has been verified on Redis v6.0.5.
I think the key here is whether the HELLO request explicitly includes AUTH ~ as a user I would expect Redis to evaluate the explicit AUTH if present :)
Comment From: itamarhaber
Fixed via #8633 - closing.