Add X-Forwarded-For header

This commit is contained in:
Maciej Szlosarczyk 2019-05-29 10:57:43 +03:00
parent ffc5ddaa3c
commit 750cdbd270
No known key found for this signature in database
GPG key ID: 41D62D42D3B0D765
5 changed files with 42 additions and 17 deletions

View file

@ -28,7 +28,6 @@
{ok, CrlFile} -> CrlFile {ok, CrlFile} -> CrlFile
end). end).
%% gen_server callbacks %% gen_server callbacks
-export([init/1, handle_cast/2, handle_call/3, start_link/1]). -export([init/1, handle_cast/2, handle_call/3, start_link/1]).

View file

@ -9,9 +9,9 @@
-export([init/1, handle_cast/2, handle_call/3, start_link/1]). -export([init/1, handle_cast/2, handle_call/3, start_link/1]).
-export([code_change/3]). -export([code_change/3]).
-export([request/5]). -export([request/6]).
-record(state,{socket, length, session_id, common_name, client_cert}). -record(state,{socket, session_id, common_name, client_cert, peer_ip}).
init(Socket) -> init(Socket) ->
logger:info("Created a worker process"), logger:info("Created a worker process"),
@ -22,18 +22,17 @@ start_link(Socket) ->
gen_server:start_link(?MODULE, Socket, []). gen_server:start_link(?MODULE, Socket, []).
handle_cast(serve, State = #state{socket=Socket}) -> handle_cast(serve, State = #state{socket=Socket}) ->
%% If certificate is revoked, this will fail right away here.
%% mod_epp does exactly the same thing.
{ok, SecureSocket} = ssl:handshake(Socket), {ok, SecureSocket} = ssl:handshake(Socket),
{ok, PeerCert} = ssl:peercert(SecureSocket), NewState = state_from_socket(SecureSocket, State),
{SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT} = {noreply, NewState};
epp_certs:headers_from_cert(PeerCert),
{noreply, State#state{socket=SecureSocket, common_name=SSL_CLIENT_S_DN_CN,
client_cert=SSL_CLIENT_CERT}};
handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN, handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN,
client_cert=SSL_CLIENT_CERT, client_cert=SSL_CLIENT_CERT,
session_id=SessionId}) -> session_id=SessionId,
peer_ip=PeerIp}) ->
Request = request("hello", SessionId, "", SSL_CLIENT_S_DN_CN, Request = request("hello", SessionId, "", SSL_CLIENT_S_DN_CN,
SSL_CLIENT_CERT), SSL_CLIENT_CERT, PeerIp),
logger:info("Request: ~p~n", [Request]), logger:info("Request: ~p~n", [Request]),
{_Status, _StatusCode, _Headers, ClientRef} = {_Status, _StatusCode, _Headers, ClientRef} =
@ -49,7 +48,8 @@ handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_
handle_cast(process_command, State = #state{socket=Socket, handle_cast(process_command, State = #state{socket=Socket,
common_name=SSL_CLIENT_S_DN_CN, common_name=SSL_CLIENT_S_DN_CN,
client_cert=SSL_CLIENT_CERT, client_cert=SSL_CLIENT_CERT,
session_id=SessionId}) -> session_id=SessionId,
peer_ip=PeerIp}) ->
Length = case read_length(Socket) of Length = case read_length(Socket) of
{ok, Data} -> {ok, Data} ->
Data; Data;
@ -69,7 +69,7 @@ handle_cast(process_command, State = #state{socket=Socket,
Command = epp_xml:get_command(XMLRecord), Command = epp_xml:get_command(XMLRecord),
Request = request(Command, SessionId, Frame, SSL_CLIENT_S_DN_CN, Request = request(Command, SessionId, Frame, SSL_CLIENT_S_DN_CN,
SSL_CLIENT_CERT), SSL_CLIENT_CERT, PeerIp),
logger:info("Request: ~p~n", [Request]), logger:info("Request: ~p~n", [Request]),
{_Status, _StatusCode, _Headers, ClientRef} = {_Status, _StatusCode, _Headers, ClientRef} =
@ -119,7 +119,7 @@ read_frame(Socket, FrameLength) ->
end. end.
%% Map request and return values %% Map request and return values
request(Command, SessionId, RawFrame, CommonName, ClientCert) -> request(Command, SessionId, RawFrame, CommonName, ClientCert, PeerIp) ->
URL = epp_router:route_request(Command), URL = epp_router:route_request(Command),
RequestMethod = epp_router:request_method(Command), RequestMethod = epp_router:request_method(Command),
Cookie = hackney_cookie:setcookie("session", SessionId, []), Cookie = hackney_cookie:setcookie("session", SessionId, []),
@ -131,7 +131,8 @@ request(Command, SessionId, RawFrame, CommonName, ClientCert) ->
end, end,
Headers = [{"SSL_CLIENT_CERT", ClientCert}, Headers = [{"SSL_CLIENT_CERT", ClientCert},
{"SSL_CLIENT_S_DN_CN", CommonName}, {"SSL_CLIENT_S_DN_CN", CommonName},
{"User-Agent", <<"EPP proxy">>}], {"User-Agent", <<"EPP proxy">>},
{"X-Forwarded-for", epp_util:readable_ip(PeerIp)}],
#epp_request{url=URL, method=RequestMethod, body=Body, cookies=[Cookie], #epp_request{url=URL, method=RequestMethod, body=Body, cookies=[Cookie],
headers=Headers}. headers=Headers}.
@ -141,3 +142,14 @@ frame_to_socket(Message, Socket) ->
ByteSize = << Length:32/big >>, ByteSize = << Length:32/big >>,
write_line(Socket, ByteSize), write_line(Socket, ByteSize),
write_line(Socket, Message). write_line(Socket, Message).
%% Extract state info from socket. Fail if you must.
state_from_socket(Socket, State) ->
{ok, PeerCert} = ssl:peercert(Socket),
{ok, {PeerIp, _PeerPort}} = ssl:peername(Socket),
{SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT} =
epp_certs:headers_from_cert(PeerCert),
NewState = State#state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN,
client_cert=SSL_CLIENT_CERT, peer_ip=PeerIp},
logger:info("Established connection with: [~p]~n", [NewState]),
NewState.

