Fix issue #1335 - Forward real client IP using a reverse proxy for websocket
This commit is contained in:
parent
a5e06308e5
commit
4915195b1e
|
@ -28,7 +28,7 @@
|
|||
|
||||
-include("emqttd_internal.hrl").
|
||||
|
||||
-import(proplists, [get_value/3, get_value/2]).
|
||||
-import(proplists, [get_value/3]).
|
||||
|
||||
%% API Exports
|
||||
-export([start_link/4]).
|
||||
|
@ -93,7 +93,7 @@ init([Env, WsPid, Req, ReplyChannel]) ->
|
|||
process_flag(trap_exit, true),
|
||||
Conn = Req:get(connection),
|
||||
true = link(WsPid),
|
||||
case peername(Env, Req) of
|
||||
case Req:get(peername) of
|
||||
{ok, Peername} ->
|
||||
Headers = mochiweb_headers:to_list(
|
||||
mochiweb_request:get(headers, Req)),
|
||||
|
@ -321,32 +321,3 @@ gc(State) ->
|
|||
Cb = fun() -> emit_stats(State) end,
|
||||
emqttd_gc:maybe_force_gc(#wsclient_state.force_gc_count, State, Cb).
|
||||
|
||||
peername(Env, Req) ->
|
||||
Conn = Req:get(connection),
|
||||
case Conn:peername() of
|
||||
{ok, Peername} ->
|
||||
% return original address, if existed
|
||||
case last_forwarded(get_value(Conn:type(), Env, []), Req) of
|
||||
undefined -> {ok, Peername};
|
||||
Forwarded -> {ok, Forwarded}
|
||||
end;
|
||||
{error, Reason} -> {error, Reason}
|
||||
end.
|
||||
|
||||
last_forwarded([], _) -> undefined;
|
||||
last_forwarded(Conf, Req) ->
|
||||
HostHeader = get_value(proxy_ipaddress_header, Conf),
|
||||
PortHeader = get_value(proxy_port_header, Conf),
|
||||
case tune_host(Req:get_header_value(HostHeader)) of
|
||||
undefined -> undefined;
|
||||
Host -> {Host, tune_port(Req:get_header_value(PortHeader))}
|
||||
end.
|
||||
|
||||
tune_host(undefined) -> undefined;
|
||||
tune_host(Hosts) ->
|
||||
{ok, Last} = inet:parse_address(string:strip(lists:last(string:tokens(Hosts, ",")))),
|
||||
Last.
|
||||
|
||||
tune_port(undefined) -> undefined;
|
||||
tune_port(Port) -> list_to_integer(Port).
|
||||
|
||||
|
|
|
@ -39,25 +39,8 @@ start_client(WsPid, Req, ReplyChannel) ->
|
|||
%%--------------------------------------------------------------------
|
||||
|
||||
init([]) ->
|
||||
Env = lists:append(emqttd:env(client, []),
|
||||
emqttd:env(protocol, []) ++ forwarded_header()),
|
||||
Env = lists:append(emqttd:env(client, []), emqttd:env(protocol, [])),
|
||||
{ok, {{simple_one_for_one, 0, 1},
|
||||
[{ws_client, {emqttd_ws_client, start_link, [Env]},
|
||||
temporary, 5000, worker, [emqttd_ws_client]}]}}.
|
||||
|
||||
forwarded_header() ->
|
||||
Env = [{Proto, Opts} || {Proto, _, Opts} <- emqttd:env(listeners, []), Proto == ws orelse Proto == wss],
|
||||
lists:foldl(fun({Proto, Opts}, Acc) ->
|
||||
Proto1 = case Proto of
|
||||
ws -> tcp;
|
||||
wss -> ssl
|
||||
end,
|
||||
case {proplists:get_value(proxy_ipaddress_header, Opts),
|
||||
proplists:get_value(proxy_port_header, Opts)} of
|
||||
{undefined, _} -> Acc;
|
||||
{AddrHeader, undefined} -> [{Proto1, [{proxy_ipaddress_header, AddrHeader}]} | Acc];
|
||||
{AddrHeader, PortHeader} -> [{Proto1, [{proxy_ipaddress_header, AddrHeader},
|
||||
{proxy_port_header, PortHeader}]} | Acc]
|
||||
end
|
||||
end, [], Env).
|
||||
|
||||
|
|
Loading…
Reference in New Issue