Przeglądaj źródła

Merge pull request #6416 from JimMoen/log-for-proxy-protocol

feat(frame): better log for proxy_protocol config disabled
JimMoen 4 lat temu
rodzic
commit
812d123453
5 zmienionych plików z 50 dodań i 3 usunięć
  1. 12 0
      .gitignore
  2. 4 0
      src/emqx.appup.src
  3. 6 1
      src/emqx_connection.erl
  4. 18 0
      src/emqx_frame.erl
  5. 10 2
      test/emqx_frame_SUITE.erl

+ 12 - 0
.gitignore

@@ -47,3 +47,15 @@ dist.zip
 scripts/git-token
 etc/*.seg
 _upgrade_base/
+erlang_ls.config
+.els_cache/
+# VSCode files
+.vs/
+.vscode/
+# Emacs Backup files
+*~
+# Emacs temporary files
+.#*
+*#
+# For direnv
+.envrc

+ 4 - 0
src/emqx.appup.src

@@ -3,12 +3,14 @@
   [{"4.3.11",
     [{load_module,emqx_vm,brutal_purge,soft_purge,[]},
      {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
+     {load_module,emqx_frame,brutal_purge,soft_purge,[]},
      {load_module,emqx_http_lib,brutal_purge,soft_purge,[]}]},
    {"4.3.10",
     [{load_module,emqx_vm,brutal_purge,soft_purge,[]},
      {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
      {load_module,emqx_http_lib,brutal_purge,soft_purge,[]},
      {load_module,emqx_app,brutal_purge,soft_purge,[]},
+     {load_module,emqx_frame,brutal_purge,soft_purge,[]},
      {load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
    {"4.3.9",
     [{load_module,emqx_vm,brutal_purge,soft_purge,[]},
@@ -194,12 +196,14 @@
   [{"4.3.11",
     [{load_module,emqx_vm,brutal_purge,soft_purge,[]},
      {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
+     {load_module,emqx_frame,brutal_purge,soft_purge,[]},
      {load_module,emqx_http_lib,brutal_purge,soft_purge,[]}]},
    {"4.3.10",
     [{load_module,emqx_vm,brutal_purge,soft_purge,[]},
      {load_module,emqx_sys_mon,brutal_purge,soft_purge,[]},
      {load_module,emqx_http_lib,brutal_purge,soft_purge,[]},
      {load_module,emqx_app,brutal_purge,soft_purge,[]},
+     {load_module,emqx_frame,brutal_purge,soft_purge,[]},
      {load_module,emqx_connection,brutal_purge,soft_purge,[]}]},
    {"4.3.9",
     [{load_module,emqx_vm,brutal_purge,soft_purge,[]},

+ 6 - 1
src/emqx_connection.erl

@@ -629,10 +629,15 @@ parse_incoming(Data, Packets, State = #state{parse_state = ParseState}) ->
             NState = State#state{parse_state = NParseState},
             parse_incoming(Rest, [Packet|Packets], NState)
     catch
+        error:proxy_protocol_config_disabled:_Stk ->
+            ?LOG(error,
+                 "~nMalformed packet, "
+                 "please check proxy_protocol config for specific listeners and zones~n"),
+            {[{frame_error, proxy_protocol_config_disabled} | Packets], State};
         error:Reason:Stk ->
             ?LOG(error, "~nParse failed for ~0p~n~0p~nFrame data:~0p",
                  [Reason, Stk, Data]),
-            {[{frame_error, Reason}|Packets], State}
+            {[{frame_error, Reason} | Packets], State}
     end.
 
 -compile({inline, [next_incoming_msgs/1]}).

+ 18 - 0
src/emqx_frame.erl

@@ -71,8 +71,19 @@
 
 -define(MULTIPLIER_MAX, 16#200000).
 
+%% proxy_protocol v1 header human readable
+-define(PPV1_PROXY, "PROXY ").
+-define(PPV1_PROXY_UNKNOWN, "PROXY UNKNOWN").
+%% proxy_protocol v2 header signature:
+%% 16#0D,16#0A, 16#0D,16#0A,16#00,16#0D,16#0A,16#51,16#55,16#49,16#54,16#0A
+-define(PPV2_HEADER_SIG, "\r\n\r\n\0\r\nQUIT\n").
+
 -dialyzer({no_match, [serialize_utf8_string/2]}).
 
+-ifdef(TEST).
+-export([parse_variable_byte_integer/1]).
+-endif.
+
 %%--------------------------------------------------------------------
 %% Init Parse State
 %%--------------------------------------------------------------------
@@ -100,6 +111,13 @@ parse(Bin) ->
 -spec(parse(binary(), parse_state()) -> parse_result()).
 parse(<<>>, {none, Options}) ->
     {more, {none, Options}};
+parse(<<?PPV1_PROXY, IPVer:5/binary, _Rest/binary>>, {none, _Options})
+  when IPVer =:= <<"TCP4 ">> orelse IPVer =:= <<"TCP6 ">> ->
+    error(proxy_protocol_config_disabled);
+parse(<<?PPV1_PROXY_UNKNOWN, _Rest/binary>>, {none, _Options}) ->
+    error(proxy_protocol_config_disabled);
+parse(<<?PPV2_HEADER_SIG, _Rest/binary>>, {none, _Options}) ->
+    error(proxy_protocol_config_disabled);
 parse(<<Type:4, Dup:1, QoS:2, Retain:1, Rest/binary>>,
       {none, Options = #{strict_mode := StrictMode}}) ->
     %% Validate header if strict mode.

+ 10 - 2
test/emqx_frame_SUITE.erl

@@ -43,7 +43,9 @@ groups() ->
     [{parse, [parallel],
       [t_parse_cont,
        t_parse_frame_too_large,
-       t_parse_frame_malformed_variable_byte_integer
+       t_parse_frame_malformed_variable_byte_integer,
+       t_parse_frame_variable_byte_integer,
+       t_parse_frame_proxy_protocol %% proxy_protocol_config_disabled packet.
       ]},
      {connect, [parallel],
       [t_serialize_parse_v3_connect,
@@ -142,6 +144,13 @@ t_parse_frame_variable_byte_integer(_) ->
     ?catch_error(malformed_variable_byte_integer,
         emqx_frame:parse_variable_byte_integer(Bin)).
 
+t_parse_frame_proxy_protocol(_) ->
+    BinList = [ <<"PROXY TCP4 ">>, <<"PROXY TCP6 ">>, <<"PROXY UNKNOWN">>
+              , <<"\r\n\r\n\0\r\nQUIT\n">>],
+    [?assertError( proxy_protocol_config_disabled
+                 , emqx_frame:parse(Bin))
+     || Bin <- BinList].
+
 t_serialize_parse_v3_connect(_) ->
     Bin = <<16,37,0,6,77,81,73,115,100,112,3,2,0,60,0,23,109,111,115,
             113,112,117, 98,47,49,48,52,53,49,45,105,77,97,99,46,108,
@@ -555,4 +564,3 @@ parse_to_packet(Bin, Opts) ->
     Packet.
 
 payload(Len) -> iolist_to_binary(lists:duplicate(Len, 1)).
-