View file

@ -2,7 +2,7 @@
-export([create_map/1, create_session_id/1, frame_length/1, -export([create_map/1, create_session_id/1, frame_length/1,
frame_length_to_receive/1, frame_length_to_send/1, frame_length_to_receive/1, frame_length_to_send/1,
session_id/1]). session_id/1, readable_ip/1]).
-define(OFFSET, 4). -define(OFFSET, 4).
@ -48,3 +48,13 @@ frame_length(Frame) when is_binary(Frame) ->
frame_length(Frame) when is_list(Frame) -> frame_length(Frame) when is_list(Frame) ->
Bin = unicode:characters_to_binary(Frame), Bin = unicode:characters_to_binary(Frame),
byte_size(Bin). byte_size(Bin).
%% Pass a tuple of IP address, return a binary for sending over the wire.
-spec readable_ip({integer(), integer(), integer(), integer()}) -> binary().
readable_ip({FirstOctet, SecondOctet, ThirdOctet, FourthOctet}) ->
List = [integer_to_list(FirstOctet), ".",
integer_to_list(SecondOctet), ".",
integer_to_list(ThirdOctet), ".",
integer_to_list(FourthOctet)],
Binary = list_to_binary(List),
Binary.

View file

@ -37,3 +37,7 @@ frame_length_to_receive_test() ->
frame_length_to_send_test() -> frame_length_to_send_test() ->
?assertEqual(18, epp_util:frame_length_to_send("<epp><command>")), ?assertEqual(18, epp_util:frame_length_to_send("<epp><command>")),
?assertEqual(4, epp_util:frame_length_to_send("")). ?assertEqual(4, epp_util:frame_length_to_send("")).
readable_ip_test() ->
?assertEqual(<<127,46,0,46,0,46,1>>, epp_util:readable_ip({127,0,0,1})),
?assertError(function_clause, epp_util:readable_ip({127,0,0,1,0})).

View file

@ -7,5 +7,5 @@
{cacertfile_path, "/opt/shared/ca/certs/ca.crt.pem"}, {cacertfile_path, "/opt/shared/ca/certs/ca.crt.pem"},
{certfile_path, "/opt/shared/ca/certs/cert.pem"}, {certfile_path, "/opt/shared/ca/certs/cert.pem"},
{keyfile_path, "/opt/shared/ca/certs/key.pem"}, {keyfile_path, "/opt/shared/ca/certs/key.pem"},
{crlfile_path, "/opt/shared/ca/certs/key.pem"},]} {crlfile_path, "/opt/shared/ca/certs/key.pem"}]}
]. ].