fix(authz): should apply no rule on superuser
This commit is contained in:
parent
e76b49c036
commit
e49686a276
|
@ -8,20 +8,20 @@
|
||||||
if it's a HTTPs server, we didn't check if TLS handshake was successful.
|
if it's a HTTPs server, we didn't check if TLS handshake was successful.
|
||||||
[commits/6b45d2ea](https://github.com/emqx/emqx/commit/6b45d2ea9fde6d3b4a5b007f7a8c5a1c573d141e)
|
[commits/6b45d2ea](https://github.com/emqx/emqx/commit/6b45d2ea9fde6d3b4a5b007f7a8c5a1c573d141e)
|
||||||
* The `create_at` field of rules is missing after emqx restarts. [commits/5fc09e6b](https://github.com/emqx/emqx/commit/5fc09e6b950c340243d7be627a0ce1700691221c)
|
* The `create_at` field of rules is missing after emqx restarts. [commits/5fc09e6b](https://github.com/emqx/emqx/commit/5fc09e6b950c340243d7be627a0ce1700691221c)
|
||||||
* The rule engine's jq function now works even when the path to the EMQX install dir contains spaces
|
* Avoid apply any ACL checks on superusers [#8452](https://github.com/emqx/emqx/pull/8452)
|
||||||
|
|
||||||
# 5.0.3
|
# 5.0.3
|
||||||
|
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
* Websocket listener failed to read headers `X-Forwared-For` and `X-Forwarded-Port` [8415](https://github.com/emqx/emqx/pull/8415)
|
* Websocket listener failed to read headers `X-Forwared-For` and `X-Forwarded-Port` [#8415](https://github.com/emqx/emqx/pull/8415)
|
||||||
* Deleted `cluster_singleton` from MQTT bridge config document. This config is no longer applicable in 5.0 [8407](https://github.com/emqx/emqx/pull/8407)
|
* Deleted `cluster_singleton` from MQTT bridge config document. This config is no longer applicable in 5.0 [#8407](https://github.com/emqx/emqx/pull/8407)
|
||||||
* Fix `emqx/emqx:latest` docker image publish to use the Erlang flavor, but not Elixir flavor [8414](https://github.com/emqx/emqx/pull/8414)
|
* Fix `emqx/emqx:latest` docker image publish to use the Erlang flavor, but not Elixir flavor [#8414](https://github.com/emqx/emqx/pull/8414)
|
||||||
* Changed the `exp` field in JWT auth to be optional rather than required to fix backwards compatability with 4.X releases. [8425](https://github.com/emqx/emqx/pull/8425)
|
* Changed the `exp` field in JWT auth to be optional rather than required to fix backwards compatability with 4.X releases. [#8425](https://github.com/emqx/emqx/pull/8425)
|
||||||
|
|
||||||
## Enhancements
|
## Enhancements
|
||||||
|
|
||||||
* Improve the speed of dashboard's HTTP API routing rule generation, which sometimes causes timeout [8438](https://github.com/emqx/emqx/pull/8438)
|
* Improve the speed of dashboard's HTTP API routing rule generation, which sometimes causes timeout [#8438](https://github.com/emqx/emqx/pull/8438)
|
||||||
|
|
||||||
# 5.0.2
|
# 5.0.2
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ This had been the biggest obstacle for EMQX team to act agile enough in delivery
|
||||||
|
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
* Fixed a typo in `bin/emqx` which affects MacOs release when trying to enable Erlang distribution over TLS [8398](https://github.com/emqx/emqx/pull/8398)
|
* Fixed a typo in `bin/emqx` which affects MacOs release when trying to enable Erlang distribution over TLS [#8398](https://github.com/emqx/emqx/pull/8398)
|
||||||
* Restricted shell was accidentally disabled in 5.0.1, it has been added back. [8396](https://github.com/emqx/emqx/pull/8396)
|
* Restricted shell was accidentally disabled in 5.0.1, it has been added back. [#8396](https://github.com/emqx/emqx/pull/8396)
|
||||||
|
|
||||||
# 5.0.1
|
# 5.0.1
|
||||||
|
|
||||||
|
@ -67,25 +67,25 @@ Exceptions:
|
||||||
|
|
||||||
## Enhancements
|
## Enhancements
|
||||||
|
|
||||||
* Removed management API auth for prometheus scraping endpoint /api/v5/prometheus/stats [8299](https://github.com/emqx/emqx/pull/8299)
|
* Removed management API auth for prometheus scraping endpoint /api/v5/prometheus/stats [#8299](https://github.com/emqx/emqx/pull/8299)
|
||||||
* Added more TCP options for exhook (gRPC) connections. [8317](https://github.com/emqx/emqx/pull/8317)
|
* Added more TCP options for exhook (gRPC) connections. [#8317](https://github.com/emqx/emqx/pull/8317)
|
||||||
* HTTP Servers used for authentication and authorization will now indicate the result via the response body. [8374](https://github.com/emqx/emqx/pull/8374) [8377](https://github.com/emqx/emqx/pull/8377)
|
* HTTP Servers used for authentication and authorization will now indicate the result via the response body. [#8374](https://github.com/emqx/emqx/pull/8374) [#8377](https://github.com/emqx/emqx/pull/8377)
|
||||||
* Bulk subscribe/unsubscribe APIs [8356](https://github.com/emqx/emqx/pull/8356)
|
* Bulk subscribe/unsubscribe APIs [#8356](https://github.com/emqx/emqx/pull/8356)
|
||||||
* Added exclusive subscription [8315](https://github.com/emqx/emqx/pull/8315)
|
* Added exclusive subscription [#8315](https://github.com/emqx/emqx/pull/8315)
|
||||||
* Provide authentication counter metrics [8352](https://github.com/emqx/emqx/pull/8352) [8375](https://github.com/emqx/emqx/pull/8375)
|
* Provide authentication counter metrics [#8352](https://github.com/emqx/emqx/pull/8352) [#8375](https://github.com/emqx/emqx/pull/8375)
|
||||||
* Do not allow admin user self-deletion [8286](https://github.com/emqx/emqx/pull/8286)
|
* Do not allow admin user self-deletion [#8286](https://github.com/emqx/emqx/pull/8286)
|
||||||
* After restart, ensure to copy `cluster-override.conf` from the clustered node which has the greatest `tnxid`. [8333](https://github.com/emqx/emqx/pull/8333)
|
* After restart, ensure to copy `cluster-override.conf` from the clustered node which has the greatest `tnxid`. [#8333](https://github.com/emqx/emqx/pull/8333)
|
||||||
|
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
* A bug fix ported from 4.x: allow deleting subscriptions from `client.subscribe` hookpoint callback result. [8304](https://github.com/emqx/emqx/pull/8304) [8347](https://github.com/emqx/emqx/pull/8377)
|
* A bug fix ported from 4.x: allow deleting subscriptions from `client.subscribe` hookpoint callback result. [#8304](https://github.com/emqx/emqx/pull/8304) [#8347](https://github.com/emqx/emqx/pull/8377)
|
||||||
* Fixed Erlang distribution over TLS [8309](https://github.com/emqx/emqx/pull/8309)
|
* Fixed Erlang distribution over TLS [#8309](https://github.com/emqx/emqx/pull/8309)
|
||||||
* Made possible to override authentication configs from environment variables [8323](https://github.com/emqx/emqx/pull/8309)
|
* Made possible to override authentication configs from environment variables [#8323](https://github.com/emqx/emqx/pull/8309)
|
||||||
* Made authentication passwords in Mnesia database backward compatible to 4.x, so we can support data migration better. [8351](https://github.com/emqx/emqx/pull/8351)
|
* Made authentication passwords in Mnesia database backward compatible to 4.x, so we can support data migration better. [#8351](https://github.com/emqx/emqx/pull/8351)
|
||||||
* Fix plugins upload for rpm/deb installations [8379](https://github.com/emqx/emqx/pull/8379)
|
* Fix plugins upload for rpm/deb installations [#8379](https://github.com/emqx/emqx/pull/8379)
|
||||||
* Sync data/authz/acl.conf and data/certs from clustered nodes after a new node joins the cluster [8369](https://github.com/emqx/emqx/pull/8369)
|
* Sync data/authz/acl.conf and data/certs from clustered nodes after a new node joins the cluster [#8369](https://github.com/emqx/emqx/pull/8369)
|
||||||
* Ensure auto-retry of failed resources [8371](https://github.com/emqx/emqx/pull/8371)
|
* Ensure auto-retry of failed resources [#8371](https://github.com/emqx/emqx/pull/8371)
|
||||||
* Fix the issue that the count of `packets.connack.auth_error` is inaccurate when the client uses a protocol version below MQTT v5.0 to access [8178](https://github.com/emqx/emqx/pull/8178)
|
* Fix the issue that the count of `packets.connack.auth_error` is inaccurate when the client uses a protocol version below MQTT v5.0 to access [#8178](https://github.com/emqx/emqx/pull/8178)
|
||||||
|
|
||||||
## Others
|
## Others
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_authz, [
|
{application, emqx_authz, [
|
||||||
{description, "An OTP application"},
|
{description, "An OTP application"},
|
||||||
{vsn, "0.1.2"},
|
{vsn, "0.1.3"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_authz_app, []}},
|
{mod, {emqx_authz_app, []}},
|
||||||
{applications, [
|
{applications, [
|
||||||
|
|
|
@ -53,11 +53,12 @@
|
||||||
|
|
||||||
-type sources() :: [source()].
|
-type sources() :: [source()].
|
||||||
|
|
||||||
|
-define(METRIC_SUPERUSER, 'authorization.superuser').
|
||||||
-define(METRIC_ALLOW, 'authorization.matched.allow').
|
-define(METRIC_ALLOW, 'authorization.matched.allow').
|
||||||
-define(METRIC_DENY, 'authorization.matched.deny').
|
-define(METRIC_DENY, 'authorization.matched.deny').
|
||||||
-define(METRIC_NOMATCH, 'authorization.nomatch').
|
-define(METRIC_NOMATCH, 'authorization.nomatch').
|
||||||
|
|
||||||
-define(METRICS, [?METRIC_ALLOW, ?METRIC_DENY, ?METRIC_NOMATCH]).
|
-define(METRICS, [?METRIC_SUPERUSER, ?METRIC_ALLOW, ?METRIC_DENY, ?METRIC_NOMATCH]).
|
||||||
|
|
||||||
-define(IS_ENABLED(Enable), ((Enable =:= true) or (Enable =:= <<"true">>))).
|
-define(IS_ENABLED(Enable), ((Enable =:= true) or (Enable =:= <<"true">>))).
|
||||||
|
|
||||||
|
@ -308,6 +309,30 @@ authorize(
|
||||||
Topic,
|
Topic,
|
||||||
DefaultResult,
|
DefaultResult,
|
||||||
Sources
|
Sources
|
||||||
|
) ->
|
||||||
|
case maps:get(is_superuser, Client, false) of
|
||||||
|
true ->
|
||||||
|
log_allowed(#{
|
||||||
|
username => Username,
|
||||||
|
ipaddr => IpAddress,
|
||||||
|
topic => Topic,
|
||||||
|
is_superuser => true
|
||||||
|
}),
|
||||||
|
emqx_metrics:inc(?METRIC_SUPERUSER),
|
||||||
|
{stop, allow};
|
||||||
|
false ->
|
||||||
|
authorize_non_superuser(Client, PubSub, Topic, DefaultResult, Sources)
|
||||||
|
end.
|
||||||
|
|
||||||
|
authorize_non_superuser(
|
||||||
|
#{
|
||||||
|
username := Username,
|
||||||
|
peerhost := IpAddress
|
||||||
|
} = Client,
|
||||||
|
PubSub,
|
||||||
|
Topic,
|
||||||
|
DefaultResult,
|
||||||
|
Sources
|
||||||
) ->
|
) ->
|
||||||
case do_authorize(Client, PubSub, Topic, sources_with_defaults(Sources)) of
|
case do_authorize(Client, PubSub, Topic, sources_with_defaults(Sources)) of
|
||||||
{{matched, allow}, AuthzSource} ->
|
{{matched, allow}, AuthzSource} ->
|
||||||
|
@ -315,8 +340,7 @@ authorize(
|
||||||
'client.check_authz_complete',
|
'client.check_authz_complete',
|
||||||
[Client, PubSub, Topic, allow, AuthzSource]
|
[Client, PubSub, Topic, allow, AuthzSource]
|
||||||
),
|
),
|
||||||
?SLOG(info, #{
|
log_allowed(#{
|
||||||
msg => "authorization_permission_allowed",
|
|
||||||
username => Username,
|
username => Username,
|
||||||
ipaddr => IpAddress,
|
ipaddr => IpAddress,
|
||||||
topic => Topic,
|
topic => Topic,
|
||||||
|
@ -356,6 +380,9 @@ authorize(
|
||||||
{stop, DefaultResult}
|
{stop, DefaultResult}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
log_allowed(Meta) ->
|
||||||
|
?SLOG(info, Meta#{msg => "authorization_permission_allowed"}).
|
||||||
|
|
||||||
do_authorize(_Client, _PubSub, _Topic, []) ->
|
do_authorize(_Client, _PubSub, _Topic, []) ->
|
||||||
nomatch;
|
nomatch;
|
||||||
do_authorize(Client, PubSub, Topic, [#{enable := false} | Rest]) ->
|
do_authorize(Client, PubSub, Topic, [#{enable := false} | Rest]) ->
|
||||||
|
|
|
@ -84,8 +84,6 @@ t_ok(_Config) ->
|
||||||
<<"rules">> => <<"{allow, {user, \"username\"}, publish, [\"t\"]}.">>
|
<<"rules">> => <<"{allow, {user, \"username\"}, publish, [\"t\"]}.">>
|
||||||
}),
|
}),
|
||||||
|
|
||||||
io:format("~p", [emqx_authz:acl_conf_file()]),
|
|
||||||
|
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
allow,
|
allow,
|
||||||
emqx_access_control:authorize(ClientInfo, publish, <<"t">>)
|
emqx_access_control:authorize(ClientInfo, publish, <<"t">>)
|
||||||
|
@ -96,6 +94,31 @@ t_ok(_Config) ->
|
||||||
emqx_access_control:authorize(ClientInfo, subscribe, <<"t">>)
|
emqx_access_control:authorize(ClientInfo, subscribe, <<"t">>)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
t_superuser(_Config) ->
|
||||||
|
ClientInfo = #{
|
||||||
|
clientid => <<"clientid">>,
|
||||||
|
username => <<"username">>,
|
||||||
|
is_superuser => true,
|
||||||
|
peerhost => {127, 0, 0, 1},
|
||||||
|
zone => default,
|
||||||
|
listener => {tcp, default}
|
||||||
|
},
|
||||||
|
|
||||||
|
%% no rules apply to superuser
|
||||||
|
ok = setup_config(?RAW_SOURCE#{
|
||||||
|
<<"rules">> => <<"{deny, {user, \"username\"}, publish, [\"t\"]}.">>
|
||||||
|
}),
|
||||||
|
|
||||||
|
?assertEqual(
|
||||||
|
allow,
|
||||||
|
emqx_access_control:authorize(ClientInfo, publish, <<"t">>)
|
||||||
|
),
|
||||||
|
|
||||||
|
?assertEqual(
|
||||||
|
allow,
|
||||||
|
emqx_access_control:authorize(ClientInfo, subscribe, <<"t">>)
|
||||||
|
).
|
||||||
|
|
||||||
t_invalid_file(_Config) ->
|
t_invalid_file(_Config) ->
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error, bad_acl_file_content},
|
{error, bad_acl_file_content},
|
||||||
|
|
Loading…
Reference in New Issue