feat(redis): add support for `username` on AUTH command
Fixes https://emqx.atlassian.net/browse/EMQX-9911
This commit is contained in:
parent
fc3720627b
commit
2c458b62f5
|
@ -4,12 +4,11 @@ services:
|
||||||
redis_server:
|
redis_server:
|
||||||
container_name: redis
|
container_name: redis
|
||||||
image: redis:${REDIS_TAG}
|
image: redis:${REDIS_TAG}
|
||||||
|
volumes:
|
||||||
|
- ./redis/single-tcp:/usr/local/etc/redis/
|
||||||
ports:
|
ports:
|
||||||
- "6379:6379"
|
- "6379:6379"
|
||||||
command:
|
command: redis-server /usr/local/etc/redis/redis.conf
|
||||||
- redis-server
|
|
||||||
- "--bind 0.0.0.0 ::"
|
|
||||||
- --requirepass public
|
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- emqx_bridge
|
- emqx_bridge
|
||||||
|
|
|
@ -8,18 +8,10 @@ services:
|
||||||
- ./certs/server.crt:/etc/certs/redis.crt
|
- ./certs/server.crt:/etc/certs/redis.crt
|
||||||
- ./certs/server.key:/etc/certs/redis.key
|
- ./certs/server.key:/etc/certs/redis.key
|
||||||
- ./certs/ca.crt:/etc/certs/ca.crt
|
- ./certs/ca.crt:/etc/certs/ca.crt
|
||||||
|
- ./redis/single-tls:/usr/local/etc/redis
|
||||||
ports:
|
ports:
|
||||||
- "6380:6380"
|
- "6380:6380"
|
||||||
command:
|
command: redis-server /usr/local/etc/redis/redis.conf
|
||||||
- redis-server
|
|
||||||
- "--bind 0.0.0.0 ::"
|
|
||||||
- --requirepass public
|
|
||||||
- --tls-port 6380
|
|
||||||
- --tls-cert-file /etc/certs/redis.crt
|
|
||||||
- --tls-key-file /etc/certs/redis.key
|
|
||||||
- --tls-ca-cert-file /etc/certs/ca.crt
|
|
||||||
- --tls-protocols "TLSv1.3"
|
|
||||||
- --tls-ciphersuites "TLS_CHACHA20_POLY1305_SHA256"
|
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
emqx_bridge:
|
emqx_bridge:
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
bind :: 0.0.0.0
|
bind :: 0.0.0.0
|
||||||
port 6379
|
port 6379
|
||||||
requirepass public
|
|
||||||
|
|
||||||
cluster-enabled yes
|
cluster-enabled yes
|
||||||
|
|
||||||
|
masteruser default
|
||||||
masterauth public
|
masterauth public
|
||||||
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
protected-mode no
|
protected-mode no
|
||||||
daemonize no
|
daemonize no
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
user default on >public ~* &* +@all
|
||||||
|
user test_user on >test_passwd ~* &* +@all
|
|
@ -1,10 +1,11 @@
|
||||||
bind :: 0.0.0.0
|
bind :: 0.0.0.0
|
||||||
port 6379
|
port 6379
|
||||||
requirepass public
|
|
||||||
|
|
||||||
cluster-enabled yes
|
cluster-enabled yes
|
||||||
|
|
||||||
|
masteruser default
|
||||||
masterauth public
|
masterauth public
|
||||||
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
tls-port 6389
|
tls-port 6389
|
||||||
tls-cert-file /etc/certs/cert.pem
|
tls-cert-file /etc/certs/cert.pem
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
user default on >public ~* &* +@all
|
||||||
|
user test_user on >test_passwd ~* &* +@all
|
|
@ -1,6 +1,6 @@
|
||||||
bind :: 0.0.0.0
|
bind :: 0.0.0.0
|
||||||
port 6379
|
port 6379
|
||||||
requirepass public
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
protected-mode no
|
protected-mode no
|
||||||
daemonize no
|
daemonize no
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
bind :: 0.0.0.0
|
bind :: 0.0.0.0
|
||||||
port 6379
|
port 6379
|
||||||
requirepass public
|
|
||||||
|
|
||||||
replicaof redis-sentinel-master 6379
|
replicaof redis-sentinel-master 6379
|
||||||
|
masteruser default
|
||||||
masterauth public
|
masterauth public
|
||||||
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
protected-mode no
|
protected-mode no
|
||||||
daemonize no
|
daemonize no
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
user default on >public ~* &* +@all
|
||||||
|
user test_user on >test_passwd ~* &* +@all
|
|
@ -1,6 +1,6 @@
|
||||||
bind :: 0.0.0.0
|
bind :: 0.0.0.0
|
||||||
port 6379
|
port 6379
|
||||||
requirepass public
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
tls-port 6389
|
tls-port 6389
|
||||||
tls-cert-file /etc/certs/cert.pem
|
tls-cert-file /etc/certs/cert.pem
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
bind :: 0.0.0.0
|
bind :: 0.0.0.0
|
||||||
port 6379
|
port 6379
|
||||||
requirepass public
|
|
||||||
|
|
||||||
replicaof redis-sentinel-tls-master 6389
|
replicaof redis-sentinel-tls-master 6389
|
||||||
|
masteruser default
|
||||||
masterauth public
|
masterauth public
|
||||||
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
tls-port 6389
|
tls-port 6389
|
||||||
tls-replication yes
|
tls-replication yes
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
user default on >public ~* &* +@all
|
||||||
|
user test_user on >test_passwd ~* &* +@all
|
|
@ -0,0 +1,3 @@
|
||||||
|
bind :: 0.0.0.0
|
||||||
|
port 6379
|
||||||
|
aclfile /usr/local/etc/redis/users.acl
|
|
@ -0,0 +1,2 @@
|
||||||
|
user default on >public ~* &* +@all
|
||||||
|
user test_user on >test_passwd ~* &* +@all
|
|
@ -0,0 +1,9 @@
|
||||||
|
bind :: 0.0.0.0
|
||||||
|
aclfile /usr/local/etc/redis/users.acl
|
||||||
|
|
||||||
|
tls-port 6380
|
||||||
|
tls-cert-file /etc/certs/redis.crt
|
||||||
|
tls-key-file /etc/certs/redis.key
|
||||||
|
tls-ca-cert-file /etc/certs/ca.crt
|
||||||
|
tls-protocols "TLSv1.3"
|
||||||
|
tls-ciphersuites "TLS_CHACHA20_POLY1305_SHA256"
|
|
@ -0,0 +1,2 @@
|
||||||
|
user default on >public ~* &* +@all
|
||||||
|
user test_user on >test_passwd ~* &* +@all
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_bridge_redis, [
|
{application, emqx_bridge_redis, [
|
||||||
{description, "EMQX Enterprise Redis Bridge"},
|
{description, "EMQX Enterprise Redis Bridge"},
|
||||||
{vsn, "0.1.2"},
|
{vsn, "0.1.3"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [
|
{applications, [
|
||||||
kernel,
|
kernel,
|
||||||
|
|
|
@ -30,6 +30,11 @@
|
||||||
<<"local_topic">> => <<"local_topic/#">>
|
<<"local_topic">> => <<"local_topic/#">>
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
-define(USERNAME_PASSWORD_AUTH_OPTS, #{
|
||||||
|
<<"username">> => <<"test_user">>,
|
||||||
|
<<"password">> => <<"test_passwd">>
|
||||||
|
}).
|
||||||
|
|
||||||
-define(BATCH_SIZE, 5).
|
-define(BATCH_SIZE, 5).
|
||||||
|
|
||||||
-define(PROXY_HOST, "toxiproxy").
|
-define(PROXY_HOST, "toxiproxy").
|
||||||
|
@ -319,6 +324,22 @@ t_permanent_error(_Config) ->
|
||||||
),
|
),
|
||||||
{ok, _} = emqx_bridge:remove(Type, Name).
|
{ok, _} = emqx_bridge:remove(Type, Name).
|
||||||
|
|
||||||
|
t_auth_username_password(_Config) ->
|
||||||
|
Name = <<"mybridge">>,
|
||||||
|
Type = <<"redis_single">>,
|
||||||
|
ResourceId = emqx_bridge_resource:resource_id(Type, Name),
|
||||||
|
BridgeConfig = username_password_redis_bridge_config(),
|
||||||
|
?assertMatch(
|
||||||
|
{ok, _},
|
||||||
|
emqx_bridge:create(Type, Name, BridgeConfig)
|
||||||
|
),
|
||||||
|
?WAIT(
|
||||||
|
{ok, connected},
|
||||||
|
emqx_resource:health_check(ResourceId),
|
||||||
|
5
|
||||||
|
),
|
||||||
|
{ok, _} = emqx_bridge:remove(Type, Name).
|
||||||
|
|
||||||
t_create_disconnected(Config) ->
|
t_create_disconnected(Config) ->
|
||||||
Name = <<"toxic_bridge">>,
|
Name = <<"toxic_bridge">>,
|
||||||
Type = <<"redis_single">>,
|
Type = <<"redis_single">>,
|
||||||
|
@ -528,6 +549,19 @@ toxiproxy_redis_bridge_config() ->
|
||||||
},
|
},
|
||||||
maps:merge(Conf0, ?COMMON_REDIS_OPTS).
|
maps:merge(Conf0, ?COMMON_REDIS_OPTS).
|
||||||
|
|
||||||
|
username_password_redis_bridge_config() ->
|
||||||
|
Conf0 = ?REDIS_TOXYPROXY_CONNECT_CONFIG#{
|
||||||
|
<<"resource_opts">> => #{
|
||||||
|
<<"query_mode">> => <<"sync">>,
|
||||||
|
<<"worker_pool_size">> => <<"1">>,
|
||||||
|
<<"batch_size">> => integer_to_binary(?BATCH_SIZE),
|
||||||
|
<<"health_check_interval">> => <<"1s">>,
|
||||||
|
<<"start_timeout">> => <<"15s">>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Conf1 = maps:merge(Conf0, ?COMMON_REDIS_OPTS),
|
||||||
|
maps:merge(Conf1, ?USERNAME_PASSWORD_AUTH_OPTS).
|
||||||
|
|
||||||
invalid_command_bridge_config() ->
|
invalid_command_bridge_config() ->
|
||||||
#{redis_single := #{tcp := Conf0}} = redis_connect_configs(),
|
#{redis_single := #{tcp := Conf0}} = redis_connect_configs(),
|
||||||
Conf1 = maps:merge(Conf0, ?COMMON_REDIS_OPTS),
|
Conf1 = maps:merge(Conf0, ?COMMON_REDIS_OPTS),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{erl_opts, [debug_info]}.
|
{erl_opts, [debug_info]}.
|
||||||
{deps, [
|
{deps, [
|
||||||
%% NOTE: mind ecpool version when updating eredis_cluster version
|
%% NOTE: mind ecpool version when updating eredis_cluster version
|
||||||
{eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.8.1"}}},
|
{eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.8.2"}}},
|
||||||
{emqx_connector, {path, "../../apps/emqx_connector"}},
|
{emqx_connector, {path, "../../apps/emqx_connector"}},
|
||||||
{emqx_resource, {path, "../../apps/emqx_resource"}}
|
{emqx_resource, {path, "../../apps/emqx_resource"}}
|
||||||
]}.
|
]}.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_redis, [
|
{application, emqx_redis, [
|
||||||
{description, "EMQX Redis Database Connector"},
|
{description, "EMQX Redis Database Connector"},
|
||||||
{vsn, "0.1.0"},
|
{vsn, "0.1.1"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [
|
{applications, [
|
||||||
kernel,
|
kernel,
|
||||||
|
|
|
@ -146,6 +146,7 @@ on_start(
|
||||||
Opts =
|
Opts =
|
||||||
[
|
[
|
||||||
{pool_size, PoolSize},
|
{pool_size, PoolSize},
|
||||||
|
{username, maps:get(username, Config, undefined)},
|
||||||
{password, maps:get(password, Config, "")},
|
{password, maps:get(password, Config, "")},
|
||||||
{auto_reconnect, ?AUTO_RECONNECT_INTERVAL}
|
{auto_reconnect, ?AUTO_RECONNECT_INTERVAL}
|
||||||
] ++ Database ++ Servers,
|
] ++ Database ++ Servers,
|
||||||
|
@ -292,6 +293,7 @@ connect(Opts) ->
|
||||||
redis_fields() ->
|
redis_fields() ->
|
||||||
[
|
[
|
||||||
{pool_size, fun emqx_connector_schema_lib:pool_size/1},
|
{pool_size, fun emqx_connector_schema_lib:pool_size/1},
|
||||||
|
{username, fun emqx_connector_schema_lib:username/1},
|
||||||
{password, fun emqx_connector_schema_lib:password/1},
|
{password, fun emqx_connector_schema_lib:password/1},
|
||||||
{database, #{
|
{database, #{
|
||||||
type => non_neg_integer(),
|
type => non_neg_integer(),
|
||||||
|
|
|
@ -137,6 +137,31 @@ perform_lifecycle_check(ResourceId, InitialConfig, RedisCommand) ->
|
||||||
#{timeout => 500}
|
#{timeout => 500}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
% check authentication methods
|
||||||
|
?assertEqual(
|
||||||
|
{ok, <<"OK">>},
|
||||||
|
emqx_resource:query(ResourceId, {cmd, ["AUTH", "public"]})
|
||||||
|
),
|
||||||
|
?assertEqual(
|
||||||
|
{error, <<"WRONGPASS invalid username-password pair or user is disabled.">>},
|
||||||
|
emqx_resource:query(ResourceId, {cmd, ["AUTH", "test_passwd"]})
|
||||||
|
),
|
||||||
|
?assertEqual(
|
||||||
|
{ok, <<"OK">>},
|
||||||
|
emqx_resource:query(ResourceId, {cmd, ["AUTH", "test_user", "test_passwd"]})
|
||||||
|
),
|
||||||
|
?assertEqual(
|
||||||
|
{error, <<"WRONGPASS invalid username-password pair or user is disabled.">>},
|
||||||
|
emqx_resource:query(ResourceId, {cmd, ["AUTH", "test_user", "public"]})
|
||||||
|
),
|
||||||
|
?assertEqual(
|
||||||
|
{error, <<"WRONGPASS invalid username-password pair or user is disabled.">>},
|
||||||
|
emqx_resource:query(ResourceId, {cmd, ["AUTH", "wrong_user", "test_passwd"]})
|
||||||
|
),
|
||||||
|
?assertEqual(
|
||||||
|
{error, <<"WRONGPASS invalid username-password pair or user is disabled.">>},
|
||||||
|
emqx_resource:query(ResourceId, {cmd, ["AUTH", "wrong_user", "public"]})
|
||||||
|
),
|
||||||
?assertEqual(ok, emqx_resource:stop(ResourceId)),
|
?assertEqual(ok, emqx_resource:stop(ResourceId)),
|
||||||
% Resource will be listed still, but state will be changed and healthcheck will fail
|
% Resource will be listed still, but state will be changed and healthcheck will fail
|
||||||
% as the worker no longer exists.
|
% as the worker no longer exists.
|
||||||
|
@ -186,7 +211,8 @@ redis_config_sentinel() ->
|
||||||
" redis_type = ~s\n" ++
|
" redis_type = ~s\n" ++
|
||||||
MaybeSentinel ++
|
MaybeSentinel ++
|
||||||
MaybeDatabase ++
|
MaybeDatabase ++
|
||||||
" password = public\n" ++
|
" username = test_user\n" ++
|
||||||
|
" password = test_passwd\n" ++
|
||||||
" ~s = \"~s:~b\"\n" ++
|
" ~s = \"~s:~b\"\n" ++
|
||||||
" " ++
|
" " ++
|
||||||
""
|
""
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added support for specifying username in Redis authentication.
|
Loading…
Reference in New Issue