Przeglądaj źródła

fix(ws connection): fix peer_cert_as_username error when ws connect

zhanghongtong 4 lat temu
rodzic
commit
446a69c814
3 zmienionych plików z 35 dodań i 11 usunięć
  1. 16 2
      etc/emqx.conf
  2. 5 1
      priv/emqx.schema
  3. 14 8
      src/emqx_ws_connection.erl

+ 16 - 2
etc/emqx.conf

@@ -1113,14 +1113,14 @@ listener.tcp.external.access.1 = allow all
 
 ## Enable the option for X.509 certificate based authentication.
 ## EMQX will use the common name of certificate as MQTT username.
-## The proxy-protocol protocol can get the certificate CN through tcp
+## Only support Proxy Protocol V2, the CN is available in Proxy Protocol V2 additional info
 ##
 ## Value: cn
 ## listener.tcp.external.peer_cert_as_username = cn
 
 ## Enable the option for X.509 certificate based authentication.
 ## EMQX will use the common name of certificate as MQTT clientid.
-## The proxy-protocol protocol can get the certificate CN through tcp
+## Only support Proxy Protocol V2, the CN is available in Proxy Protocol V2 additional info
 ##
 ## Value: cn
 ## listener.tcp.external.peer_cert_as_clientid = cn
@@ -1635,6 +1635,20 @@ listener.ws.external.access.1 = allow all
 ## Value: Duration
 ## listener.ws.external.proxy_protocol_timeout = 3s
 
+## Enable the option for X.509 certificate based authentication.
+## EMQX will use the common name of certificate as MQTT username.
+## Only support Proxy Protocol V2, the CN is available in Proxy Protocol V2 additional info
+##
+## Value: cn
+## listener.ws.external.peer_cert_as_username = cn
+
+## Enable the option for X.509 certificate based authentication.
+## EMQX will use the common name of certificate as MQTT clientid.
+## Only support Proxy Protocol V2, the CN is available in Proxy Protocol V2 additional info
+##
+## Value: cn
+## listener.ws.external.peer_cert_as_clientid = cn
+
 ## The TCP backlog of external MQTT/WebSocket Listener.
 ##
 ## See: listener.ws.$name.backlog

+ 5 - 1
priv/emqx.schema

@@ -1647,7 +1647,11 @@ end}.
 ]}.
 
 {mapping, "listener.ws.$name.peer_cert_as_username", "emqx.listeners", [
-  {datatype, {enum, [cn, dn, crt]}}
+  {datatype, {enum, [cn]}}
+]}.
+
+{mapping, "listener.ws.$name.peer_cert_as_clientid", "emqx.listeners", [
+  {datatype, {enum, [cn]}}
 ]}.
 
 {mapping, "listener.ws.$name.check_origin_enable", "emqx.listeners", [

+ 14 - 8
src/emqx_ws_connection.erl

@@ -248,15 +248,21 @@ check_origin_header(Req, Opts) ->
     end.
 
 websocket_init([Req, Opts]) ->
-    Peername = case proplists:get_bool(proxy_protocol, Opts)
-                    andalso maps:get(proxy_header, Req) of
-                   #{src_address := SrcAddr, src_port := SrcPort} ->
-                       {SrcAddr, SrcPort};
-                   _ ->
-                       get_peer(Req, Opts)
-               end,
+    {Peername, Peercert} =
+        case proplists:get_bool(proxy_protocol, Opts)
+        andalso maps:get(proxy_header, Req) of
+            #{src_address := SrcAddr, src_port := SrcPort, ssl := SSL} ->
+                ProxyName = {SrcAddr, SrcPort},
+                %% Notice: Only CN is available in Proxy Protocol V2 additional info
+                ProxySSL = case maps:get(cn, SSL, undefined) of
+                             undeined -> nossl;
+                             CN -> [{pp2_ssl_cn, CN}]
+                           end,
+                {ProxyName, ProxySSL};
+            _ ->
+                {get_peer(Req, Opts), cowboy_req:cert(Req)}
+        end,
     Sockname = cowboy_req:sock(Req),
-    Peercert = cowboy_req:cert(Req),
     WsCookie = try cowboy_req:parse_cookies(Req)
                catch
                    error:badarg ->