diff --git a/.github/workflows/apps_version_check.yaml b/.github/workflows/apps_version_check.yaml index 16dc5c218..b787a2afe 100644 --- a/.github/workflows/apps_version_check.yaml +++ b/.github/workflows/apps_version_check.yaml @@ -3,7 +3,7 @@ name: Check Apps Version on: [pull_request] jobs: - check_apps_version: + check_apps_version_4_x: runs-on: ubuntu-20.04 strategy: diff --git a/CHANGES-4.3.md b/CHANGES-4.3.md index cefb7f798..aeade59c6 100644 --- a/CHANGES-4.3.md +++ b/CHANGES-4.3.md @@ -17,6 +17,12 @@ File format: * Made possible for EMQX to boot from a Linux directory which has white spaces in its path. * Add support for JWT authorization [#7596] Now MQTT clients may be authorized with respect to a specific claim containing publish/subscribe topic whitelists. +* Better randomisation of app screts (changed from timestamp seeded sha hash (uuid) to crypto:strong_rand_bytes) + +### Bug fixes +* List subscription topic (/api/v4/subscriptions), the result do not match with multiple conditions. + +* SSL closed error bug fixed for redis client. ## v4.3.14 diff --git a/apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl b/apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl index 9e47333ed..aa3aeb3af 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl @@ -67,7 +67,8 @@ list(Bindings, Params) when map_size(Bindings) == 0 -> Topic0 -> Topic = emqx_mgmt_util:urldecode(Topic0), Data = emqx_mgmt:list_subscriptions_via_topic(Topic, ?format_fun), - minirest:return({ok, add_meta(Params, Data)}) + FilterData = filter_subscriptions(Data, Params), + minirest:return({ok, add_meta(Params, FilterData)}) end; list(#{node := Node} = Bindings, Params) -> @@ -85,7 +86,8 @@ list(#{node := Node} = Bindings, Params) -> Topic0 -> Topic = emqx_mgmt_util:urldecode(Topic0), Data = emqx_mgmt:list_subscriptions_via_topic(Node, Topic, ?format_fun), - minirest:return({ok, add_meta(Params, Data)}) + FilterData = filter_subscriptions(Data, Params), + minirest:return({ok, add_meta(Params, FilterData)}) end. add_meta(Params, List) -> @@ -169,3 +171,30 @@ update_ms(share, X, {{Pid, Topic}, Opts}) -> {{Pid, Topic}, Opts#{share => X}}; update_ms(qos, X, {{Pid, Topic}, Opts}) -> {{Pid, Topic}, Opts#{qos => X}}. + +filter_subscriptions(Data0, Params) -> + Data1 = filter_by_key(qos, qos(Params), Data0), + Data2 = filter_by_key(clientid, proplists:get_value(<<"clientid">>, Params), Data1), + case proplists:get_value(<<"share">>, Params) of + undefined -> Data2; + Share -> + Prefix = filename:join([<<"$share">>, Share]), + Size = byte_size(Prefix), + lists:filter(fun(#{topic := Topic}) -> + case Topic of + <> -> true; + _ -> false + end + end, + Data2) + end. + +qos(Params) -> + case proplists:get_value(<<"qos">>, Params) of + undefined -> undefined; + Qos when is_integer(Qos) -> Qos; + Qos when is_binary(Qos) -> binary_to_integer(Qos) + end. + +filter_by_key(_Key, undefined, List) -> List; +filter_by_key(Key, Value, List) -> lists:filter(fun(E) -> Value =:= maps:get(Key, E) end, List). diff --git a/apps/emqx_management/src/emqx_mgmt_auth.erl b/apps/emqx_management/src/emqx_mgmt_auth.erl index 5413cf95a..6eca989cf 100644 --- a/apps/emqx_management/src/emqx_mgmt_auth.erl +++ b/apps/emqx_management/src/emqx_mgmt_auth.erl @@ -138,8 +138,11 @@ generate_appsecret_if_need(InSecrt) when is_binary(InSecrt), byte_size(InSecrt) generate_appsecret_if_need(_) -> AppConf = application:get_env(?APP, application, []), case proplists:get_value(default_secret, AppConf) of - undefined -> emqx_guid:to_base62(emqx_guid:gen()); - Secret when is_binary(Secret) -> Secret + undefined -> + Random = crypto:strong_rand_bytes(32), + emqx_base62:encode(Random); + Secret when is_binary(Secret) -> + Secret end. -spec(get_appsecret(appid()) -> {appsecret() | undefined}). diff --git a/bin/emqx b/bin/emqx index 8caede90b..6a4f3fbb7 100755 --- a/bin/emqx +++ b/bin/emqx @@ -362,9 +362,9 @@ generate_config() { ## NOTE: the -args_file and -vm_args are the same file passed twice because args_file is used by beam, but not possible to get at runtime ## by calling init:get_arguments/0 lines="$(echo "$CUTTLEFISH_OUTPUT" | tail -1 \ - | sed -e $'s/-config/\\\nconfig=/g' \ - | sed -e $'s/-args_file/\\\nargs_file=/g' \ - | sed -e $'s/-vm_args/\\\nvm_args=/g')" + | sed -e $'s/-config/\\\nconfig=/g' \ + | sed -e $'s/-args_file/\\\nargs_file=/g' \ + | sed -e $'s/-vm_args/\\\nvm_args=/g')" CONFIG_FILE="$(trim "$(echo -e "$lines" | grep 'config=' | sed 's/config=//g')")" CUTTLE_GEN_ARG_FILE="$(trim "$(echo -e "$lines" | grep 'vm_args=' | sed 's/vm_args=//g')")" diff --git a/deploy/charts/emqx/README.md b/deploy/charts/emqx/README.md index 54d267415..935624769 100644 --- a/deploy/charts/emqx/README.md +++ b/deploy/charts/emqx/README.md @@ -70,18 +70,21 @@ Parameter | Description | Default Value `ingress.dashboard.enabled` | Enable ingress for EMQX Dashboard | false `ingress.dashboard.ingressClassName` | Set the ingress class for EMQX Dashboard `ingress.dashboard.path` | Ingress path for EMQX Dashboard | `/` +`ingress.dashboard.pathType` | Ingress pathType for EMQX Dashboard | `ImplementationSpecific` `ingress.dashboard.hosts` | Ingress hosts for EMQX Mgmt API | dashboard.emqx.local `ingress.dashboard.tls` | Ingress tls for EMQX Mgmt API | `[]` `ingress.dashboard.annotations` | Ingress annotations for EMQX Mgmt API | `{}` `ingress.mgmt.enabled` | Enable ingress for EMQX Mgmt API | `false` `ingress.mqtt.ingressClassName` | Set the ingress class for EMQX Mgmt API | `nil` `ingress.mgmt.path` | Ingress path for EMQX Mgmt API | `/` +`ingress.mgmt.pathType` | Ingress pathType for EMQX Mgmt API | `ImplementationSpecific` `ingress.mgmt.hosts` | Ingress hosts for EMQX Mgmt API | `api.emqx.local` `ingress.mgmt.tls` | Ingress tls for EMQX Mgmt API | `[]` `ingress.mgmt.annotations` | Ingress annotations for EMQX Mgmt API | `{}` `ingress.wss.enabled` | Enable ingress for EMQX Mgmt API | `false` `ingress.wss.ingressClassName` | Set the ingress class for EMQX Mgmt API | `nil` `ingress.wss.path` | Ingress path for EMQX WSS | `/` +`ingress.wss.pathType` | Ingress pathType for EMQX WSS | `ImplementationSpecific` `ingress.wss.hosts` | Ingress hosts for EMQX WSS | `wss.emqx.local` `ingress.wss.tls` | Ingress tls for EMQX WSS | `[]` `ingress.wss.annotations` | Ingress annotations for EMQX WSS | `{}` @@ -122,6 +125,7 @@ ingress: nginx.ingress.kubernetes.io/use-proxy-protocol: "false" nginx.ingress.kubernetes.io/proxy-protocol-header-timeout: "5s" path: /mqtt + pathType: ImplementationSpecific hosts: - myhost.example.com tls: diff --git a/deploy/charts/emqx/templates/ingress.dashboard.yaml b/deploy/charts/emqx/templates/ingress.dashboard.yaml index 9ea06cdc4..5a8bbd4a9 100644 --- a/deploy/charts/emqx/templates/ingress.dashboard.yaml +++ b/deploy/charts/emqx/templates/ingress.dashboard.yaml @@ -34,7 +34,7 @@ spec: paths: - path: / {{- if (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: ImplementationSpecific + pathType: {{ .Values.ingress.dashboard.pathType | default "ImplementationSpecific" }} {{- end }} backend: {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} diff --git a/deploy/charts/emqx/templates/ingress.mgmt.yaml b/deploy/charts/emqx/templates/ingress.mgmt.yaml index c9abe79a9..6c3811f77 100644 --- a/deploy/charts/emqx/templates/ingress.mgmt.yaml +++ b/deploy/charts/emqx/templates/ingress.mgmt.yaml @@ -34,7 +34,7 @@ spec: paths: - path: {{ $.Values.ingress.mgmt.path | default "/" }} {{- if (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: ImplementationSpecific + pathType: {{ .Values.ingress.mgmt.pathType | default "ImplementationSpecific" }} {{- end }} backend: {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} diff --git a/deploy/charts/emqx/templates/ingress.wss.yaml b/deploy/charts/emqx/templates/ingress.wss.yaml index 7c7b395a5..ec74889bc 100644 --- a/deploy/charts/emqx/templates/ingress.wss.yaml +++ b/deploy/charts/emqx/templates/ingress.wss.yaml @@ -34,7 +34,7 @@ spec: paths: - path: {{ $.Values.ingress.wss.path | default "/mqtt" }} {{- if (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: ImplementationSpecific + pathType: {{ .Values.ingress.wss.pathType | default "ImplementationSpecific" }} {{- end }} backend: {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} diff --git a/deploy/charts/emqx/values.yaml b/deploy/charts/emqx/values.yaml index bf66a2251..69ed2424e 100644 --- a/deploy/charts/emqx/values.yaml +++ b/deploy/charts/emqx/values.yaml @@ -210,6 +210,7 @@ ingress: # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" path: / + pathType: ImplementationSpecific hosts: - dashboard.emqx.local tls: [] @@ -221,6 +222,7 @@ ingress: # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" path: / + pathType: ImplementationSpecific hosts: - api.emqx.local tls: [] @@ -243,6 +245,7 @@ ingress: # nginx.ingress.kubernetes.io/use-proxy-protocol: "false" # nginx.ingress.kubernetes.io/proxy-protocol-header-timeout: "5s" path: /mqtt + pathType: ImplementationSpecific # path: /wss(\/.*)? hosts: - wss.emqx.local diff --git a/deploy/packages/emqx.service b/deploy/packages/emqx.service index def74a1a4..35be2ad61 100644 --- a/deploy/packages/emqx.service +++ b/deploy/packages/emqx.service @@ -11,10 +11,10 @@ Environment=HOME=/var/lib/emqx # Must use a 'bash' wrap for some OS # errno=13 'Permission denied' # Cannot create FIFO ... for writing -ExecStart=bash /usr/bin/emqx start +ExecStart=/bin/bash /usr/bin/emqx start LimitNOFILE=1048576 -ExecStop=bash /usr/bin/emqx stop +ExecStop=/bin/bash /usr/bin/emqx stop Restart=on-failure # When clustered, give the peers enough time to get this node's 'DOWN' event diff --git a/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl b/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl index 73aa0c614..a4504fe29 100644 --- a/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl +++ b/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl @@ -183,13 +183,21 @@ check(Username, Password) -> case lookup_user(Username) of [#mqtt_admin{password = PwdHash}] -> case is_valid_pwd(PwdHash, Password) of - true -> ok; - false -> {error, <<"Username/Password error">>} + true -> + ok; + false -> + ok = bad_login_penalty(), + {error, <<"Username/Password error">>} end; [] -> + ok = bad_login_penalty(), {error, <<"Username/Password error">>} end. +bad_login_penalty() -> + timer:sleep(2000), + ok. + is_valid_pwd(<>, Password) -> Hash =:= md5_hash(Salt, Password). diff --git a/rebar.config b/rebar.config index 9feb9fe9e..913f3c994 100644 --- a/rebar.config +++ b/rebar.config @@ -40,7 +40,7 @@ {deps, [ {gpb, "4.11.2"} %% gpb only used to build, but not for release, pin it here to avoid fetching a wrong version due to rebar plugins scattered in all the deps , {ehttpc, {git, "https://github.com/emqx/ehttpc", {tag, "0.2.0"}}} - , {eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.7.1"}}} + , {eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.7.2"}}} , {gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.8.0"}}} , {jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.5"}}} , {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.0"}}} diff --git a/scripts/update-appup.sh b/scripts/update-appup.sh index 4cfe4a06f..6b15d6917 100755 --- a/scripts/update-appup.sh +++ b/scripts/update-appup.sh @@ -102,7 +102,7 @@ else git fetch "$REMOTE" fi git reset --hard - git clean -fdx + git clean -ffdx git checkout "${PREV_TAG}" make "$PROFILE" popd